]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: Fix zfcp problems that have been found | |
3 | References: bnc#434333 | |
4 | ||
5 | Symptom: lock dependency warnings and flaws found during code review | |
6 | Problem: various small zfcp problems | |
7 | Solution: fix zfcp problems | |
8 | - SCSI command times out on "deleted scsi device" | |
9 | - fix memory leak for status_read requests | |
10 | - locking for req_list | |
11 | - fix error path for failed request send | |
12 | ||
13 | Acked-by: John Jolly <jjolly@suse.de> | |
14 | --- | |
15 | drivers/s390/scsi/zfcp_fsf.c | 23 ++++++++++------------- | |
16 | drivers/s390/scsi/zfcp_scsi.c | 12 ++++-------- | |
17 | 2 files changed, 14 insertions(+), 21 deletions(-) | |
18 | ||
19 | --- a/drivers/s390/scsi/zfcp_scsi.c 2008-10-15 16:39:08.000000000 +0200 | |
20 | +++ b/drivers/s390/scsi/zfcp_scsi.c 2008-10-15 16:39:08.000000000 +0200 | |
21 | @@ -26,14 +26,10 @@ char *zfcp_get_fcp_sns_info_ptr(struct f | |
22 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | |
23 | { | |
24 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; | |
25 | - WARN_ON(!unit); | |
26 | - if (unit) { | |
27 | - atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); | |
28 | - sdpnt->hostdata = NULL; | |
29 | - unit->device = NULL; | |
30 | - zfcp_erp_unit_failed(unit, 12, NULL); | |
31 | - zfcp_unit_put(unit); | |
32 | - } | |
33 | + atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); | |
34 | + unit->device = NULL; | |
35 | + zfcp_erp_unit_failed(unit, 12, NULL); | |
36 | + zfcp_unit_put(unit); | |
37 | } | |
38 | ||
39 | static int zfcp_scsi_slave_configure(struct scsi_device *sdp) | |
40 | --- a/drivers/s390/scsi/zfcp_fsf.c 2008-10-15 16:39:08.000000000 +0200 | |
41 | +++ b/drivers/s390/scsi/zfcp_fsf.c 2008-10-15 16:40:11.000000000 +0200 | |
42 | @@ -685,6 +685,7 @@ static struct zfcp_fsf_req *zfcp_fsf_all | |
43 | if (!req) | |
44 | return NULL; | |
45 | memset(req, 0, sizeof(*req)); | |
46 | + req->pool = pool; | |
47 | return req; | |
48 | } | |
49 | ||
50 | @@ -771,28 +772,24 @@ static struct zfcp_fsf_req *zfcp_fsf_req | |
51 | static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) | |
52 | { | |
53 | struct zfcp_adapter *adapter = req->adapter; | |
54 | - struct zfcp_qdio_queue *req_q = &adapter->req_q; | |
55 | + unsigned long flags; | |
56 | int idx; | |
57 | ||
58 | /* put allocated FSF request into hash table */ | |
59 | - spin_lock(&adapter->req_list_lock); | |
60 | + spin_lock_irqsave(&adapter->req_list_lock, flags); | |
61 | idx = zfcp_reqlist_hash(req->req_id); | |
62 | list_add_tail(&req->list, &adapter->req_list[idx]); | |
63 | - spin_unlock(&adapter->req_list_lock); | |
64 | + spin_unlock_irqrestore(&adapter->req_list_lock, flags); | |
65 | ||
66 | - req->qdio_outb_usage = atomic_read(&req_q->count); | |
67 | + req->qdio_outb_usage = atomic_read(&adapter->req_q.count); | |
68 | req->issued = get_clock(); | |
69 | if (zfcp_qdio_send(req)) { | |
70 | - /* Queues are down..... */ | |
71 | del_timer(&req->timer); | |
72 | - spin_lock(&adapter->req_list_lock); | |
73 | - zfcp_reqlist_remove(adapter, req); | |
74 | - spin_unlock(&adapter->req_list_lock); | |
75 | - /* undo changes in request queue made for this request */ | |
76 | - atomic_add(req->sbal_number, &req_q->count); | |
77 | - req_q->first -= req->sbal_number; | |
78 | - req_q->first += QDIO_MAX_BUFFERS_PER_Q; | |
79 | - req_q->first %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */ | |
80 | + spin_lock_irqsave(&adapter->req_list_lock, flags); | |
81 | + /* lookup request again, list might have changed */ | |
82 | + if (zfcp_reqlist_find_safe(adapter, req)) | |
83 | + zfcp_reqlist_remove(adapter, req); | |
84 | + spin_unlock_irqrestore(&adapter->req_list_lock, flags); | |
85 | zfcp_erp_adapter_reopen(adapter, 0, 116, req); | |
86 | return -EIO; | |
87 | } |