Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b421922e authored by Dean Luick's avatar Dean Luick Committed by Greg Kroah-Hartman
Browse files

staging/rdma/hfi1: Add a schedule in send thread



When under heavy load, the send handler can run too long without allowing other
tasks to run.  Add a conditional resched to break this up.

Reviewed-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarDean Luick <dean.luick@intel.com>
Signed-off-by: default avatarIra Weiny <ira.weiny@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c91b4a12
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1530,6 +1530,14 @@ static u64 access_sw_kmem_wait(const struct cntr_entry *entry,
	return dd->verbs_dev.n_kmem_wait;
}

static u64 access_sw_send_schedule(const struct cntr_entry *entry,
			       void *context, int vl, int mode, u64 data)
{
	struct hfi1_devdata *dd = (struct hfi1_devdata *)context;

	return dd->verbs_dev.n_send_schedule;
}

#define def_access_sw_cpu(cntr) \
static u64 access_sw_cpu_##cntr(const struct cntr_entry *entry,		      \
			      void *context, int vl, int mode, u64 data)      \
@@ -1720,6 +1728,8 @@ static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = {
			    access_sw_pio_wait),
[C_SW_KMEM_WAIT] = CNTR_ELEM("KmemWait", 0, 0, CNTR_NORMAL,
			    access_sw_kmem_wait),
[C_SW_SEND_SCHED] = CNTR_ELEM("SendSched", 0, 0, CNTR_NORMAL,
			    access_sw_send_schedule),
};

static struct cntr_entry port_cntrs[PORT_CNTR_LAST] = {
+1 −0
Original line number Diff line number Diff line
@@ -787,6 +787,7 @@ enum {
	C_SW_VTX_WAIT,
	C_SW_PIO_WAIT,
	C_SW_KMEM_WAIT,
	C_SW_SEND_SCHED,
	DEV_CNTR_LAST  /* Must be kept last */
};

+12 −0
Original line number Diff line number Diff line
@@ -820,6 +820,9 @@ void hfi1_make_ruc_header(struct hfi1_qp *qp, struct hfi1_other_headers *ohdr,
	ohdr->bth[2] = cpu_to_be32(bth2);
}

/* when sending, force a reschedule every one of these periods */
#define SEND_RESCHED_TIMEOUT (5 * HZ)  /* 5s in jiffies */

/**
 * hfi1_do_send - perform a send on a QP
 * @work: contains a pointer to the QP
@@ -836,6 +839,7 @@ void hfi1_do_send(struct work_struct *work)
	struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
	int (*make_req)(struct hfi1_qp *qp);
	unsigned long flags;
	unsigned long timeout;

	if ((qp->ibqp.qp_type == IB_QPT_RC ||
	     qp->ibqp.qp_type == IB_QPT_UC) &&
@@ -864,6 +868,7 @@ void hfi1_do_send(struct work_struct *work)

	spin_unlock_irqrestore(&qp->s_lock, flags);

	timeout = jiffies + SEND_RESCHED_TIMEOUT;
	do {
		/* Check for a constructed packet to be sent. */
		if (qp->s_hdrwords != 0) {
@@ -877,6 +882,13 @@ void hfi1_do_send(struct work_struct *work)
			/* Record that s_hdr is empty. */
			qp->s_hdrwords = 0;
		}

		/* allow other tasks to run */
		if (unlikely(time_after(jiffies, timeout))) {
			cond_resched();
			ppd->dd->verbs_dev.n_send_schedule++;
			timeout = jiffies + SEND_RESCHED_TIMEOUT;
		}
	} while (make_req(qp));
}

+1 −0
Original line number Diff line number Diff line
@@ -754,6 +754,7 @@ struct hfi1_ibdev {
	u64 n_piowait;
	u64 n_txwait;
	u64 n_kmem_wait;
	u64 n_send_schedule;

	u32 n_pds_allocated;    /* number of PDs allocated for device */
	spinlock_t n_pds_lock;