zfcp: improve management of request IDs
Subsystems (3)
PATCH 1/3 zfcp: improve management of request IDs
From: Volker Sameske <[email protected]>
Improve request handling. Use hash table to manage request IDs.
Signed-off-by Volker Sameske <[email protected]>
Signed-off-by Andreas Herrmann <[email protected]>
--- drivers/s390/scsi/zfcp_aux.c | 120 +++++++++++++++++++++++++++++++++++++--- drivers/s390/scsi/zfcp_ccw.c | 5 ++ drivers/s390/scsi/zfcp_def.h | 11 ++-- drivers/s390/scsi/zfcp_erp.c | 16 ++--- drivers/s390/scsi/zfcp_ext.h | 6 ++ drivers/s390/scsi/zfcp_fsf.c | 122 ++++++++++++++++++++++------------------- drivers/s390/scsi/zfcp_qdio.c | 79 +++++++++++---------------- 7 files changed, 231 insertions(+), 128 deletions(-)
drivers/s390/scsi/zfcp_aux.c +111 -9
@@ -112,6 +112,105 @@ _zfcp_hex_dump(char *addr, int count)printk ("\n" ); } + +/****************************************************************/ +/****** Functions to handle the request ID hash table ********/ +/****************************************************************/ + +#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF + +static int zfcp_reqlist_init (struct zfcp_adapter *adapter) +{ +int i; + + adapter->req_list =kcalloc (REQUEST_LIST_SIZE ,sizeof (struct list_head ), +GFP_KERNEL ); + +if (!adapter->req_list) +return -ENOMEM ; + +for (i=0 ; i<REQUEST_LIST_SIZE ; i++) +INIT_LIST_HEAD (&adapter->req_list[i]); + +return 0 ; +} + +static void zfcp_reqlist_free (struct zfcp_adapter *adapter) +{ +struct zfcp_fsf_req *request, *tmp; +unsigned int i; + +for (i=0 ; i<REQUEST_LIST_SIZE ; i++) { +if (list_empty (&adapter->req_list[i])) +continue ; + +list_for_each_entry_safe (request, tmp, + &adapter->req_list[i], list) +list_del (&request->list); + } + +kfree (adapter->req_list); +} + +void zfcp_reqlist_add (struct zfcp_adapter *adapter, +struct zfcp_fsf_req *fsf_req) +{ +unsigned int i; + + i = fsf_req->req_id %REQUEST_LIST_SIZE ; +list_add_tail (&fsf_req->list, &adapter->req_list[i]); +} + +void zfcp_reqlist_remove (struct zfcp_adapter *adapter,unsigned long req_id) +{ +struct zfcp_fsf_req *request, *tmp; +unsigned int i, counter; +u64 dbg_tmp[2 ]; + + i = req_id %REQUEST_LIST_SIZE ; +BUG_ON (list_empty (&adapter->req_list[i])); + + counter =0 ; +list_for_each_entry_safe (request, tmp, &adapter->req_list[i], list) { +if (request->req_id == req_id) { + dbg_tmp[0 ] = (u64 )atomic_read (&adapter->reqs_active); + dbg_tmp[1 ] = (u64 ) counter; +debug_event (adapter->erp_dbf,4 , (void *) dbg_tmp,16 ); +list_del (&request->list); +break ; + } + counter++; + } +} + +struct zfcp_fsf_req *zfcp_reqlist_ismember (struct zfcp_adapter *adapter, +unsigned long req_id) +{ +struct zfcp_fsf_req *request, *tmp; +unsigned int i; + + i = req_id %REQUEST_LIST_SIZE ; + +list_for_each_entry_safe (request, tmp, &adapter->req_list[i], list) +if (request->req_id == req_id) +return request; + +return NULL ; +} + +int zfcp_reqlist_isempty (struct zfcp_adapter *adapter) +{ +unsigned int i; + +for (i=0 ; i<REQUEST_LIST_SIZE ; i++) +if (!list_empty (&adapter->req_list[i])) +return 0 ; + +return 1 ; +} + +#undef ZFCP_LOG_AREA +/****************************************************************/ /************** Uncategorised Functions *************************/ /****************************************************************/
@@ -961,8 +1060,12 @@ zfcp_adapter_enqueue(struct ccw_device *INIT_LIST_HEAD (&adapter->port_remove_lh);/* initialize list of fsf requests */ -spin_lock_init (&adapter->fsf_req_list_lock); -INIT_LIST_HEAD (&adapter->fsf_req_list_head); +spin_lock_init (&adapter->req_list_lock); + retval =zfcp_reqlist_init (adapter); +if (retval) { +ZFCP_LOG_INFO ("request list initialization failed\n" ); + goto failed_low_mem_buffers; + }/* initialize debug locks */
@@ -1041,8 +1144,6 @@ zfcp_adapter_enqueue(struct ccw_device ** !0 - struct zfcp_adapter data structure could not be removed * (e.g. still used) * locks: adapter list write lock is assumed to be held by caller -* adapter->fsf_req_list_lock is taken and released within this -* function and must not be held on entry */ void zfcp_adapter_dequeue (struct zfcp_adapter *adapter)
@@ -1054,14 +1155,14 @@ zfcp_adapter_dequeue(struct zfcp_adapterzfcp_sysfs_adapter_remove_files (&adapter->ccw_device->dev);dev_set_drvdata (&adapter->ccw_device->dev,NULL );/* sanity check: no pending FSF requests */ -spin_lock_irqsave (&adapter->fsf_req_list_lock, flags); - retval = !list_empty (&adapter->fsf_req_list_head); -spin_unlock_irqrestore (&adapter->fsf_req_list_lock, flags); -if (retval) { +spin_lock_irqsave (&adapter->req_list_lock, flags); + retval =zfcp_reqlist_isempty (adapter); +spin_unlock_irqrestore (&adapter->req_list_lock, flags); +if (!retval) {ZFCP_LOG_NORMAL ("bug: adapter %s (%p) still in use, " "%i requests outstanding\n" ,zfcp_get_busid_by_adapter (adapter), adapter, -atomic_read (&adapter->fsf_reqs_active)); +atomic_read (&adapter->reqs_active)); retval = -EBUSY ; goto out; }
@@ -1087,6 +1188,7 @@ zfcp_adapter_dequeue(struct zfcp_adapterzfcp_free_low_mem_buffers (adapter);/* free memory of adapter data structure and queues */ zfcp_qdio_free_queues (adapter); +zfcp_reqlist_free (adapter);kfree (adapter->fc_stats);kfree (adapter->stats_reset_data);ZFCP_LOG_TRACE ("freeing adapter structure\n" );
drivers/s390/scsi/zfcp_ccw.c +5 -0
@@ -164,6 +164,11 @@ zfcp_ccw_set_online(struct ccw_device *c retval =zfcp_adapter_scsi_register (adapter);if (retval) goto out_scsi_register; + +/* initialize request counter */ +BUG_ON (!zfcp_reqlist_isempty (adapter)); + adapter->req_no =0 ; +zfcp_erp_modify_adapter_status (adapter,ZFCP_STATUS_COMMON_RUNNING ,ZFCP_SET );zfcp_erp_adapter_reopen (adapter,ZFCP_STATUS_COMMON_ERP_FAILED );
drivers/s390/scsi/zfcp_def.h +6 -5
@@ -886,11 +886,11 @@ struct zfcp_adapter {struct list_head port_remove_lh;/* head of ports to be removed */ u32 ports;/* number of remote ports */ -struct timer_list scsi_er_timer;/* SCSI err recovery watch */ -struct list_head fsf_req_list_head;/* head of FSF req list */ -spinlock_t fsf_req_list_lock;/* lock for ops on list of -FSF requests */ -atomic_t fsf_reqs_active;/* # active FSF reqs */ +struct timer_list scsi_er_timer;/* SCSI err recovery watch */ +atomic_t reqs_active;/* # active FSF reqs */ +unsigned long req_no;/* unique FSF req number */ +struct list_head *req_list;/* list of pending reqs */ +spinlock_t req_list_lock;/* request list lock */ struct zfcp_qdio_queue request_queue;/* request queue */ u32 fsf_req_seq_no;/* FSF cmnd seq number */ wait_queue_head_t request_wq;/* can be used to wait for
@@ -986,6 +986,7 @@ struct zfcp_unit {/* FSF request */ struct zfcp_fsf_req {struct list_head list;/* list of FSF requests */ +unsigned long req_id;/* unique request ID */ struct zfcp_adapter *adapter;/* adapter request belongs to */ u8 sbal_number;/* nr of SBALs free for use */ u8 sbal_first;/* first SBAL for this request */
drivers/s390/scsi/zfcp_erp.c +7 -9
@@ -848,18 +848,16 @@ zfcp_erp_strategy_check_fsfreq(struct zfstruct zfcp_adapter *adapter = erp_action->adapter;if (erp_action->fsf_req) { -/* take lock to ensure that request is not being deleted meanwhile */ -spin_lock (&adapter->fsf_req_list_lock); -/* check whether fsf req does still exist */ -list_for_each_entry (fsf_req, &adapter->fsf_req_list_head, list) -if (fsf_req == erp_action->fsf_req) -break ; -if (fsf_req && (fsf_req->erp_action == erp_action)) { +/* take lock to ensure that request is not deleted meanwhile */ +spin_lock (&adapter->req_list_lock); +if ((!zfcp_reqlist_ismember (adapter, + erp_action->fsf_req->req_id)) && + (fsf_req->erp_action == erp_action)) {/* fsf_req still exists */ debug_text_event (adapter->erp_dbf,3 ,"a_ca_req" );debug_event (adapter->erp_dbf,3 , &fsf_req,sizeof (unsigned long )); -/* dismiss fsf_req of timed out or dismissed erp_action */ +/* dismiss fsf_req of timed out/dismissed erp_action */ if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED |ZFCP_STATUS_ERP_TIMEDOUT )) { debug_text_event(adapter->erp_dbf, 3,
@@ -892,7 +890,7 @@ zfcp_erp_strategy_check_fsfreq(struct zf*/ erp_action->fsf_req =NULL ; } -spin_unlock (&adapter->fsf_req_list_lock); +spin_unlock (&adapter->req_list_lock); }else debug_text_event (adapter->erp_dbf,3 ,"a_ca_noreq" );
drivers/s390/scsi/zfcp_ext.h +5 -1
@@ -63,7 +63,6 @@ extern int zfcp_qdio_allocate_queues(stextern void zfcp_qdio_free_queues (struct zfcp_adapter *);extern int zfcp_qdio_determine_pci (struct zfcp_qdio_queue *,struct zfcp_fsf_req *); -extern int zfcp_qdio_reqid_check (struct zfcp_adapter *,void *);extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req (struct zfcp_fsf_req *,int ,int );
@@ -190,5 +189,10 @@ extern void zfcp_scsi_dbf_event_abort(co struct zfcp_fsf_req *);extern void zfcp_scsi_dbf_event_devreset (const char *,u8 ,struct zfcp_unit *,struct scsi_cmnd *); +extern void zfcp_reqlist_add (struct zfcp_adapter *,struct zfcp_fsf_req *); +extern void zfcp_reqlist_remove (struct zfcp_adapter *,unsigned long ); +extern struct zfcp_fsf_req *zfcp_reqlist_ismember (struct zfcp_adapter *, +unsigned long ); +extern int zfcp_reqlist_isempty (struct zfcp_adapter *);#endif /* ZFCP_EXT_H */
drivers/s390/scsi/zfcp_fsf.c +65 -57
202 lines not on this page · raw message
drivers/s390/scsi/zfcp_qdio.c +32 -47
97 lines not on this page · raw message
Signature · 1 line
1.4.2.rc2.gef1d9