zfcp fixes for 2.6.27
Subsystems (3)
cover zfcp fixes for 2.6.27
James,
this is a series of fixes for problems that were found after the last zfcp changes. The patches apply to the current scsi-rc-fixes tree.
Christof
PATCH 1/6 zfcp: Fix request queue locking
From: Christof Schmitt <[email protected]>
The request queue lock can be acquired from softirq context when the SCSI midlayer issues commands. Disable softirqs for this lock when commands are issued from zfcp.
---
drivers/s390/scsi/zfcp_fsf.c | 56 +++++++++++++++++++++--------------------- drivers/s390/scsi/zfcp_qdio.c | 4 +-- 2 files changed, 30 insertions(+), 30 deletions(-)
drivers/s390/scsi/zfcp_fsf.c +28 -28
@@ -710,10 +710,10 @@ static void zfcp_fsf_exchange_port_data_static int zfcp_fsf_sbal_check (struct zfcp_qdio_queue *queue) { -spin_lock (&queue->lock); +spin_lock_bh (&queue->lock);if (atomic_read (&queue->count))return 1 ; -spin_unlock (&queue->lock); +spin_unlock_bh (&queue->lock);return 0 ; }
@@ -722,13 +722,13 @@ static int zfcp_fsf_req_sbal_get(structlong ret;struct zfcp_qdio_queue *req_q = &adapter->req_q; -spin_unlock (&req_q->lock); +spin_unlock_bh (&req_q->lock); ret =wait_event_interruptible_timeout (adapter->request_wq,zfcp_fsf_sbal_check (req_q),5 *HZ );if (ret >0 )return 0 ; -spin_lock (&req_q->lock); +spin_lock_bh (&req_q->lock);return -EIO ; }
@@ -870,7 +870,7 @@ int zfcp_fsf_status_read(struct zfcp_adavolatile struct qdio_buffer_element *sbale;int retval = -EIO ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out;
@@ -910,7 +910,7 @@ failed_buf:zfcp_fsf_req_free (req);zfcp_hba_dbf_event_fsf_unsol ("fail" , adapter,NULL ); out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);return retval; }
@@ -1106,7 +1106,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ctstruct zfcp_fsf_req *req;int ret = -EIO ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out;
@@ -1148,7 +1148,7 @@ failed_send:if (erp_action) erp_action->fsf_req =NULL ; out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);return ret; }
@@ -1263,7 +1263,7 @@ int zfcp_fsf_exchange_config_data(structstruct zfcp_adapter *adapter = erp_action->adapter;int retval = -EIO ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (!atomic_read (&adapter->req_q.count)) goto out; req = zfcp_fsf_req_create(adapter,
@@ -1295,7 +1295,7 @@ int zfcp_fsf_exchange_config_data(struct erp_action->fsf_req =NULL ; } out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);return retval; }
@@ -1306,7 +1306,7 @@ int zfcp_fsf_exchange_config_data_sync(sstruct zfcp_fsf_req *req =NULL ;int retval = -EIO ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out;
@@ -1334,7 +1334,7 @@ int zfcp_fsf_exchange_config_data_sync(szfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT ); retval =zfcp_fsf_req_send (req); out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);if (!retval)wait_event (req->completion_wq, req->status &ZFCP_STATUS_FSFREQ_COMPLETED );
@@ -1359,7 +1359,7 @@ int zfcp_fsf_exchange_port_data(struct zif (!(adapter->adapter_features &FSF_FEATURE_HBAAPI_MANAGEMENT ))return -EOPNOTSUPP ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (!atomic_read (&adapter->req_q.count)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
@@ -1385,7 +1385,7 @@ int zfcp_fsf_exchange_port_data(struct z erp_action->fsf_req =NULL ; } out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);return retval; }
@@ -1405,7 +1405,7 @@ int zfcp_fsf_exchange_port_data_sync(strif (!(adapter->adapter_features &FSF_FEATURE_HBAAPI_MANAGEMENT ))return -EOPNOTSUPP ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (!atomic_read (&adapter->req_q.count)) goto out;
@@ -1427,7 +1427,7 @@ int zfcp_fsf_exchange_port_data_sync(strzfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT ); retval =zfcp_fsf_req_send (req); out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);if (!retval)wait_event (req->completion_wq, req->status &ZFCP_STATUS_FSFREQ_COMPLETED );
@@ -1531,7 +1531,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_astruct zfcp_fsf_req *req;int retval = -EIO ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out;
@@ -1562,7 +1562,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_a erp_action->fsf_req =NULL ; } out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);return retval; }
@@ -1603,7 +1603,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_struct zfcp_fsf_req *req;int retval = -EIO ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out;
@@ -1633,7 +1633,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_ erp_action->fsf_req =NULL ; } out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);return retval; }
@@ -1700,7 +1700,7 @@ int zfcp_fsf_close_physical_port(structstruct zfcp_fsf_req *req;int retval = -EIO ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out;
@@ -1731,7 +1731,7 @@ int zfcp_fsf_close_physical_port(struct erp_action->fsf_req =NULL ; } out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);return retval; }
@@ -1875,7 +1875,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_astruct zfcp_fsf_req *req;int retval = -EIO ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out;
@@ -1910,7 +1910,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_a erp_action->fsf_req =NULL ; } out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);return retval; }
@@ -1965,7 +1965,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_struct zfcp_fsf_req *req;int retval = -EIO ; -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN,
@@ -1995,7 +1995,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_ erp_action->fsf_req =NULL ; } out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);return retval; }
@@ -2417,7 +2417,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_fireturn ERR_PTR (-EINVAL ); } -spin_lock (&adapter->req_q.lock); +spin_lock_bh (&adapter->req_q.lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out;
@@ -2447,7 +2447,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_fizfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT ); retval =zfcp_fsf_req_send (req); out: -spin_unlock (&adapter->req_q.lock); +spin_unlock_bh (&adapter->req_q.lock);if (!retval) { wait_event(req->completion_wq,
drivers/s390/scsi/zfcp_qdio.c +2 -2
@@ -423,9 +423,9 @@ void zfcp_qdio_close(struct zfcp_adapter/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ req_q = &adapter->req_q; -spin_lock (&req_q->lock); +spin_lock_bh (&req_q->lock);atomic_clear_mask (ZFCP_STATUS_ADAPTER_QDIOUP , &adapter->status); -spin_unlock (&req_q->lock); +spin_unlock_bh (&req_q->lock);qdio_shutdown (adapter->ccw_device,QDIO_FLAG_CLEANUP_USING_CLEAR );
PATCH 2/6 zfcp: Correctly query end flag in gpn_ft response
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
When the last port entry in the gpn_ft response is already a known port, the eval function would skip the end flag and try to attach ports with wwpn 0. Fix this by checking the flag first.
---
drivers/s390/scsi/zfcp_fc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/s390/scsi/zfcp_fc.c +3 -4
@@ -475,7 +475,7 @@ static int zfcp_scan_eval_gpn_ft(structstruct zfcp_adapter *adapter = ct->port->adapter;struct zfcp_port *port, *tmp;u32 d_id; -int ret =0 , x; +int ret =0 , x, last =0 ;if (ct->status)return -EIO ;
@@ -492,12 +492,13 @@ static int zfcp_scan_eval_gpn_ft(structdown (&zfcp_data.config_sema);/* first entry is the header */ -for (x =1 ; x <ZFCP_GPN_FT_MAX_ENTRIES ; x++) { +for (x =1 ; x <ZFCP_GPN_FT_MAX_ENTRIES && !last; x++) {if (x % (ZFCP_GPN_FT_ENTRIES +1 )) acc++;else acc =sg_virt (++sg); + last = acc->control &0x80 ; d_id = acc->port_id[0 ] <<16 | acc->port_id[1 ] <<8 | acc->port_id[2 ];
@@ -513,8 +514,6 @@ static int zfcp_scan_eval_gpn_ft(struct ret =PTR_ERR (port); else zfcp_erp_port_reopen(port, 0, 149, NULL); -if (acc->control &0x80 )/* last entry */ -break ; }zfcp_erp_wait (adapter);
PATCH 3/6 zfcp: Simplify ccw notify handler
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The notify handler does not change the list of adapters, it only triggers erp actions to open or shutdown the adapter. We don't need to hold the config semaphore and wait for the erp to complete.
This is a prerequisite for a fix in the s390 common i/o code.
---
drivers/s390/scsi/zfcp_ccw.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/s390/scsi/zfcp_ccw.c +1 -5
@@ -152,10 +152,8 @@ static int zfcp_ccw_set_offline(struct c*/ static int zfcp_ccw_notify (struct ccw_device *ccw_device,int event) { -struct zfcp_adapter *adapter; +struct zfcp_adapter *adapter =dev_get_drvdata (&ccw_device->dev); -down (&zfcp_data.config_sema); - adapter =dev_get_drvdata (&ccw_device->dev);switch (event) {case CIO_GONE :dev_warn (&adapter->ccw_device->dev,"device gone\n" );
@@ -174,8 +172,6 @@ static int zfcp_ccw_notify(struct ccw_de 89, NULL);break ; } -zfcp_erp_wait (adapter); -up (&zfcp_data.config_sema);return 1 ; }
PATCH 4/6 zfcp: Fix reference counter for remote ports
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
Fix the remote port reference counter handling during ELS ADISC commands and find the remote port by WWPN not by D_IDs that could change.
---
drivers/s390/scsi/zfcp_fc.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-)
drivers/s390/scsi/zfcp_fc.c +9 -16
@@ -39,18 +39,6 @@ struct zfcp_gpn_ft {struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS ]; }; -static struct zfcp_port *zfcp_get_port_by_did (struct zfcp_adapter *adapter, -u32 d_id) -{ -struct zfcp_port *port; - -list_for_each_entry (port, &adapter->port_list_head, list) -if ((port->d_id == d_id) && - !atomic_test_mask (ZFCP_STATUS_COMMON_REMOVE , &port->status)) -return port; -return NULL ; -} -static void _zfcp_fc_incoming_rscn (struct zfcp_fsf_req *fsf_req,u32 range,struct fcp_rscn_element *elem) {
@@ -341,12 +329,13 @@ void zfcp_test_link(struct zfcp_port *pozfcp_port_get (port); retval =zfcp_fc_adisc (port); -if (retval ==0 || retval == -EBUSY ) +if (retval ==0 )return ;/* send of ADISC was not possible */ zfcp_port_put (port); -zfcp_erp_port_forced_reopen (port,0 ,65 ,NULL ); +if (retval != -EBUSY ) +zfcp_erp_port_forced_reopen (port,0 ,65 ,NULL ); }static int zfcp_scan_get_nameserver (struct zfcp_adapter *adapter)
@@ -503,9 +492,13 @@ static int zfcp_scan_eval_gpn_ft(struct acc->port_id[2 ];/* skip the adapter's port and known remote ports */ -if (acc->wwpn ==fc_host_port_name (adapter->scsi_host) || -zfcp_get_port_by_did (adapter, d_id)) +if (acc->wwpn ==fc_host_port_name (adapter->scsi_host))continue ; + port =zfcp_get_port_by_wwpn (adapter, acc->wwpn); +if (port) { +zfcp_port_get (port); +continue ; + } port = zfcp_port_enqueue(adapter, acc->wwpn, ZFCP_STATUS_PORT_DID_DID |
PATCH 5/6 zfcp: channel cannot be detached due to refcount imbalance
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
Due to an imbalance of the nameserver refcounting, channel devices couldn't be take offline anymore after the channel was activated.
---
drivers/s390/scsi/zfcp_fc.c | 1 - 1 file changed, 1 deletion(-)
drivers/s390/scsi/zfcp_fc.c +0 -1
@@ -352,7 +352,6 @@ static int zfcp_scan_get_nameserver(struif (ret)return ret;zfcp_erp_wait (adapter); -zfcp_port_put (adapter->nameserver_port); }return !atomic_test_mask (ZFCP_STATUS_COMMON_UNBLOCKED , &adapter->nameserver_port->status);
PATCH 6/6 zfcp: Remove duplicated unlikely() macros.
In reply to Christof SchmittFrom: Hirofumi Nakagawa <[email protected]>
Some drivers have duplicated unlikely() macros. IS_ERR() already has unlikely() in itself. This patch cleans up such pointless codes although there is no real effect on the kernel's behaviour.
---
drivers/s390/scsi/zfcp_fsf.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
drivers/s390/scsi/zfcp_fsf.c +16 -16
@@ -877,7 +877,7 @@ int zfcp_fsf_status_read(struct zfcp_ada req =zfcp_fsf_req_create (adapter,FSF_QTCB_UNSOLICITED_STATUS ,ZFCP_REQ_NO_QTCB , adapter->pool.fsf_req_status_read); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -988,7 +988,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_ goto out; req =zfcp_fsf_req_create (adapter,FSF_QTCB_ABORT_FCP_CMND , req_flags, adapter->pool.fsf_req_abort); -if (unlikely (IS_ERR (req))) +if (IS_ERR (req)) goto out; if (unlikely(!(atomic_read(&unit->status) &
@@ -1112,7 +1112,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct req =zfcp_fsf_req_create (adapter,FSF_QTCB_SEND_GENERIC ,ZFCP_REQ_AUTO_CLEANUP , pool); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { ret =PTR_ERR (req); goto out; }
@@ -1223,7 +1223,7 @@ int zfcp_fsf_send_els(struct zfcp_send_e goto out; req =zfcp_fsf_req_create (adapter,FSF_QTCB_SEND_ELS ,ZFCP_REQ_AUTO_CLEANUP ,NULL ); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { ret =PTR_ERR (req); goto out; }
@@ -1270,7 +1270,7 @@ int zfcp_fsf_exchange_config_data(structFSF_QTCB_EXCHANGE_CONFIG_DATA ,ZFCP_REQ_AUTO_CLEANUP , adapter->pool.fsf_req_erp); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -1312,7 +1312,7 @@ int zfcp_fsf_exchange_config_data_sync(s req =zfcp_fsf_req_create (adapter,FSF_QTCB_EXCHANGE_CONFIG_DATA ,0 ,NULL ); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -1365,7 +1365,7 @@ int zfcp_fsf_exchange_port_data(struct z req =zfcp_fsf_req_create (adapter,FSF_QTCB_EXCHANGE_PORT_DATA ,ZFCP_REQ_AUTO_CLEANUP , adapter->pool.fsf_req_erp); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -1411,7 +1411,7 @@ int zfcp_fsf_exchange_port_data_sync(str req =zfcp_fsf_req_create (adapter,FSF_QTCB_EXCHANGE_PORT_DATA ,0 ,NULL ); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -1539,7 +1539,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_aFSF_QTCB_OPEN_PORT_WITH_DID ,ZFCP_REQ_AUTO_CLEANUP , adapter->pool.fsf_req_erp); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -1610,7 +1610,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_ req =zfcp_fsf_req_create (adapter,FSF_QTCB_CLOSE_PORT ,ZFCP_REQ_AUTO_CLEANUP , adapter->pool.fsf_req_erp); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -1707,7 +1707,7 @@ int zfcp_fsf_close_physical_port(struct req =zfcp_fsf_req_create (adapter,FSF_QTCB_CLOSE_PHYSICAL_PORT ,ZFCP_REQ_AUTO_CLEANUP , adapter->pool.fsf_req_erp); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -1882,7 +1882,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_a req =zfcp_fsf_req_create (adapter,FSF_QTCB_OPEN_LUN ,ZFCP_REQ_AUTO_CLEANUP , adapter->pool.fsf_req_erp); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -1971,7 +1971,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_ req =zfcp_fsf_req_create (adapter,FSF_QTCB_CLOSE_LUN ,ZFCP_REQ_AUTO_CLEANUP , adapter->pool.fsf_req_erp); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -2228,7 +2228,7 @@ int zfcp_fsf_send_fcp_command_task(struc goto out; req =zfcp_fsf_req_create (adapter,FSF_QTCB_FCP_CMND , req_flags, adapter->pool.fsf_req_scsi); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; }
@@ -2351,7 +2351,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_c goto out; req =zfcp_fsf_req_create (adapter,FSF_QTCB_FCP_CMND , req_flags, adapter->pool.fsf_req_scsi); -if (unlikely (IS_ERR (req))) +if (IS_ERR (req)) goto out; req->status |=ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT ;
@@ -2422,7 +2422,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_fi goto out; req =zfcp_fsf_req_create (adapter, fsf_cfdc->command,0 ,NULL ); -if (unlikely (IS_ERR (req))) { +if (IS_ERR (req)) { retval = -EPERM ; goto out; }