Commit 711e104d authored by Mike Marciniszyn's avatar Mike Marciniszyn Committed by Doug Ledford
Browse files

staging/rdma/hfi1: fix panic in send engine



The send engine wasn't correctly handling
pre-built packets, and worse, the pointer to
a packet state's txreq wasn't initialized correctly.

To fix:
- all waiters need to save any prebuilt packets
  (smda waits already did)
- the progress routine needs to handle a QPs prebuilt packet
  and initialize the txreq pointer properly

To keep SDMA working, the dma send code needs to see if
a packet has been built already. If not the code will build
it.

Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 1235bef8
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@
#include <linux/workqueue.h>
#include <linux/sched.h>

#include "sdma_txreq.h"
/*
 * typedef (*restart_t)() - restart callback
 * @work: pointer to work structure
@@ -185,4 +186,23 @@ static inline void iowait_drain_wakeup(struct iowait *wait)
	wake_up(&wait->wait_dma);
}

/**
 * iowait_get_txhead() - get packet off of iowait list
 *
 * @wait wait struture
 */
static inline struct sdma_txreq *iowait_get_txhead(struct iowait *wait)
{
	struct sdma_txreq *tx = NULL;

	if (!list_empty(&wait->tx_head)) {
		tx = list_first_entry(
			&wait->tx_head,
			struct sdma_txreq,
			list);
		list_del_init(&tx->list);
	}
	return tx;
}

#endif
+4 −0
Original line number Diff line number Diff line
@@ -348,6 +348,8 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp,
	}
	qp->s_rdma_ack_cnt++;
	qp->s_hdrwords = hwords;
	/* pbc */
	ps->s_txreq->hdr_dwords = hwords + 2;
	qp->s_cur_size = len;
	hfi1_make_ruc_header(qp, ohdr, bth0, bth2, middle, ps);
	return 1;
@@ -750,6 +752,8 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
	}
	qp->s_len -= len;
	qp->s_hdrwords = hwords;
	/* pbc */
	ps->s_txreq->hdr_dwords = hwords + 2;
	qp->s_cur_sge = ss;
	qp->s_cur_size = len;
	hfi1_make_ruc_header(
+2 −0
Original line number Diff line number Diff line
@@ -879,6 +879,8 @@ void hfi1_do_send(struct rvt_qp *qp)
	timeout = jiffies + (timeout_int) / 8;
	cpu = priv->s_sde ? priv->s_sde->cpu :
			cpumask_first(cpumask_of_node(ps.ppd->dd->node));
	/* insure a pre-built packet is handled  */
	ps.s_txreq = get_waiting_verbs_txreq(qp);
	do {
		/* Check for a constructed packet to be sent. */
		if (qp->s_hdrwords != 0) {
+5 −0
Original line number Diff line number Diff line
@@ -127,4 +127,9 @@ struct sdma_txreq {
	struct sdma_desc descs[NUM_DESC];
};

static inline int sdma_txreq_built(struct sdma_txreq *tx)
{
	return tx->num_desc;
}

#endif                          /* HFI1_SDMA_TXREQ_H */
+2 −0
Original line number Diff line number Diff line
@@ -235,6 +235,8 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
	}
	qp->s_len -= len;
	qp->s_hdrwords = hwords;
	/* pbc */
	ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
	qp->s_cur_sge = &qp->s_sge;
	qp->s_cur_size = len;
	hfi1_make_ruc_header(qp, ohdr, bth0 | (qp->s_state << 24),
Loading