Commit 3765138a authored by Christof Schmitt's avatar Christof Schmitt Committed by James Bottomley

[SCSI] zfcp: Fix request list handling in error path

Fix the handling of the request list in the error path:
 - Use irqsave for the lock as in the good path.
 - Before removing the request, check if it is still in the list, a
   call to dismiss_all might have changed the list in between.
 - zfcp_qdio_send does not change the queue counters on failure,
   trying revert something is wrong, so remove this.
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarSwen Schillig <swen@vnet.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 88f2a977
...@@ -770,7 +770,6 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, ...@@ -770,7 +770,6 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
{ {
struct zfcp_adapter *adapter = req->adapter; struct zfcp_adapter *adapter = req->adapter;
struct zfcp_qdio_queue *req_q = &adapter->req_q;
unsigned long flags; unsigned long flags;
int idx; int idx;
...@@ -780,19 +779,15 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) ...@@ -780,19 +779,15 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
list_add_tail(&req->list, &adapter->req_list[idx]); list_add_tail(&req->list, &adapter->req_list[idx]);
spin_unlock_irqrestore(&adapter->req_list_lock, flags); spin_unlock_irqrestore(&adapter->req_list_lock, flags);
req->qdio_outb_usage = atomic_read(&req_q->count); req->qdio_outb_usage = atomic_read(&adapter->req_q.count);
req->issued = get_clock(); req->issued = get_clock();
if (zfcp_qdio_send(req)) { if (zfcp_qdio_send(req)) {
/* Queues are down..... */
del_timer(&req->timer); del_timer(&req->timer);
spin_lock(&adapter->req_list_lock); spin_lock_irqsave(&adapter->req_list_lock, flags);
zfcp_reqlist_remove(adapter, req); /* lookup request again, list might have changed */
spin_unlock(&adapter->req_list_lock); if (zfcp_reqlist_find_safe(adapter, req))
/* undo changes in request queue made for this request */ zfcp_reqlist_remove(adapter, req);
atomic_add(req->sbal_number, &req_q->count); spin_unlock_irqrestore(&adapter->req_list_lock, flags);
req_q->first -= req->sbal_number;
req_q->first += QDIO_MAX_BUFFERS_PER_Q;
req_q->first %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */
zfcp_erp_adapter_reopen(adapter, 0, 116, req); zfcp_erp_adapter_reopen(adapter, 0, 116, req);
return -EIO; return -EIO;
} }
......
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