]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sif: eq: Add timeout to the threaded interrupt handler
authorFrancisco Triviño <francisco.trivino@oracle.com>
Fri, 30 Sep 2016 08:35:14 +0000 (10:35 +0200)
committerSantosh Shilimkar <santosh.shilimkar@oracle.com>
Mon, 24 Oct 2016 16:06:01 +0000 (09:06 -0700)
This commit implements a timeout that prevents soft lockup issues when
the threaded interrupt function (sif_intr_worker) keeps processing
events for a long period. If the timeout is reached, the threaded
handler returns IRQ_HANDLED even if there are more events to be
processed. In such a case, the coalescing mechanism will generate
an IRQ for the last event.

Orabug: 24839976

Signed-off-by: Francisco Triviño <francisco.trivino@oracle.com>
Reviewed-by: Håkon Bugge <haakon.bugge@oracle.com>
drivers/infiniband/hw/sif/sif_eq.c
drivers/infiniband/hw/sif/sif_eq.h

index 745fcb3508f7bca9feb5136e43cee8ef6a9a6101..fec8534a34b73ce6418f6dfb16eda0faef5fcd0b 100644 (file)
@@ -37,7 +37,7 @@ static void sif_eq_table_deinit(struct sif_dev *sdev, struct sif_eps *es, u16 eq
 
 static void sif_eq_deinit_tables(struct sif_dev *sdev, struct sif_eps *es);
 
-static bool dispatch_eq(struct sif_eq *eq, int irq, bool interruptible);
+static bool dispatch_eq(struct sif_eq *eq, int irq, unsigned int msecs);
 
 static enum ib_event_type epsc2ib_event(struct psif_eq_entry *eqe);
 
@@ -338,7 +338,7 @@ static irqreturn_t sif_intr_worker(int irq, void *d)
 {
        struct sif_eq *eq = (struct sif_eq *)d;
 
-       dispatch_eq(eq, irq, false);
+       dispatch_eq(eq, irq, SIF_IRQ_THR_HANDLER_TIMEOUT);
 
        return IRQ_HANDLED;
 }
@@ -351,7 +351,7 @@ static irqreturn_t sif_intr(int irq, void *d)
        struct sif_eq *eq = (struct sif_eq *)d;
        bool wakeup_thread;
 
-       wakeup_thread = dispatch_eq(eq, irq, true);
+       wakeup_thread = dispatch_eq(eq, irq, SIF_IRQ_HANDLER_TIMEOUT);
 
        elapsed = jiffies_to_msecs(jiffies - start_time);
 
@@ -885,7 +885,7 @@ static u32 handle_srq_event(struct sif_eq *eq, struct ib_event *ibe)
 
 
 /* Called from interrupt threads */
-static bool dispatch_eq(struct sif_eq *eq, int irq, bool interruptible)
+static bool dispatch_eq(struct sif_eq *eq, int irq, unsigned int msecs)
 {
        volatile struct psif_eq_entry *eqe;
        struct psif_eq_entry leqe;
@@ -893,7 +893,7 @@ static bool dispatch_eq(struct sif_eq *eq, int irq, bool interruptible)
        struct sif_dev *sdev = eq->ba.sdev;
        struct ib_event ibe;
        struct ib_qp *ibqp = NULL;
-       ulong timeout = jiffies + msecs_to_jiffies(SIF_IRQ_HANDLER_TIMEOUT);
+       ulong timeout = jiffies + msecs_to_jiffies(msecs);
        bool wakeup_thread = false;
        u32 seqno;
        u32 nreqs = 0;
@@ -1122,7 +1122,7 @@ only_cne:
                eqe = (struct psif_eq_entry *)get_eq_entry(eq, seqno);
                nreqs++;
                /* check whether we should stop processing events */
-               wakeup_thread = interruptible ? time_after(jiffies, timeout) : false;
+               wakeup_thread = msecs ? time_after(jiffies, timeout) : false;
        }
        spin_unlock_irqrestore(&eq->ba.lock, flags);
        atomic_add(nreqs, &eq->intr_cnt);
index 87c6cfd25094f628d77931dbf50f84a8fa8c4011..8d6b3c3541db22611cdfc819a2ff126d1da55e1b 100644 (file)
  */
 #define SIF_IRQ_HANDLER_TIMEOUT 20
 
+/* This defines a timeout period in msecs to stop processing events
+ * from the threaded irq handler (sif_intr_worker)
+ */
+#define SIF_IRQ_THR_HANDLER_TIMEOUT 5000
+
+
 extern uint sif_cq_eq_max;
 
 struct sif_dev;