Commit b583faf4 authored by Jianxin Xiong's avatar Jianxin Xiong Committed by Doug Ledford

IB/hfi1: Fix bug that blocks process on exit after port bounce

During the processing of a user SDMA request, if there was an
error before the request counter was increased, the state of
the packet queue could be updated incorrectly, causing the
counter to underflow. As the result, the process could get
stuck later since the counter could never get back to 0.

This patch adds a condition to guard the packet queue update
so that the counter is only decreased if it has been increased
before the error happens.
Reviewed-by: default avatarMitko Haralanov <mitko.haralanov@intel.com>
Signed-off-by: default avatarJianxin Xiong <jianxin.xiong@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent f70f5f6a
...@@ -510,6 +510,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, ...@@ -510,6 +510,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
struct sdma_req_info info; struct sdma_req_info info;
struct user_sdma_request *req; struct user_sdma_request *req;
u8 opcode, sc, vl; u8 opcode, sc, vl;
int req_queued = 0;
if (iovec[idx].iov_len < sizeof(info) + sizeof(req->hdr)) { if (iovec[idx].iov_len < sizeof(info) + sizeof(req->hdr)) {
hfi1_cdbg( hfi1_cdbg(
...@@ -706,6 +707,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, ...@@ -706,6 +707,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
set_comp_state(pq, cq, info.comp_idx, QUEUED, 0); set_comp_state(pq, cq, info.comp_idx, QUEUED, 0);
atomic_inc(&pq->n_reqs); atomic_inc(&pq->n_reqs);
req_queued = 1;
/* Send the first N packets in the request to buy us some time */ /* Send the first N packets in the request to buy us some time */
ret = user_sdma_send_pkts(req, pcount); ret = user_sdma_send_pkts(req, pcount);
if (unlikely(ret < 0 && ret != -EBUSY)) { if (unlikely(ret < 0 && ret != -EBUSY)) {
...@@ -750,7 +752,8 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, ...@@ -750,7 +752,8 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec,
return 0; return 0;
free_req: free_req:
user_sdma_free_request(req, true); user_sdma_free_request(req, true);
pq_update(pq); if (req_queued)
pq_update(pq);
set_comp_state(pq, cq, info.comp_idx, ERROR, req->status); set_comp_state(pq, cq, info.comp_idx, ERROR, req->status);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment