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

Commit e9c48ebd authored by Sebastian Sanchez's avatar Sebastian Sanchez Committed by Doug Ledford
Browse files

IB/hfi1: Remove atomic SDMA_REQ_HAS_ERROR bit operation



Atomic bit tests are used to single errors and the
completion of request submissions. These operations
don't need to be atomic and show to be expensive on
the profile.

Replace each atomic bit operation with a bool type
and a READ_ONCE/WRITE_ONCE pairing.

Reviewed-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarSebastian Sanchez <sebastian.sanchez@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent b888429c
Loading
Loading
Loading
Loading
+7 −15
Original line number Original line Diff line number Diff line
@@ -153,10 +153,6 @@ MODULE_PARM_DESC(sdma_comp_size, "Size of User SDMA completion ring. Default: 12
#define TXREQ_FLAGS_REQ_ACK   BIT(0)      /* Set the ACK bit in the header */
#define TXREQ_FLAGS_REQ_ACK   BIT(0)      /* Set the ACK bit in the header */
#define TXREQ_FLAGS_REQ_DISABLE_SH BIT(1) /* Disable header suppression */
#define TXREQ_FLAGS_REQ_DISABLE_SH BIT(1) /* Disable header suppression */


/* SDMA request flag bits */
#define SDMA_REQ_HAS_ERROR  1
#define SDMA_REQ_DONE_ERROR 2

#define SDMA_PKT_Q_INACTIVE BIT(0)
#define SDMA_PKT_Q_INACTIVE BIT(0)
#define SDMA_PKT_Q_ACTIVE   BIT(1)
#define SDMA_PKT_Q_ACTIVE   BIT(1)
#define SDMA_PKT_Q_DEFERRED BIT(2)
#define SDMA_PKT_Q_DEFERRED BIT(2)
@@ -232,7 +228,6 @@ struct user_sdma_request {
	/* Writeable fields shared with interrupt */
	/* Writeable fields shared with interrupt */
	u64 seqcomp ____cacheline_aligned_in_smp;
	u64 seqcomp ____cacheline_aligned_in_smp;
	u64 seqsubmitted;
	u64 seqsubmitted;
	unsigned long flags;
	/* status of the last txreq completed */
	/* status of the last txreq completed */
	int status;
	int status;


@@ -257,6 +252,7 @@ struct user_sdma_request {
	/* progress index moving along the iovs array */
	/* progress index moving along the iovs array */
	u8 iov_idx;
	u8 iov_idx;
	u8 done;
	u8 done;
	u8 has_error;


	struct user_sdma_iovec iovs[MAX_VECTORS_PER_REQ];
	struct user_sdma_iovec iovs[MAX_VECTORS_PER_REQ];
} ____cacheline_aligned_in_smp;
} ____cacheline_aligned_in_smp;
@@ -625,9 +621,9 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
	req->seqnum = 0;
	req->seqnum = 0;
	req->seqcomp = 0;
	req->seqcomp = 0;
	req->seqsubmitted = 0;
	req->seqsubmitted = 0;
	req->flags = 0;
	req->tids = NULL;
	req->tids = NULL;
	req->done = 0;
	req->done = 0;
	req->has_error = 0;
	INIT_LIST_HEAD(&req->txps);
	INIT_LIST_HEAD(&req->txps);


	memcpy(&req->info, &info, sizeof(info));
	memcpy(&req->info, &info, sizeof(info));
@@ -814,7 +810,7 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd,
		if (ret < 0) {
		if (ret < 0) {
			if (ret != -EBUSY) {
			if (ret != -EBUSY) {
				req->status = ret;
				req->status = ret;
				set_bit(SDMA_REQ_DONE_ERROR, &req->flags);
				WRITE_ONCE(req->has_error, 1);
				if (ACCESS_ONCE(req->seqcomp) ==
				if (ACCESS_ONCE(req->seqcomp) ==
				    req->seqsubmitted - 1)
				    req->seqsubmitted - 1)
					goto free_req;
					goto free_req;
@@ -916,10 +912,8 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
	pq = req->pq;
	pq = req->pq;


	/* If tx completion has reported an error, we are done. */
	/* If tx completion has reported an error, we are done. */
	if (test_bit(SDMA_REQ_HAS_ERROR, &req->flags)) {
	if (READ_ONCE(req->has_error))
		set_bit(SDMA_REQ_DONE_ERROR, &req->flags);
		return -EFAULT;
		return -EFAULT;
	}


	/*
	/*
	 * Check if we might have sent the entire request already
	 * Check if we might have sent the entire request already
@@ -942,10 +936,8 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
		 * with errors. If so, we are not going to process any
		 * with errors. If so, we are not going to process any
		 * more packets from this request.
		 * more packets from this request.
		 */
		 */
		if (test_bit(SDMA_REQ_HAS_ERROR, &req->flags)) {
		if (READ_ONCE(req->has_error))
			set_bit(SDMA_REQ_DONE_ERROR, &req->flags);
			return -EFAULT;
			return -EFAULT;
		}


		tx = kmem_cache_alloc(pq->txreq_cache, GFP_KERNEL);
		tx = kmem_cache_alloc(pq->txreq_cache, GFP_KERNEL);
		if (!tx)
		if (!tx)
@@ -1566,7 +1558,7 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status)
	if (status != SDMA_TXREQ_S_OK) {
	if (status != SDMA_TXREQ_S_OK) {
		SDMA_DBG(req, "SDMA completion with error %d",
		SDMA_DBG(req, "SDMA completion with error %d",
			 status);
			 status);
		set_bit(SDMA_REQ_HAS_ERROR, &req->flags);
		WRITE_ONCE(req->has_error, 1);
	}
	}


	req->seqcomp = tx->seqnum;
	req->seqcomp = tx->seqnum;
@@ -1586,7 +1578,7 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status)
			req->status = status;
			req->status = status;
		if (req->seqcomp == (ACCESS_ONCE(req->seqsubmitted) - 1) &&
		if (req->seqcomp == (ACCESS_ONCE(req->seqsubmitted) - 1) &&
		    (READ_ONCE(req->done) ||
		    (READ_ONCE(req->done) ||
		     test_bit(SDMA_REQ_DONE_ERROR, &req->flags))) {
		     READ_ONCE(req->has_error))) {
			user_sdma_free_request(req, false);
			user_sdma_free_request(req, false);
			pq_update(pq);
			pq_update(pq);
			set_comp_state(pq, cq, idx, ERROR, req->status);
			set_comp_state(pq, cq, idx, ERROR, req->status);