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

Commit 1c94283d authored by Mike Marciniszyn's avatar Mike Marciniszyn Committed by Roland Dreier
Browse files

IB/qib: Add cache line awareness to qib_qp and qib_devdata structures



This patch reorganizes the QP and devdata files to be more cache line aware.

qib_qp fields in particular are split into read-mostly, send, and receive fields.

qib_devdata fields are split into read-mostly and read/write fields

Testing has show that bidirectional tests improve by as much as 100%
with this patch.

Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 3236b2d4
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -530,8 +530,6 @@ struct qib_pportdata {
	/* qib_lflags driver is waiting for */
	u32 state_wanted;
	spinlock_t lflags_lock;
	/* number of (port-specific) interrupts for this port -- saturates... */
	u32 int_counter;

	/* ref count for each pkey */
	atomic_t pkeyrefs[4];
@@ -543,24 +541,26 @@ struct qib_pportdata {
	u64 *statusp;

	/* SendDMA related entries */
	spinlock_t            sdma_lock;
	struct qib_sdma_state sdma_state;
	unsigned long         sdma_buf_jiffies;

	/* read mostly */
	struct qib_sdma_desc *sdma_descq;
	struct qib_sdma_state sdma_state;
	dma_addr_t       sdma_descq_phys;
	volatile __le64 *sdma_head_dma; /* DMA'ed by chip */
	dma_addr_t       sdma_head_phys;
	u16                   sdma_descq_cnt;

	/* read/write using lock */
	spinlock_t            sdma_lock ____cacheline_aligned_in_smp;
	struct list_head      sdma_activelist;
	u64                   sdma_descq_added;
	u64                   sdma_descq_removed;
	u16                   sdma_descq_cnt;
	u16                   sdma_descq_tail;
	u16                   sdma_descq_head;
	u16                   sdma_next_intr;
	u16                   sdma_reset_wait;
	u8                    sdma_generation;
	struct tasklet_struct sdma_sw_clean_up_task;
	struct list_head      sdma_activelist;

	dma_addr_t       sdma_descq_phys;
	volatile __le64 *sdma_head_dma; /* DMA'ed by chip */
	dma_addr_t       sdma_head_phys;
	struct tasklet_struct sdma_sw_clean_up_task
		____cacheline_aligned_in_smp;

	wait_queue_head_t state_wait; /* for state_wanted */

+7 −0
Original line number Diff line number Diff line
@@ -1038,6 +1038,11 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd,
			goto bail_swq;
		}
		RCU_INIT_POINTER(qp->next, NULL);
		qp->s_hdr = kzalloc(sizeof(*qp->s_hdr), GFP_KERNEL);
		if (!qp->s_hdr) {
			ret = ERR_PTR(-ENOMEM);
			goto bail_qp;
		}
		qp->timeout_jiffies =
			usecs_to_jiffies((4096UL * (1UL << qp->timeout)) /
				1000UL);
@@ -1159,6 +1164,7 @@ bail_ip:
		vfree(qp->r_rq.wq);
	free_qpn(&dev->qpn_table, qp->ibqp.qp_num);
bail_qp:
	kfree(qp->s_hdr);
	kfree(qp);
bail_swq:
	vfree(swq);
@@ -1214,6 +1220,7 @@ int qib_destroy_qp(struct ib_qp *ibqp)
	else
		vfree(qp->r_rq.wq);
	vfree(qp->s_wq);
	kfree(qp->s_hdr);
	kfree(qp);
	return 0;
}
+2 −2
Original line number Diff line number Diff line
@@ -244,9 +244,9 @@ int qib_make_rc_req(struct qib_qp *qp)
	int ret = 0;
	int delta;

	ohdr = &qp->s_hdr.u.oth;
	ohdr = &qp->s_hdr->u.oth;
	if (qp->remote_ah_attr.ah_flags & IB_AH_GRH)
		ohdr = &qp->s_hdr.u.l.oth;
		ohdr = &qp->s_hdr->u.l.oth;

	/*
	 * The lock is needed to synchronize between the sending tasklet,
+6 −6
Original line number Diff line number Diff line
@@ -688,17 +688,17 @@ void qib_make_ruc_header(struct qib_qp *qp, struct qib_other_headers *ohdr,
	nwords = (qp->s_cur_size + extra_bytes) >> 2;
	lrh0 = QIB_LRH_BTH;
	if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) {
		qp->s_hdrwords += qib_make_grh(ibp, &qp->s_hdr.u.l.grh,
		qp->s_hdrwords += qib_make_grh(ibp, &qp->s_hdr->u.l.grh,
					       &qp->remote_ah_attr.grh,
					       qp->s_hdrwords, nwords);
		lrh0 = QIB_LRH_GRH;
	}
	lrh0 |= ibp->sl_to_vl[qp->remote_ah_attr.sl] << 12 |
		qp->remote_ah_attr.sl << 4;
	qp->s_hdr.lrh[0] = cpu_to_be16(lrh0);
	qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid);
	qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC);
	qp->s_hdr.lrh[3] = cpu_to_be16(ppd_from_ibp(ibp)->lid |
	qp->s_hdr->lrh[0] = cpu_to_be16(lrh0);
	qp->s_hdr->lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid);
	qp->s_hdr->lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC);
	qp->s_hdr->lrh[3] = cpu_to_be16(ppd_from_ibp(ibp)->lid |
				       qp->remote_ah_attr.src_path_bits);
	bth0 |= qib_get_pkey(ibp, qp->s_pkey_index);
	bth0 |= extra_bytes << 20;
@@ -758,7 +758,7 @@ void qib_do_send(struct work_struct *work)
			 * If the packet cannot be sent now, return and
			 * the send tasklet will be woken up later.
			 */
			if (qib_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords,
			if (qib_verbs_send(qp, qp->s_hdr, qp->s_hdrwords,
					   qp->s_cur_sge, qp->s_cur_size))
				break;
			/* Record that s_hdr is empty. */
+2 −2
Original line number Diff line number Diff line
@@ -72,9 +72,9 @@ int qib_make_uc_req(struct qib_qp *qp)
		goto done;
	}

	ohdr = &qp->s_hdr.u.oth;
	ohdr = &qp->s_hdr->u.oth;
	if (qp->remote_ah_attr.ah_flags & IB_AH_GRH)
		ohdr = &qp->s_hdr.u.l.oth;
		ohdr = &qp->s_hdr->u.l.oth;

	/* header size in 32-bit words LRH+BTH = (8+12)/4. */
	hwords = 5;
Loading