Commit d4538817 authored by Christof Schmitt's avatar Christof Schmitt Committed by James Bottomley

[SCSI] zfcp: Fix request queue locking

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.
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarMartin Petermann <martin@linux.vnet.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent bfad9cea
...@@ -710,10 +710,10 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) ...@@ -710,10 +710,10 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
static int zfcp_fsf_sbal_check(struct zfcp_qdio_queue *queue) 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)) if (atomic_read(&queue->count))
return 1; return 1;
spin_unlock(&queue->lock); spin_unlock_bh(&queue->lock);
return 0; return 0;
} }
...@@ -722,13 +722,13 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) ...@@ -722,13 +722,13 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
long ret; long ret;
struct zfcp_qdio_queue *req_q = &adapter->req_q; 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, ret = wait_event_interruptible_timeout(adapter->request_wq,
zfcp_fsf_sbal_check(req_q), 5 * HZ); zfcp_fsf_sbal_check(req_q), 5 * HZ);
if (ret > 0) if (ret > 0)
return 0; return 0;
spin_lock(&req_q->lock); spin_lock_bh(&req_q->lock);
return -EIO; return -EIO;
} }
...@@ -870,7 +870,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) ...@@ -870,7 +870,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter)
volatile struct qdio_buffer_element *sbale; volatile struct qdio_buffer_element *sbale;
int retval = -EIO; int retval = -EIO;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter)) if (zfcp_fsf_req_sbal_get(adapter))
goto out; goto out;
...@@ -910,7 +910,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) ...@@ -910,7 +910,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter)
zfcp_fsf_req_free(req); zfcp_fsf_req_free(req);
zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL);
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
return retval; return retval;
} }
...@@ -1106,7 +1106,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, ...@@ -1106,7 +1106,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
struct zfcp_fsf_req *req; struct zfcp_fsf_req *req;
int ret = -EIO; int ret = -EIO;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter)) if (zfcp_fsf_req_sbal_get(adapter))
goto out; goto out;
...@@ -1148,7 +1148,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, ...@@ -1148,7 +1148,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
if (erp_action) if (erp_action)
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
return ret; return ret;
} }
...@@ -1263,7 +1263,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) ...@@ -1263,7 +1263,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
struct zfcp_adapter *adapter = erp_action->adapter; struct zfcp_adapter *adapter = erp_action->adapter;
int retval = -EIO; int retval = -EIO;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (!atomic_read(&adapter->req_q.count)) if (!atomic_read(&adapter->req_q.count))
goto out; goto out;
req = zfcp_fsf_req_create(adapter, req = zfcp_fsf_req_create(adapter,
...@@ -1295,7 +1295,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) ...@@ -1295,7 +1295,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
} }
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
return retval; return retval;
} }
...@@ -1306,7 +1306,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, ...@@ -1306,7 +1306,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
struct zfcp_fsf_req *req = NULL; struct zfcp_fsf_req *req = NULL;
int retval = -EIO; int retval = -EIO;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter)) if (zfcp_fsf_req_sbal_get(adapter))
goto out; goto out;
...@@ -1334,7 +1334,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, ...@@ -1334,7 +1334,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(req); retval = zfcp_fsf_req_send(req);
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
if (!retval) if (!retval)
wait_event(req->completion_wq, wait_event(req->completion_wq,
req->status & ZFCP_STATUS_FSFREQ_COMPLETED); req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
...@@ -1359,7 +1359,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) ...@@ -1359,7 +1359,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
return -EOPNOTSUPP; return -EOPNOTSUPP;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (!atomic_read(&adapter->req_q.count)) if (!atomic_read(&adapter->req_q.count))
goto out; goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
...@@ -1385,7 +1385,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) ...@@ -1385,7 +1385,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
} }
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
return retval; return retval;
} }
...@@ -1405,7 +1405,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, ...@@ -1405,7 +1405,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
return -EOPNOTSUPP; return -EOPNOTSUPP;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (!atomic_read(&adapter->req_q.count)) if (!atomic_read(&adapter->req_q.count))
goto out; goto out;
...@@ -1427,7 +1427,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, ...@@ -1427,7 +1427,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(req); retval = zfcp_fsf_req_send(req);
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
if (!retval) if (!retval)
wait_event(req->completion_wq, wait_event(req->completion_wq,
req->status & ZFCP_STATUS_FSFREQ_COMPLETED); req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
...@@ -1531,7 +1531,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) ...@@ -1531,7 +1531,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req; struct zfcp_fsf_req *req;
int retval = -EIO; int retval = -EIO;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter)) if (zfcp_fsf_req_sbal_get(adapter))
goto out; goto out;
...@@ -1562,7 +1562,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) ...@@ -1562,7 +1562,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
} }
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
return retval; return retval;
} }
...@@ -1603,7 +1603,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) ...@@ -1603,7 +1603,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req; struct zfcp_fsf_req *req;
int retval = -EIO; int retval = -EIO;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter)) if (zfcp_fsf_req_sbal_get(adapter))
goto out; goto out;
...@@ -1633,7 +1633,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) ...@@ -1633,7 +1633,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
} }
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
return retval; return retval;
} }
...@@ -1700,7 +1700,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) ...@@ -1700,7 +1700,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req; struct zfcp_fsf_req *req;
int retval = -EIO; int retval = -EIO;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter)) if (zfcp_fsf_req_sbal_get(adapter))
goto out; goto out;
...@@ -1731,7 +1731,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) ...@@ -1731,7 +1731,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
} }
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
return retval; return retval;
} }
...@@ -1875,7 +1875,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) ...@@ -1875,7 +1875,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req; struct zfcp_fsf_req *req;
int retval = -EIO; int retval = -EIO;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter)) if (zfcp_fsf_req_sbal_get(adapter))
goto out; goto out;
...@@ -1910,7 +1910,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) ...@@ -1910,7 +1910,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
} }
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
return retval; return retval;
} }
...@@ -1965,7 +1965,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) ...@@ -1965,7 +1965,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
struct zfcp_fsf_req *req; struct zfcp_fsf_req *req;
int retval = -EIO; int retval = -EIO;
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter)) if (zfcp_fsf_req_sbal_get(adapter))
goto out; goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN, req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN,
...@@ -1995,7 +1995,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) ...@@ -1995,7 +1995,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
} }
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
return retval; return retval;
} }
...@@ -2417,7 +2417,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, ...@@ -2417,7 +2417,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
spin_lock(&adapter->req_q.lock); spin_lock_bh(&adapter->req_q.lock);
if (zfcp_fsf_req_sbal_get(adapter)) if (zfcp_fsf_req_sbal_get(adapter))
goto out; goto out;
...@@ -2447,7 +2447,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, ...@@ -2447,7 +2447,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(req); retval = zfcp_fsf_req_send(req);
out: out:
spin_unlock(&adapter->req_q.lock); spin_unlock_bh(&adapter->req_q.lock);
if (!retval) { if (!retval) {
wait_event(req->completion_wq, wait_event(req->completion_wq,
......
...@@ -423,9 +423,9 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) ...@@ -423,9 +423,9 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
req_q = &adapter->req_q; 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); 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); qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
......
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