]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: zfcp: add queue_full sysfs attribute | |
3 | References: bnc#417243 | |
4 | ||
5 | From: Stefan Raspl <raspl@linux.vnet.ibm.com> | |
6 | ||
7 | Adds a new sysfs attribute queue_full for adapters that records the number | |
8 | of incidents where a requests could not be submitted due to insufficient | |
9 | free space on the request queue. | |
10 | ||
11 | Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com> | |
12 | Signed-off-by: Martin Peschke <mp3@de.ibm.com> | |
13 | Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> | |
14 | ||
15 | Acked-by: John Jolly <jjolly@suse.de> | |
16 | ||
17 | --- | |
18 | drivers/s390/scsi/zfcp_def.h | 1 + | |
19 | drivers/s390/scsi/zfcp_fsf.c | 24 +++++++++++++++++------- | |
20 | drivers/s390/scsi/zfcp_qdio.c | 1 + | |
21 | drivers/s390/scsi/zfcp_sysfs.c | 13 +++++++++++++ | |
22 | 4 files changed, 32 insertions(+), 7 deletions(-) | |
23 | ||
24 | --- a/drivers/s390/scsi/zfcp_def.h | |
25 | +++ b/drivers/s390/scsi/zfcp_def.h | |
26 | @@ -568,6 +568,7 @@ struct zfcp_adapter { | |
27 | struct fsf_qtcb_bottom_port *stats_reset_data; | |
28 | unsigned long stats_reset; | |
29 | struct work_struct scan_work; | |
30 | + atomic_t qdio_outb_full; /* queue full incidents */ | |
31 | }; | |
32 | ||
33 | struct zfcp_port { | |
34 | --- a/drivers/s390/scsi/zfcp_fsf.c | |
35 | +++ b/drivers/s390/scsi/zfcp_fsf.c | |
36 | @@ -718,6 +718,14 @@ static int zfcp_fsf_sbal_check(struct zf | |
37 | return 0; | |
38 | } | |
39 | ||
40 | +static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter) | |
41 | +{ | |
42 | + unsigned int count = atomic_read(&adapter->req_q.count); | |
43 | + if (!count) | |
44 | + atomic_inc(&adapter->qdio_outb_full); | |
45 | + return count > 0; | |
46 | +} | |
47 | + | |
48 | static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) | |
49 | { | |
50 | long ret; | |
51 | @@ -728,6 +736,8 @@ static int zfcp_fsf_req_sbal_get(struct | |
52 | zfcp_fsf_sbal_check(req_q), 5 * HZ); | |
53 | if (ret > 0) | |
54 | return 0; | |
55 | + if (!ret) | |
56 | + atomic_inc(&adapter->qdio_outb_full); | |
57 | ||
58 | spin_lock_bh(&req_q->lock); | |
59 | return -EIO; | |
60 | @@ -986,7 +996,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_ | |
61 | struct zfcp_fsf_req *req = NULL; | |
62 | ||
63 | spin_lock(&adapter->req_q.lock); | |
64 | - if (!atomic_read(&adapter->req_q.count)) | |
65 | + if (!zfcp_fsf_sbal_available(adapter)) | |
66 | goto out; | |
67 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, | |
68 | req_flags, adapter->pool.fsf_req_abort); | |
69 | @@ -1221,7 +1231,7 @@ int zfcp_fsf_send_els(struct zfcp_send_e | |
70 | return -EBUSY; | |
71 | ||
72 | spin_lock(&adapter->req_q.lock); | |
73 | - if (!atomic_read(&adapter->req_q.count)) | |
74 | + if (!zfcp_fsf_sbal_available(adapter)) | |
75 | goto out; | |
76 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS, | |
77 | ZFCP_REQ_AUTO_CLEANUP, NULL); | |
78 | @@ -1266,7 +1276,7 @@ int zfcp_fsf_exchange_config_data(struct | |
79 | int retval = -EIO; | |
80 | ||
81 | spin_lock_bh(&adapter->req_q.lock); | |
82 | - if (!atomic_read(&adapter->req_q.count)) | |
83 | + if (!zfcp_fsf_sbal_available(adapter)) | |
84 | goto out; | |
85 | req = zfcp_fsf_req_create(adapter, | |
86 | FSF_QTCB_EXCHANGE_CONFIG_DATA, | |
87 | @@ -1362,7 +1372,7 @@ int zfcp_fsf_exchange_port_data(struct z | |
88 | return -EOPNOTSUPP; | |
89 | ||
90 | spin_lock_bh(&adapter->req_q.lock); | |
91 | - if (!atomic_read(&adapter->req_q.count)) | |
92 | + if (!zfcp_fsf_sbal_available(adapter)) | |
93 | goto out; | |
94 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, | |
95 | ZFCP_REQ_AUTO_CLEANUP, | |
96 | @@ -1408,7 +1418,7 @@ int zfcp_fsf_exchange_port_data_sync(str | |
97 | return -EOPNOTSUPP; | |
98 | ||
99 | spin_lock_bh(&adapter->req_q.lock); | |
100 | - if (!atomic_read(&adapter->req_q.count)) | |
101 | + if (!zfcp_fsf_sbal_available(adapter)) | |
102 | goto out; | |
103 | ||
104 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, | |
105 | @@ -2258,7 +2268,7 @@ int zfcp_fsf_send_fcp_command_task(struc | |
106 | return -EBUSY; | |
107 | ||
108 | spin_lock(&adapter->req_q.lock); | |
109 | - if (!atomic_read(&adapter->req_q.count)) | |
110 | + if (!zfcp_fsf_sbal_available(adapter)) | |
111 | goto out; | |
112 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, | |
113 | adapter->pool.fsf_req_scsi); | |
114 | @@ -2381,7 +2391,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_c | |
115 | return NULL; | |
116 | ||
117 | spin_lock(&adapter->req_q.lock); | |
118 | - if (!atomic_read(&adapter->req_q.count)) | |
119 | + if (!zfcp_fsf_sbal_available(adapter)) | |
120 | goto out; | |
121 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, | |
122 | adapter->pool.fsf_req_scsi); | |
123 | --- a/drivers/s390/scsi/zfcp_qdio.c | |
124 | +++ b/drivers/s390/scsi/zfcp_qdio.c | |
125 | @@ -283,6 +283,7 @@ static int zfcp_qdio_fill_sbals(struct z | |
126 | addr += length, remaining -= length) { | |
127 | sbale = zfcp_qdio_sbale_next(fsf_req, sbtype); | |
128 | if (!sbale) { | |
129 | + atomic_inc(&fsf_req->adapter->qdio_outb_full); | |
130 | zfcp_qdio_undo_sbals(fsf_req); | |
131 | return -EINVAL; | |
132 | } | |
133 | --- a/drivers/s390/scsi/zfcp_sysfs.c | |
134 | +++ b/drivers/s390/scsi/zfcp_sysfs.c | |
135 | @@ -487,10 +487,23 @@ ZFCP_SHOST_ATTR(megabytes, "%llu %llu\n" | |
136 | ZFCP_SHOST_ATTR(seconds_active, "%llu\n", | |
137 | (unsigned long long) stat_info.seconds_act); | |
138 | ||
139 | +static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev, | |
140 | + struct device_attribute *attr, | |
141 | + char *buf) | |
142 | +{ | |
143 | + struct Scsi_Host *scsi_host = class_to_shost(dev); | |
144 | + struct zfcp_adapter *adapter = | |
145 | + (struct zfcp_adapter *) scsi_host->hostdata[0]; | |
146 | + | |
147 | + return sprintf(buf, "%d\n", atomic_read(&adapter->qdio_outb_full)); | |
148 | +} | |
149 | +static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL); | |
150 | + | |
151 | struct device_attribute *zfcp_sysfs_shost_attrs[] = { | |
152 | &dev_attr_utilization, | |
153 | &dev_attr_requests, | |
154 | &dev_attr_megabytes, | |
155 | &dev_attr_seconds_active, | |
156 | + &dev_attr_queue_full, | |
157 | NULL | |
158 | }; |