zfcp updates for 2.6.32
Subsystems (3)
cover zfcp updates for 2.6.32
James,
here is the series of zfcp updates for the 2.6.32 merge window. Most patches are concerned with code simplifications and minor improvements. With these patches, zfcp no longer uses the old kernel_thread API and no longer semaphores.
The last patch "zfcp: optimize zfcp_qdio_account" uses a new s390 function that is introduced with the s390 patch "introduce get_clock_monotonic", see http://marc.info/?l=linux-s390&m=125024973232085&w=2
The zfcp patch applies cleanly, but compilation on s390 fails without the s390 patch. This should be no problem for the linux-next tree, since linux-next also includes the s390 git tree.
--
Christof Schmitt
PATCH 1/27 zfcp: invalid usage after free of port resources
From: Swen Schillig <[email protected]>
In certain error scenarios ports, rports are getting attached, validated and removed from the systems environment. Depending on the layer this occurs asynchronously. This patch fixes the few races which existed and ensures all references and cross references are cleared at the time they're invalid. In addition fc transports actions are only scheduled when required.
---
drivers/s390/scsi/zfcp_aux.c | 7 +++++-- drivers/s390/scsi/zfcp_scsi.c | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-)
drivers/s390/scsi/zfcp_aux.c +5 -2
@@ -672,12 +672,15 @@ err_out:*/ void zfcp_port_dequeue (struct zfcp_port *port) { -wait_event (port->remove_wq,atomic_read (&port->refcount) ==0 );write_lock_irq (&zfcp_data.config_lock);list_del (&port->list);write_unlock_irq (&zfcp_data.config_lock); -if (port->rport) +if (port->rport) { port->rport->dd_data =NULL ; + port->rport =NULL ; + } +wait_event (port->remove_wq,atomic_read (&port->refcount) ==0 ); +cancel_work_sync (&port->rport_work);/* usually not necessary */ zfcp_adapter_put (port->adapter);sysfs_remove_group (&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);device_unregister (&port->sysfs_device);
drivers/s390/scsi/zfcp_scsi.c +4 -2
@@ -582,8 +582,10 @@ void zfcp_scsi_schedule_rport_block(struzfcp_port_get (port); port->rport_task =RPORT_DEL ; -if (!queue_work (zfcp_data.work_queue, &port->rport_work)) -zfcp_port_put (port); +if (port->rport &&queue_work (zfcp_data.work_queue, &port->rport_work)) +return ; + +zfcp_port_put (port); }void zfcp_scsi_schedule_rports_block (struct zfcp_adapter *adapter)
PATCH 2/27 zfcp: Move debug data from zfcp_data to own data structure
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The struct zfcp_adapter includes everything related to the debug traces. This introduces dependences between the definitions in zfcp_def.h and zfcp_dbf.h. Move all debug related data structures to a new data structure to break those dependencies and manage the debug data in zfcp_dbf.[hc].
---
drivers/s390/scsi/zfcp_aux.c | 4 drivers/s390/scsi/zfcp_dbf.c | 217 ++++++++++++++++++++++++------------------- drivers/s390/scsi/zfcp_dbf.h | 17 +++ drivers/s390/scsi/zfcp_def.h | 15 -- drivers/s390/scsi/zfcp_fsf.h | 3 5 files changed, 143 insertions(+), 113 deletions(-)
drivers/s390/scsi/zfcp_aux.c +0 -4
@@ -502,10 +502,6 @@ int zfcp_adapter_enqueue(struct ccw_devispin_lock_init (&adapter->req_list_lock); -spin_lock_init (&adapter->hba_dbf_lock); -spin_lock_init (&adapter->san_dbf_lock); -spin_lock_init (&adapter->scsi_dbf_lock); -spin_lock_init (&adapter->rec_dbf_lock);spin_lock_init (&adapter->req_q_lock);spin_lock_init (&adapter->qdio_stat_lock);
drivers/s390/scsi/zfcp_dbf.c +124 -93
459 lines not on this page · raw message
drivers/s390/scsi/zfcp_dbf.h +16 -1
@@ -2,7 +2,7 @@* This file is part of the zfcp device driver for * FCP adapters for IBM System z9 and zSeries. * -* Copyright IBM Corp. 2008, 2008 +* Copyright IBM Corp. 2008, 2009 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by
@@ -222,4 +222,19 @@ struct zfcp_scsi_dbf_record {u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO ]; } __attribute__ ((packed)); +struct zfcp_dbf { +debug_info_t *rec_dbf; +debug_info_t *hba_dbf; +debug_info_t *san_dbf; +debug_info_t *scsi_dbf; +spinlock_t rec_dbf_lock; +spinlock_t hba_dbf_lock; +spinlock_t san_dbf_lock; +spinlock_t scsi_dbf_lock; +struct zfcp_rec_dbf_record rec_dbf_buf; +struct zfcp_hba_dbf_record hba_dbf_buf; +struct zfcp_san_dbf_record san_dbf_buf; +struct zfcp_scsi_dbf_record scsi_dbf_buf; +}; +#endif /* ZFCP_DBF_H */
drivers/s390/scsi/zfcp_def.h +1 -14
@@ -37,10 +37,8 @@#include <asm/debug.h> #include <asm/ebcdic.h> #include <asm/sysinfo.h> -#include "zfcp_dbf.h" #include "zfcp_fsf.h" -/********************* GENERAL DEFINES *********************************/ #define REQUEST_LIST_SIZE 128
@@ -468,18 +466,7 @@ struct zfcp_adapter {u32 erp_low_mem_count;/* nr of erp actions waiting for memory */ struct zfcp_wka_ports *gs;/* generic services */ -debug_info_t *rec_dbf; -debug_info_t *hba_dbf; -debug_info_t *san_dbf;/* debug feature areas */ -debug_info_t *scsi_dbf; -spinlock_t rec_dbf_lock; -spinlock_t hba_dbf_lock; -spinlock_t san_dbf_lock; -spinlock_t scsi_dbf_lock; -struct zfcp_rec_dbf_record rec_dbf_buf; -struct zfcp_hba_dbf_record hba_dbf_buf; -struct zfcp_san_dbf_record san_dbf_buf; -struct zfcp_scsi_dbf_record scsi_dbf_buf; +struct zfcp_dbf *dbf;/* debug traces */ struct zfcp_adapter_mempool pool;/* Adapter memory pools */ struct qdio_initialize qdio_init_data;/* for qdio_establish */ struct fc_host_statistics *fc_stats;
drivers/s390/scsi/zfcp_fsf.h +2 -1
@@ -3,13 +3,14 @@* * Interface to the FSF support functions. * -* Copyright IBM Corporation 2002, 2008 +* Copyright IBM Corporation 2002, 2009 */ #ifndef FSF_H #define FSF_H #include <linux/pfn.h> +#include <linux/scatterlist.h> #define FSF_QTCB_CURRENT_VERSION 0x00000001
PATCH 3/27 zfcp: Only collect SCSI debug data for matching trace levels
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The default trace level is to only trace failed SCSI commands. Thus it is not necessary to collect trace data for most SCSI commands since it will be thrown away later. Restructure the SCSI trace infrastructure to first check the trace level in a inline function and only do the expensive data collection for matching trace levels.
---
drivers/s390/scsi/zfcp_dbf.c | 58 ++------------------------------------ drivers/s390/scsi/zfcp_dbf.h | 63 ++++++++++++++++++++++++++++++++++++++++++ drivers/s390/scsi/zfcp_ext.h | 11 ++----- drivers/s390/scsi/zfcp_fsf.c | 1 drivers/s390/scsi/zfcp_scsi.c | 3 +- 5 files changed, 73 insertions(+), 63 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +4 -54
@@ -921,13 +921,11 @@ static struct debug_view zfcp_san_dbf_vi NULL }; -static void zfcp_scsi_dbf_event (const char *tag,const char *tag2,int level, -struct zfcp_adapter *adapter, -struct scsi_cmnd *scsi_cmnd, -struct zfcp_fsf_req *fsf_req, -unsigned long old_req_id) +void _zfcp_scsi_dbf_event (const char *tag,const char *tag2,int level, +struct zfcp_dbf *dbf,struct scsi_cmnd *scsi_cmnd, +struct zfcp_fsf_req *fsf_req, +unsigned long old_req_id) { -struct zfcp_dbf *dbf = adapter->dbf;struct zfcp_scsi_dbf_record *rec = &dbf->scsi_dbf_buf;struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;unsigned long flags;
@@ -999,54 +997,6 @@ static void zfcp_scsi_dbf_event(const chspin_unlock_irqrestore (&dbf->scsi_dbf_lock, flags); } -/** -* zfcp_scsi_dbf_event_result - trace event for SCSI command completion -* @tag: tag indicating success or failure of SCSI command -* @level: trace level applicable for this event -* @adapter: adapter that has been used to issue the SCSI command -* @scsi_cmnd: SCSI command pointer -* @fsf_req: request used to issue SCSI command (might be NULL) -*/ -void zfcp_scsi_dbf_event_result (const char *tag,int level, -struct zfcp_adapter *adapter, -struct scsi_cmnd *scsi_cmnd, -struct zfcp_fsf_req *fsf_req) -{ -zfcp_scsi_dbf_event ("rslt" , tag, level, adapter, scsi_cmnd, fsf_req,0 ); -} - -/** -* zfcp_scsi_dbf_event_abort - trace event for SCSI command abort -* @tag: tag indicating success or failure of abort operation -* @adapter: adapter thas has been used to issue SCSI command to be aborted -* @scsi_cmnd: SCSI command to be aborted -* @new_fsf_req: request containing abort (might be NULL) -* @old_req_id: identifier of request containg SCSI command to be aborted -*/ -void zfcp_scsi_dbf_event_abort (const char *tag,struct zfcp_adapter *adapter, -struct scsi_cmnd *scsi_cmnd, -struct zfcp_fsf_req *new_fsf_req, -unsigned long old_req_id) -{ -zfcp_scsi_dbf_event ("abrt" , tag,1 , adapter, scsi_cmnd, new_fsf_req, - old_req_id); -} - -/** -* zfcp_scsi_dbf_event_devreset - trace event for Logical Unit or Target Reset -* @tag: tag indicating success or failure of reset operation -* @flag: indicates type of reset (Target Reset, Logical Unit Reset) -* @unit: unit that needs reset -* @scsi_cmnd: SCSI command which caused this error recovery -*/ -void zfcp_scsi_dbf_event_devreset (const char *tag,u8 flag, -struct zfcp_unit *unit, -struct scsi_cmnd *scsi_cmnd) -{ -zfcp_scsi_dbf_event (flag ==FCP_TARGET_RESET ?"trst" :"lrst" , tag,1 , - unit->port->adapter, scsi_cmnd,NULL ,0 ); -} -static int zfcp_scsi_dbf_view_format (debug_info_t *id,struct debug_view *view,char *out_buf,const char *in_buf) {
drivers/s390/scsi/zfcp_dbf.h +63 -0
74 lines not on this page · raw message
drivers/s390/scsi/zfcp_ext.h +3 -8
@@ -57,14 +57,9 @@ extern void zfcp_san_dbf_event_ct_responextern void zfcp_san_dbf_event_els_request (struct zfcp_fsf_req *);extern void zfcp_san_dbf_event_els_response (struct zfcp_fsf_req *);extern void zfcp_san_dbf_event_incoming_els (struct zfcp_fsf_req *); -extern void zfcp_scsi_dbf_event_result (const char *,int ,struct zfcp_adapter *, -struct scsi_cmnd *, -struct zfcp_fsf_req *); -extern void zfcp_scsi_dbf_event_abort (const char *,struct zfcp_adapter *, -struct scsi_cmnd *,struct zfcp_fsf_req *, -unsigned long ); -extern void zfcp_scsi_dbf_event_devreset (const char *,u8 ,struct zfcp_unit *, -struct scsi_cmnd *); +extern void _zfcp_scsi_dbf_event (const char *,const char *,int , +struct zfcp_dbf *,struct scsi_cmnd *, +struct zfcp_fsf_req *,unsigned long );/* zfcp_erp.c */ extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, char *,
drivers/s390/scsi/zfcp_fsf.c +1 -0
@@ -11,6 +11,7 @@#include <linux/blktrace_api.h> #include "zfcp_ext.h" +#include "zfcp_dbf.h" #define ZFCP_REQ_AUTO_CLEANUP 0x00000002#define ZFCP_REQ_NO_QTCB 0x00000008
drivers/s390/scsi/zfcp_scsi.c +2 -1
@@ -9,8 +9,9 @@#define KMSG_COMPONENT "zfcp"#define pr_fmt (fmt) KMSG_COMPONENT ": " fmt -#include "zfcp_ext.h" #include <asm/atomic.h> +#include "zfcp_ext.h" +#include "zfcp_dbf.h" static unsigned int default_depth =32 ;module_param_named (queue_depth, default_depth, uint,0600 );
PATCH 4/27 zfcp: Only collect FSF/HBA debug data for matching trace levels
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The default trace level is to only trace failed FSF commands. Thus it is not necessary to collect trace data for most FSF commands, since it will be thrown away later. Restructure the FSF/HBA trace infrastructure to first check the trace level in a inline function and only do the expensive data collection for matching trace levels.
---
drivers/s390/scsi/zfcp_dbf.c | 44 ++++++----------------------------- drivers/s390/scsi/zfcp_dbf.h | 53 +++++++++++++++++++++++++++++++++++++++++++ drivers/s390/scsi/zfcp_ext.h | 9 ++++--- 3 files changed, 67 insertions(+), 39 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +8 -36
@@ -120,14 +120,10 @@ static int zfcp_dbf_view_header(debug_inreturn p - out_buf; } -/** -* zfcp_hba_dbf_event_fsf_response - trace event for request completion -* @fsf_req: request that has been completed -*/ -void zfcp_hba_dbf_event_fsf_response (struct zfcp_fsf_req *fsf_req) +void _zfcp_hba_dbf_event_fsf_response (const char *tag2,int level, +struct zfcp_fsf_req *fsf_req, +struct zfcp_dbf *dbf) { -struct zfcp_adapter *adapter = fsf_req->adapter; -struct zfcp_dbf *dbf = adapter->dbf;struct fsf_qtcb *qtcb = fsf_req->qtcb;union fsf_prot_status_qual *prot_status_qual = &qtcb->prefix.prot_status_qual;
@@ -138,31 +134,12 @@ void zfcp_hba_dbf_event_fsf_response(strstruct zfcp_send_els *send_els;struct zfcp_hba_dbf_record *rec = &dbf->hba_dbf_buf;struct zfcp_hba_dbf_record_response *response = &rec->u.response; -int level;unsigned long flags;spin_lock_irqsave (&dbf->hba_dbf_lock, flags);memset (rec,0 ,sizeof (*rec));strncpy (rec->tag,"resp" ,ZFCP_DBF_TAG_SIZE ); - -if ((qtcb->prefix.prot_status !=FSF_PROT_GOOD ) && - (qtcb->prefix.prot_status !=FSF_PROT_FSF_STATUS_PRESENTED )) { -strncpy (rec->tag2,"perr" ,ZFCP_DBF_TAG_SIZE ); - level =1 ; - }else if (qtcb->header.fsf_status !=FSF_GOOD ) { -strncpy (rec->tag2,"ferr" ,ZFCP_DBF_TAG_SIZE ); - level =1 ; - }else if ((fsf_req->fsf_command ==FSF_QTCB_OPEN_PORT_WITH_DID ) || - (fsf_req->fsf_command ==FSF_QTCB_OPEN_LUN )) { -strncpy (rec->tag2,"open" ,ZFCP_DBF_TAG_SIZE ); - level =4 ; - }else if (qtcb->header.log_length) { -strncpy (rec->tag2,"qtcb" ,ZFCP_DBF_TAG_SIZE ); - level =5 ; - }else { -strncpy (rec->tag2,"norm" ,ZFCP_DBF_TAG_SIZE ); - level =6 ; - } +strncpy (rec->tag2, tag2,ZFCP_DBF_TAG_SIZE ); response->fsf_command = fsf_req->fsf_command; response->fsf_reqid = fsf_req->req_id;
@@ -241,14 +218,9 @@ void zfcp_hba_dbf_event_fsf_response(strspin_unlock_irqrestore (&dbf->hba_dbf_lock, flags); } -/** -* zfcp_hba_dbf_event_fsf_unsol - trace event for an unsolicited status buffer -* @tag: tag indicating which kind of unsolicited status has been received -* @adapter: adapter that has issued the unsolicited status buffer -* @status_buffer: buffer containing payload of unsolicited status -*/ -void zfcp_hba_dbf_event_fsf_unsol (const char *tag,struct zfcp_adapter *adapter, -struct fsf_status_read_buffer *status_buffer) +void _zfcp_hba_dbf_event_fsf_unsol (const char *tag,int level, +struct zfcp_adapter *adapter, +struct fsf_status_read_buffer *status_buffer) {struct zfcp_dbf *dbf = adapter->dbf;struct zfcp_hba_dbf_record *rec = &dbf->hba_dbf_buf;
@@ -296,7 +268,7 @@ void zfcp_hba_dbf_event_fsf_unsol(const &status_buffer->payload, rec->u.status.payload_size); } -debug_event (dbf->hba_dbf,2 , rec,sizeof (*rec)); +debug_event (dbf->hba_dbf, level, rec,sizeof (*rec));spin_unlock_irqrestore (&dbf->hba_dbf_lock, flags); }
drivers/s390/scsi/zfcp_dbf.h +53 -0
59 lines not on this page · raw message
drivers/s390/scsi/zfcp_ext.h +6 -3
@@ -45,9 +45,12 @@ extern void zfcp_rec_dbf_event_trigger(c struct zfcp_adapter *, struct zfcp_port *, struct zfcp_unit *);extern void zfcp_rec_dbf_event_action (char *,struct zfcp_erp_action *); -extern void zfcp_hba_dbf_event_fsf_response (struct zfcp_fsf_req *); -extern void zfcp_hba_dbf_event_fsf_unsol (const char *,struct zfcp_adapter *, -struct fsf_status_read_buffer *); +extern void _zfcp_hba_dbf_event_fsf_response (const char *,int level, +struct zfcp_fsf_req *, +struct zfcp_dbf *dbf); +extern void _zfcp_hba_dbf_event_fsf_unsol (const char *,int level, +struct zfcp_adapter *, +struct fsf_status_read_buffer *);extern void zfcp_hba_dbf_event_qdio (struct zfcp_adapter *,unsigned int ,int ,int ); extern void zfcp_hba_dbf_event_berr(struct zfcp_adapter *,
PATCH 5/27 zfcp: Remove useless assignment
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Using a bitwise OR to not set anything at all is pointless so remove the useless statement.
---
drivers/s390/scsi/zfcp_fsf.c | 1 - 1 file changed, 1 deletion(-)
drivers/s390/scsi/zfcp_fsf.c +0 -1
@@ -832,7 +832,6 @@ int zfcp_fsf_status_read(struct zfcp_ada } sbale =zfcp_qdio_sbale_req (req); - sbale[0 ].flags |=SBAL_FLAGS0_TYPE_STATUS ; sbale[2 ].flags |=SBAL_FLAGS_LAST_ENTRY ; req->sbale_curr =2 ;
PATCH 6/27 zfcp: Only issue one test link command per port
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
When the FCP channel returns a series of commands with the error status "test link", zfcp will send a series of ELS ADISC commands. This is technically no problem, but it is enough to only issue one test command per remote port. So, track whether a ELS ADISC command is already pending, and do not send a new one if there is already a pending command.
---
drivers/s390/scsi/zfcp_def.h | 1 + drivers/s390/scsi/zfcp_fc.c | 9 +++++++++ 2 files changed, 10 insertions(+)
drivers/s390/scsi/zfcp_def.h +1 -0
@@ -232,6 +232,7 @@ struct zfcp_ls_adisc {/* remote port status */ #define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001 +#define ZFCP_STATUS_PORT_LINK_TEST 0x00000002/* well known address (WKA) port status*/ enum zfcp_wka_status {
drivers/s390/scsi/zfcp_fc.c +9 -0
@@ -404,6 +404,7 @@ static void zfcp_fc_adisc_handler(unsign/* port is good, unblock rport without going through erp */ zfcp_scsi_schedule_rport_register (port); out: +atomic_clear_mask (ZFCP_STATUS_PORT_LINK_TEST , &port->status);zfcp_port_put (port);kfree (adisc); }
@@ -450,13 +451,21 @@ void zfcp_fc_link_test_work(struct work_ port->rport_task =RPORT_DEL ;zfcp_scsi_rport_work (&port->rport_work); +/* only issue one test command at one time per port */ +if (atomic_read (&port->status) &ZFCP_STATUS_PORT_LINK_TEST ) + goto out; + +atomic_set_mask (ZFCP_STATUS_PORT_LINK_TEST , &port->status); + retval =zfcp_fc_adisc (port);if (retval ==0 )return ;/* send of ADISC was not possible */ +atomic_clear_mask (ZFCP_STATUS_PORT_LINK_TEST , &port->status);zfcp_erp_port_forced_reopen (port,0 ,"fcltwk1" ,NULL ); +out:zfcp_port_put (port); }
PATCH 7/27 zfcp: Implicitly close all wka ports
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
An adapter shutdown implicitly closes all open ports. Make sure to mark all WKA ports as offline, not only the directory server. Also make sure that no pending wka port work is running when the adapter is being removed.
---
drivers/s390/scsi/zfcp_aux.c | 1 + drivers/s390/scsi/zfcp_erp.c | 2 +- drivers/s390/scsi/zfcp_ext.h | 4 +--- drivers/s390/scsi/zfcp_fc.c | 11 ++++++++++- 4 files changed, 13 insertions(+), 5 deletions(-)
drivers/s390/scsi/zfcp_aux.c +1 -0
@@ -555,6 +555,7 @@ void zfcp_adapter_dequeue(struct zfcp_adcancel_work_sync (&adapter->scan_work);cancel_work_sync (&adapter->stat_work); +zfcp_fc_wka_ports_force_offline (adapter->gs);zfcp_adapter_scsi_unregister (adapter);sysfs_remove_group (&adapter->ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs);
drivers/s390/scsi/zfcp_erp.c +1 -1
@@ -714,7 +714,7 @@ static void zfcp_erp_adapter_strategy_clzfcp_qdio_close (adapter);zfcp_fsf_req_dismiss_all (adapter); adapter->fsf_req_seq_no =0 ; -zfcp_fc_wka_port_force_offline (&adapter->gs->ds); +zfcp_fc_wka_ports_force_offline (adapter->gs);/* all ports and units are closed */ zfcp_erp_modify_adapter_status (adapter,"erascl1" ,NULL ,ZFCP_STATUS_COMMON_OPEN ,ZFCP_CLEAR );
drivers/s390/scsi/zfcp_ext.h +1 -3
@@ -104,12 +104,10 @@ extern int zfcp_fc_ns_gid_pn(struct zfcpextern void zfcp_fc_plogi_evaluate (struct zfcp_port *,struct fsf_plogi *);extern void zfcp_test_link (struct zfcp_port *);extern void zfcp_fc_link_test_work (struct work_struct *); -extern void zfcp_fc_wka_port_force_offline (struct zfcp_wka_port *); +extern void zfcp_fc_wka_ports_force_offline (struct zfcp_wka_ports *);extern void zfcp_fc_wka_ports_init (struct zfcp_adapter *);extern int zfcp_fc_execute_els_fc_job (struct fc_bsg_job *);extern int zfcp_fc_execute_ct_fc_job (struct fc_bsg_job *); -extern void zfcp_fc_wka_port_force_offline (struct zfcp_wka_port *); -/* zfcp_fsf.c */ extern int zfcp_fsf_open_port (struct zfcp_erp_action *);
drivers/s390/scsi/zfcp_fc.c +10 -1
@@ -132,7 +132,7 @@ static void zfcp_fc_wka_port_init(structINIT_DELAYED_WORK (&wka_port->work, zfcp_wka_port_offline); } -void zfcp_fc_wka_port_force_offline (struct zfcp_wka_port *wka) +static void zfcp_fc_wka_port_force_offline (struct zfcp_wka_port *wka) {cancel_delayed_work_sync (&wka->work);mutex_lock (&wka->mutex);
@@ -140,6 +140,15 @@ void zfcp_fc_wka_port_force_offline(strumutex_unlock (&wka->mutex); } +void zfcp_fc_wka_ports_force_offline (struct zfcp_wka_ports *gs) +{ +zfcp_fc_wka_port_force_offline (&gs->ms); +zfcp_fc_wka_port_force_offline (&gs->ts); +zfcp_fc_wka_port_force_offline (&gs->ds); +zfcp_fc_wka_port_force_offline (&gs->as); +zfcp_fc_wka_port_force_offline (&gs->ks); +} +void zfcp_fc_wka_ports_init (struct zfcp_adapter *adapter) {struct zfcp_wka_ports *gs = adapter->gs;
PATCH 8/27 zfcp: fix layering oddities between zfcp_fsf and zfcp_qdio
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
There is no need for the QDIO layer to have knowledge or do things wich are done better by the FSF layer and vice versa. Straighten a few things to improve vividness.
---
drivers/s390/scsi/zfcp_ext.h | 2 drivers/s390/scsi/zfcp_fsf.c | 100 +++++++++++++++++++++++++++++------------- drivers/s390/scsi/zfcp_qdio.c | 45 ------------------ 3 files changed, 73 insertions(+), 74 deletions(-)
drivers/s390/scsi/zfcp_ext.h +1 -1
@@ -133,11 +133,11 @@ extern int zfcp_fsf_send_ct(struct zfcp_extern int zfcp_fsf_send_els (struct zfcp_send_els *);extern int zfcp_fsf_send_fcp_command_task (struct zfcp_unit *,struct scsi_cmnd *); -extern void zfcp_fsf_req_complete (struct zfcp_fsf_req *);extern void zfcp_fsf_req_free (struct zfcp_fsf_req *);extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm (struct zfcp_unit *,u8 );extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command (unsigned long ,struct zfcp_unit *); +extern void zfcp_fsf_reqid_check (struct zfcp_adapter *,int );/* zfcp_qdio.c */ extern int zfcp_qdio_allocate (struct zfcp_adapter *);
drivers/s390/scsi/zfcp_fsf.c +70 -30
121 lines not on this page · raw message
drivers/s390/scsi/zfcp_qdio.c +2 -43
64 lines not on this page · raw message
PATCH 9/27 zfcp: Replace fsf_req wait_queue with completion
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
The combination wait_queue/wakeup in conjunction with the flag ZFCP_STATUS_FSFREQ_COMPLETED to signal the completion of an fsfreq was not race-safe and can be better solved by a completion.
---
drivers/s390/scsi/zfcp_def.h | 3 +-- drivers/s390/scsi/zfcp_erp.c | 3 +-- drivers/s390/scsi/zfcp_fsf.c | 26 ++++++-------------------- drivers/s390/scsi/zfcp_scsi.c | 6 ++---- 4 files changed, 10 insertions(+), 28 deletions(-)
drivers/s390/scsi/zfcp_def.h +1 -2
@@ -248,7 +248,6 @@ enum zfcp_wka_status {/* FSF request status (this does not have a common part) */ #define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002 -#define ZFCP_STATUS_FSFREQ_COMPLETED 0x00000004#define ZFCP_STATUS_FSFREQ_ERROR 0x00000008#define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010#define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040
@@ -532,7 +531,7 @@ struct zfcp_fsf_req {u8 sbale_curr;/* current SBALE during creation of request */ u8 sbal_response;/* SBAL used in interrupt */ -wait_queue_head_t completion_wq;/* can be used by a routine +struct completion completion;/* can be used by a routine to wait for completion */ u32 status;/* status of this request */ u32 fsf_command;/* FSF Command copy */
drivers/s390/scsi/zfcp_erp.c +1 -2
@@ -485,8 +485,7 @@ static void zfcp_erp_strategy_check_fsfr }if (act->status &ZFCP_STATUS_ERP_TIMEDOUT )zfcp_rec_dbf_event_action ("erscf_2" , act); -if (act->fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED | -ZFCP_STATUS_FSFREQ_DISMISSED )) +if (act->fsf_req->status &ZFCP_STATUS_FSFREQ_DISMISSED ) act->fsf_req =NULL ; }else act->fsf_req =NULL ;
drivers/s390/scsi/zfcp_fsf.c +6 -20
@@ -444,23 +444,11 @@ static void zfcp_fsf_req_complete(structif (req->erp_action)zfcp_erp_notify (req->erp_action,0 ); - req->status |=ZFCP_STATUS_FSFREQ_COMPLETED ;if (likely (req->status &ZFCP_STATUS_FSFREQ_CLEANUP ))zfcp_fsf_req_free (req);else -/* notify initiator waiting for the requests completion */ -/* -* FIXME: Race! We must not access fsf_req here as it might have been -* cleaned up already due to the set ZFCP_STATUS_FSFREQ_COMPLETED -* flag. It's an improbable case. But, we have the same paranoia for -* the cleanup flag already. -* Might better be handled using complete()? -* (setting the flag and doing wakeup ought to be atomic -* with regard to checking the flag as long as waitqueue is -* part of the to be released structure) -*/ -wake_up (&req->completion_wq); +complete (&req->completion); }/**
@@ -733,7 +721,7 @@ static struct zfcp_fsf_req *zfcp_fsf_reqINIT_LIST_HEAD (&req->list);init_timer (&req->timer); -init_waitqueue_head (&req->completion_wq); +init_completion (&req->completion); req->adapter = adapter; req->fsf_command = fsf_cmd;
@@ -1309,8 +1297,7 @@ int zfcp_fsf_exchange_config_data_sync(s retval =zfcp_fsf_req_send (req);spin_unlock_bh (&adapter->req_q_lock);if (!retval) -wait_event (req->completion_wq, - req->status &ZFCP_STATUS_FSFREQ_COMPLETED ); +wait_for_completion (&req->completion);zfcp_fsf_req_free (req);return retval;
@@ -1405,8 +1392,8 @@ int zfcp_fsf_exchange_port_data_sync(strspin_unlock_bh (&adapter->req_q_lock);if (!retval) -wait_event (req->completion_wq, - req->status &ZFCP_STATUS_FSFREQ_COMPLETED ); +wait_for_completion (&req->completion); +zfcp_fsf_req_free (req);return retval;
@@ -2572,8 +2559,7 @@ out:spin_unlock_bh (&adapter->req_q_lock);if (!retval) { -wait_event (req->completion_wq, - req->status &ZFCP_STATUS_FSFREQ_COMPLETED ); +wait_for_completion (&req->completion);return req; }return ERR_PTR (retval);
drivers/s390/scsi/zfcp_scsi.c +2 -4
@@ -206,8 +206,7 @@ static int zfcp_scsi_eh_abort_handler(stif (!abrt_req)return FAILED ; -wait_event (abrt_req->completion_wq, - abrt_req->status &ZFCP_STATUS_FSFREQ_COMPLETED ); +wait_for_completion (&abrt_req->completion);if (abrt_req->status &ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED ) dbf_tag ="okay" ;
@@ -246,8 +245,7 @@ static int zfcp_task_mgmt_function(strucif (!fsf_req)return FAILED ; -wait_event (fsf_req->completion_wq, - fsf_req->status &ZFCP_STATUS_FSFREQ_COMPLETED ); +wait_for_completion (&fsf_req->completion);if (fsf_req->status &ZFCP_STATUS_FSFREQ_TMFUNCFAILED ) {zfcp_scsi_dbf_event_devreset ("fail" , tm_flags, unit, scpnt);
PATCH 10/27 zfcp: Improve request allocation through mempools
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
Remove the special case for NO_QTCB requests and optimize the mempool and cache processing for fsfreqs. Especially use seperate mempools for the zfcp_fsf_req and zfcp_qtcb structs.
---
drivers/s390/scsi/zfcp_aux.c | 98 ++++++++++++++++++++++++------------------- drivers/s390/scsi/zfcp_def.h | 31 +++++++------ drivers/s390/scsi/zfcp_fc.c | 19 ++------ drivers/s390/scsi/zfcp_fsf.c | 92 +++++++++++++++++++++------------------- 4 files changed, 127 insertions(+), 113 deletions(-)
drivers/s390/scsi/zfcp_aux.c +55 -43
@@ -42,6 +42,12 @@ static char *init_device;module_param_named (device, init_device, charp,0400 );MODULE_PARM_DESC (device,"specify initial device" ); +static struct kmem_cache *zfcp_cache_hw_align (const char *name, +unsigned long size) +{ +return kmem_cache_create (name, size,roundup_pow_of_two (size),0 ,NULL ); +} +static int zfcp_reqlist_alloc (struct zfcp_adapter *adapter) {int idx;
@@ -110,14 +116,6 @@ out_adapter:return ; } -static struct kmem_cache *zfcp_cache_create (int size,char *name) -{ -int align =1 ; -while ((size - align) >0 ) - align <<=1 ; -return kmem_cache_create (name , size, align,0 ,NULL ); -} -static void __init zfcp_init_device_setup (char *devstr) {char *token;
@@ -158,18 +156,23 @@ static int __init zfcp_module_init(void) {int retval = -ENOMEM ; - zfcp_data.fsf_req_qtcb_cache =zfcp_cache_create ( -sizeof (struct zfcp_fsf_req_qtcb ),"zfcp_fsf" ); -if (!zfcp_data.fsf_req_qtcb_cache) + zfcp_data.gpn_ft_cache =zfcp_cache_hw_align ("zfcp_gpn" , +sizeof (struct ct_iu_gpn_ft_req )); +if (!zfcp_data.gpn_ft_cache) goto out; - zfcp_data.sr_buffer_cache =zfcp_cache_create ( -sizeof (struct fsf_status_read_buffer ),"zfcp_sr" ); + zfcp_data.qtcb_cache =zfcp_cache_hw_align ("zfcp_qtcb" , +sizeof (struct fsf_qtcb )); +if (!zfcp_data.qtcb_cache) + goto out_qtcb_cache; + + zfcp_data.sr_buffer_cache =zfcp_cache_hw_align ("zfcp_sr" , +sizeof (struct fsf_status_read_buffer ));if (!zfcp_data.sr_buffer_cache) goto out_sr_cache; - zfcp_data.gid_pn_cache =zfcp_cache_create ( -sizeof (struct zfcp_gid_pn_data ),"zfcp_gid" ); + zfcp_data.gid_pn_cache =zfcp_cache_hw_align ("zfcp_gid" , +sizeof (struct zfcp_gid_pn_data ));if (!zfcp_data.gid_pn_cache) goto out_gid_cache;
@@ -209,7 +212,9 @@ out_transport: out_gid_cache:kmem_cache_destroy (zfcp_data.sr_buffer_cache); out_sr_cache: -kmem_cache_destroy (zfcp_data.fsf_req_qtcb_cache); +kmem_cache_destroy (zfcp_data.qtcb_cache); +out_qtcb_cache: +kmem_cache_destroy (zfcp_data.gpn_ft_cache); out:return retval; }
@@ -354,36 +359,41 @@ void zfcp_unit_dequeue(struct zfcp_unitstatic int zfcp_allocate_low_mem_buffers (struct zfcp_adapter *adapter) {/* must only be called with zfcp_data.config_sema taken */ - adapter->pool.fsf_req_erp = -mempool_create_slab_pool (1 , zfcp_data.fsf_req_qtcb_cache); -if (!adapter->pool.fsf_req_erp) + adapter->pool.erp_req = +mempool_create_kmalloc_pool (1 ,sizeof (struct zfcp_fsf_req )); +if (!adapter->pool.erp_req)return -ENOMEM ; - adapter->pool.fsf_req_scsi = -mempool_create_slab_pool (1 , zfcp_data.fsf_req_qtcb_cache); -if (!adapter->pool.fsf_req_scsi) + adapter->pool.scsi_req = +mempool_create_kmalloc_pool (1 ,sizeof (struct zfcp_fsf_req )); +if (!adapter->pool.scsi_req)return -ENOMEM ; - adapter->pool.fsf_req_abort = -mempool_create_slab_pool (1 , zfcp_data.fsf_req_qtcb_cache); -if (!adapter->pool.fsf_req_abort) + adapter->pool.scsi_abort = +mempool_create_kmalloc_pool (1 ,sizeof (struct zfcp_fsf_req )); +if (!adapter->pool.scsi_abort)return -ENOMEM ; - adapter->pool.fsf_req_status_read = + adapter->pool.status_read_req =mempool_create_kmalloc_pool (FSF_STATUS_READS_RECOM ,sizeof (struct zfcp_fsf_req )); -if (!adapter->pool.fsf_req_status_read) +if (!adapter->pool.status_read_req) +return -ENOMEM ; + + adapter->pool.qtcb_pool = +mempool_create_slab_pool (3 , zfcp_data.qtcb_cache); +if (!adapter->pool.qtcb_pool)return -ENOMEM ; - adapter->pool.data_status_read = + adapter->pool.status_read_data =mempool_create_slab_pool (FSF_STATUS_READS_RECOM , zfcp_data.sr_buffer_cache); -if (!adapter->pool.data_status_read) +if (!adapter->pool.status_read_data)return -ENOMEM ; - adapter->pool.data_gid_pn = + adapter->pool.gid_pn_data =mempool_create_slab_pool (1 , zfcp_data.gid_pn_cache); -if (!adapter->pool.data_gid_pn) +if (!adapter->pool.gid_pn_data)return -ENOMEM ;return 0 ;
@@ -392,18 +402,20 @@ static int zfcp_allocate_low_mem_buffersstatic void zfcp_free_low_mem_buffers (struct zfcp_adapter *adapter) {/* zfcp_data.config_sema must be held */ -if (adapter->pool.fsf_req_erp) -mempool_destroy (adapter->pool.fsf_req_erp); -if (adapter->pool.fsf_req_scsi) -mempool_destroy (adapter->pool.fsf_req_scsi); -if (adapter->pool.fsf_req_abort) -mempool_destroy (adapter->pool.fsf_req_abort); -if (adapter->pool.fsf_req_status_read) -mempool_destroy (adapter->pool.fsf_req_status_read); -if (adapter->pool.data_status_read) -mempool_destroy (adapter->pool.data_status_read); -if (adapter->pool.data_gid_pn) -mempool_destroy (adapter->pool.data_gid_pn); +if (adapter->pool.erp_req) +mempool_destroy (adapter->pool.erp_req); +if (adapter->pool.scsi_req) +mempool_destroy (adapter->pool.scsi_req); +if (adapter->pool.scsi_abort) +mempool_destroy (adapter->pool.scsi_abort); +if (adapter->pool.qtcb_pool) +mempool_destroy (adapter->pool.qtcb_pool); +if (adapter->pool.status_read_req) +mempool_destroy (adapter->pool.status_read_req); +if (adapter->pool.status_read_data) +mempool_destroy (adapter->pool.status_read_data); +if (adapter->pool.gid_pn_data) +mempool_destroy (adapter->pool.gid_pn_data); }/**
drivers/s390/scsi/zfcp_def.h +18 -13
@@ -264,12 +264,13 @@ struct zfcp_fsf_req;/* holds various memory pools of an adapter */ struct zfcp_adapter_mempool { -mempool_t *fsf_req_erp; -mempool_t *fsf_req_scsi; -mempool_t *fsf_req_abort; -mempool_t *fsf_req_status_read; -mempool_t *data_status_read; -mempool_t *data_gid_pn; +mempool_t *erp_req; +mempool_t *scsi_req; +mempool_t *scsi_abort; +mempool_t *status_read_req; +mempool_t *status_read_data; +mempool_t *gid_pn_data; +mempool_t *qtcb_pool; };/*
@@ -303,6 +304,15 @@ struct ct_iu_gid_pn_resp {u32 d_id; } __attribute__ ((packed)); +struct ct_iu_gpn_ft_req { +struct ct_hdr header; +u8 flags; +u8 domain_id_scope; +u8 area_id_scope; +u8 fc4_type; +} __attribute__ ((packed)); + +/** * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct * @wka_port: port where the request is sent to
@@ -559,18 +569,13 @@ struct zfcp_data {lists */ struct semaphore config_sema;/* serialises configuration changes */ -struct kmem_cache *fsf_req_qtcb_cache; +struct kmem_cache *gpn_ft_cache; +struct kmem_cache *qtcb_cache;struct kmem_cache *sr_buffer_cache;struct kmem_cache *gid_pn_cache;struct workqueue_struct *work_queue; }; -/* struct used by memory pools for fsf_requests */ -struct zfcp_fsf_req_qtcb { -struct zfcp_fsf_req fsf_req; -struct fsf_qtcb qtcb; -}; -/********************** ZFCP SPECIFIC DEFINES ********************************/ #define ZFCP_SET 0x00000100
drivers/s390/scsi/zfcp_fc.c +5 -14
@@ -25,14 +25,6 @@ static u32 rscn_range_mask[] = { [RSCN_FABRIC_ADDRESS] = 0x000000, }; -struct ct_iu_gpn_ft_req { -struct ct_hdr header; -u8 flags; -u8 domain_id_scope; -u8 area_id_scope; -u8 fc4_type; -} __attribute__ ((packed)); -struct gpn_ft_resp_acc {u8 control;u8 port_id[3 ];
@@ -322,8 +314,7 @@ int static zfcp_fc_ns_gid_pn_request(strinit_completion (&compl_rec.done); compl_rec.handler = zfcp_fc_ns_gid_pn_eval; compl_rec.handler_data = (unsigned long ) gid_pn; - ret =zfcp_fsf_send_ct (&gid_pn->ct, adapter->pool.fsf_req_erp, - erp_action); + ret =zfcp_fsf_send_ct (&gid_pn->ct, adapter->pool.erp_req, erp_action);if (!ret)wait_for_completion (&compl_rec.done);return ret;
@@ -340,7 +331,7 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_acstruct zfcp_gid_pn_data *gid_pn;struct zfcp_adapter *adapter = erp_action->adapter; - gid_pn =mempool_alloc (adapter->pool.data_gid_pn,GFP_ATOMIC ); + gid_pn =mempool_alloc (adapter->pool.gid_pn_data,GFP_ATOMIC );if (!gid_pn)return -ENOMEM ;
@@ -354,7 +345,7 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_aczfcp_wka_port_put (&adapter->gs->ds); out: -mempool_free (gid_pn, adapter->pool.data_gid_pn); +mempool_free (gid_pn, adapter->pool.gid_pn_data);return ret; }
@@ -497,7 +488,7 @@ static void zfcp_free_sg_env(struct zfcp {struct scatterlist *sg = &gpn_ft->sg_req; -kfree (sg_virt (sg));/* free request buffer */ +kmem_cache_free (zfcp_data.gpn_ft_cache,sg_virt (sg));zfcp_sg_free_table (gpn_ft->sg_resp, buf_num);kfree (gpn_ft);
@@ -512,7 +503,7 @@ static struct zfcp_gpn_ft *zfcp_alloc_sgif (!gpn_ft)return NULL ; - req =kzalloc (sizeof (struct ct_iu_gpn_ft_req ),GFP_KERNEL ); + req =kmem_cache_alloc (zfcp_data.gpn_ft_cache,GFP_KERNEL );if (!req) {kfree (gpn_ft); gpn_ft =NULL ;
drivers/s390/scsi/zfcp_fsf.c +49 -43
246 lines not on this page · raw message
PATCH 11/27 zfcp: Remove the useless ZFCP_REQ_AUTO_CLEANUP flag
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
The flag ZFCP_REQ_AUTO_CLEANUP was useless as the ZFCP_STATUS_FSFREQ_CLEANUP flag is there for exactly the same purpose.
---
drivers/s390/scsi/zfcp_fsf.c | 80 ++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 35 deletions(-)
drivers/s390/scsi/zfcp_fsf.c +45 -35
@@ -13,8 +13,6 @@#include "zfcp_ext.h" #include "zfcp_dbf.h" -#define ZFCP_REQ_AUTO_CLEANUP 0x00000002 -static void zfcp_fsf_request_timeout_handler (unsigned long data) {struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
@@ -703,8 +701,7 @@ static struct fsf_qtcb *zfcp_qtcb_alloc( }static struct zfcp_fsf_req *zfcp_fsf_req_create (struct zfcp_adapter *adapter, -u32 fsf_cmd,int req_flags, -mempool_t *pool) +u32 fsf_cmd,mempool_t *pool) {struct qdio_buffer_element *sbale;struct zfcp_qdio_queue *req_q = &adapter->req_q;
@@ -761,9 +758,6 @@ static struct zfcp_fsf_req *zfcp_fsf_reqreturn ERR_PTR (-EIO ); } -if (likely (req_flags &ZFCP_REQ_AUTO_CLEANUP )) - req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; -return req; }
@@ -818,7 +812,7 @@ int zfcp_fsf_status_read(struct zfcp_adaif (zfcp_fsf_req_sbal_get (adapter)) goto out; - req =zfcp_fsf_req_create (adapter,FSF_QTCB_UNSOLICITED_STATUS ,0 , + req =zfcp_fsf_req_create (adapter,FSF_QTCB_UNSOLICITED_STATUS , adapter->pool.status_read_req);if (IS_ERR (req)) { retval =PTR_ERR (req);
@@ -925,7 +919,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_if (zfcp_fsf_req_sbal_get (adapter)) goto out; req =zfcp_fsf_req_create (adapter,FSF_QTCB_ABORT_FCP_CMND , -0 , adapter->pool.scsi_abort); + adapter->pool.scsi_abort);if (IS_ERR (req)) { req =NULL ; goto out;
@@ -1081,13 +1075,14 @@ int zfcp_fsf_send_ct(struct zfcp_send_ctif (zfcp_fsf_req_sbal_get (adapter)) goto out; - req =zfcp_fsf_req_create (adapter,FSF_QTCB_SEND_GENERIC , -ZFCP_REQ_AUTO_CLEANUP , pool); + req =zfcp_fsf_req_create (adapter,FSF_QTCB_SEND_GENERIC , pool); +if (IS_ERR (req)) { ret =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; ret =zfcp_fsf_setup_ct_els_sbals (req, ct->req, ct->resp,FSF_MAX_SBALS_PER_REQ );if (ret)
@@ -1189,13 +1184,15 @@ int zfcp_fsf_send_els(struct zfcp_send_espin_lock_bh (&adapter->req_q_lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out; - req =zfcp_fsf_req_create (adapter,FSF_QTCB_SEND_ELS , -ZFCP_REQ_AUTO_CLEANUP ,NULL ); + + req =zfcp_fsf_req_create (adapter,FSF_QTCB_SEND_ELS ,NULL ); +if (IS_ERR (req)) { ret =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; ret =zfcp_fsf_setup_ct_els_sbals (req, els->req, els->resp,2 );if (ret)
@@ -1234,15 +1231,16 @@ int zfcp_fsf_exchange_config_data(structspin_lock_bh (&adapter->req_q_lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out; - req =zfcp_fsf_req_create (adapter, -FSF_QTCB_EXCHANGE_CONFIG_DATA , -ZFCP_REQ_AUTO_CLEANUP , + + req =zfcp_fsf_req_create (adapter,FSF_QTCB_EXCHANGE_CONFIG_DATA , adapter->pool.erp_req); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; sbale =zfcp_qdio_sbale_req (req); sbale[0 ].flags |=SBAL_FLAGS0_TYPE_READ ; sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ;
@@ -1278,8 +1276,8 @@ int zfcp_fsf_exchange_config_data_sync(sif (zfcp_fsf_req_sbal_get (adapter)) goto out_unlock; - req =zfcp_fsf_req_create (adapter,FSF_QTCB_EXCHANGE_CONFIG_DATA , -0 ,NULL ); + req =zfcp_fsf_req_create (adapter,FSF_QTCB_EXCHANGE_CONFIG_DATA ,NULL ); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out_unlock;
@@ -1331,14 +1329,16 @@ int zfcp_fsf_exchange_port_data(struct zspin_lock_bh (&adapter->req_q_lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out; + req =zfcp_fsf_req_create (adapter,FSF_QTCB_EXCHANGE_PORT_DATA , -ZFCP_REQ_AUTO_CLEANUP , adapter->pool.erp_req); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; sbale =zfcp_qdio_sbale_req (req); sbale[0 ].flags |=SBAL_FLAGS0_TYPE_READ ; sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ;
@@ -1378,8 +1378,8 @@ int zfcp_fsf_exchange_port_data_sync(strif (zfcp_fsf_req_sbal_get (adapter)) goto out_unlock; - req =zfcp_fsf_req_create (adapter,FSF_QTCB_EXCHANGE_PORT_DATA ,0 , -NULL ); + req =zfcp_fsf_req_create (adapter,FSF_QTCB_EXCHANGE_PORT_DATA ,NULL ); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out_unlock;
@@ -1500,15 +1500,15 @@ int zfcp_fsf_open_port(struct zfcp_erp_aif (zfcp_fsf_req_sbal_get (adapter)) goto out; - req =zfcp_fsf_req_create (adapter, -FSF_QTCB_OPEN_PORT_WITH_DID , -ZFCP_REQ_AUTO_CLEANUP , + req =zfcp_fsf_req_create (adapter,FSF_QTCB_OPEN_PORT_WITH_DID , adapter->pool.erp_req); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; sbale =zfcp_qdio_sbale_req (req); sbale[0 ].flags |=SBAL_FLAGS0_TYPE_READ ; sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ;
@@ -1571,13 +1571,14 @@ int zfcp_fsf_close_port(struct zfcp_erp_ goto out; req =zfcp_fsf_req_create (adapter,FSF_QTCB_CLOSE_PORT , -ZFCP_REQ_AUTO_CLEANUP , adapter->pool.erp_req); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; sbale =zfcp_qdio_sbale_req (req); sbale[0 ].flags |=SBAL_FLAGS0_TYPE_READ ; sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ;
@@ -1646,15 +1647,15 @@ int zfcp_fsf_open_wka_port(struct zfcp_wif (zfcp_fsf_req_sbal_get (adapter)) goto out; - req =zfcp_fsf_req_create (adapter, -FSF_QTCB_OPEN_PORT_WITH_DID , -ZFCP_REQ_AUTO_CLEANUP , + req =zfcp_fsf_req_create (adapter,FSF_QTCB_OPEN_PORT_WITH_DID , adapter->pool.erp_req); +if (unlikely (IS_ERR (req))) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; sbale =zfcp_qdio_sbale_req (req); sbale[0 ].flags |=SBAL_FLAGS0_TYPE_READ ; sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ;
@@ -1702,13 +1703,14 @@ int zfcp_fsf_close_wka_port(struct zfcp_ goto out; req =zfcp_fsf_req_create (adapter,FSF_QTCB_CLOSE_PORT , -ZFCP_REQ_AUTO_CLEANUP , adapter->pool.erp_req); +if (unlikely (IS_ERR (req))) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; sbale =zfcp_qdio_sbale_req (req); sbale[0 ].flags |=SBAL_FLAGS0_TYPE_READ ; sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ;
@@ -1793,13 +1795,14 @@ int zfcp_fsf_close_physical_port(struct goto out; req =zfcp_fsf_req_create (adapter,FSF_QTCB_CLOSE_PHYSICAL_PORT , -ZFCP_REQ_AUTO_CLEANUP , adapter->pool.erp_req); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; sbale =zfcp_qdio_sbale_req (req); sbale[0 ].flags |=SBAL_FLAGS0_TYPE_READ ; sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ;
@@ -1965,13 +1968,14 @@ int zfcp_fsf_open_unit(struct zfcp_erp_a goto out; req =zfcp_fsf_req_create (adapter,FSF_QTCB_OPEN_LUN , -ZFCP_REQ_AUTO_CLEANUP , adapter->pool.erp_req); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; sbale =zfcp_qdio_sbale_req (req); sbale[0 ].flags |=SBAL_FLAGS0_TYPE_READ ; sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ;
@@ -2049,14 +2053,16 @@ int zfcp_fsf_close_unit(struct zfcp_erp_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 , -ZFCP_REQ_AUTO_CLEANUP , adapter->pool.erp_req); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ; sbale =zfcp_qdio_sbale_req (req); sbale[0 ].flags |=SBAL_FLAGS0_TYPE_READ ; sbale[1 ].flags |=SBAL_FLAGS_LAST_ENTRY ;
@@ -2353,14 +2359,16 @@ int zfcp_fsf_send_fcp_command_task(strucatomic_inc (&adapter->qdio_outb_full); goto out; } + req =zfcp_fsf_req_create (adapter,FSF_QTCB_FCP_CMND , -ZFCP_REQ_AUTO_CLEANUP , adapter->pool.scsi_req); +if (IS_ERR (req)) { retval =PTR_ERR (req); goto out; } + req->status |=ZFCP_STATUS_FSFREQ_CLEANUP ;zfcp_unit_get (unit); req->unit = unit; req->data = scsi_cmnd;
@@ -2465,8 +2473,10 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_cspin_lock_bh (&adapter->req_q_lock);if (zfcp_fsf_req_sbal_get (adapter)) goto out; - req =zfcp_fsf_req_create (adapter,FSF_QTCB_FCP_CMND ,0 , + + req =zfcp_fsf_req_create (adapter,FSF_QTCB_FCP_CMND , adapter->pool.scsi_req); +if (IS_ERR (req)) { req =NULL ; goto out;
@@ -2537,7 +2547,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_fiif (zfcp_fsf_req_sbal_get (adapter)) goto out; - req =zfcp_fsf_req_create (adapter, fsf_cfdc->command,0 ,NULL ); + req =zfcp_fsf_req_create (adapter, fsf_cfdc->command,NULL );if (IS_ERR (req)) { retval = -EPERM ; goto out;
PATCH 12/27 zfcp: Move workqueue to adapter struct
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
Remove the global driver work queue and replace it with a workqueue local to the adapter. The usage of this workqueue makes this the correct place for the structure. In addition multiple adapters won't block each other due to the serialization of the queued work.
drivers/s390/scsi/zfcp_aux.c +27 -2
@@ -176,8 +176,6 @@ static int __init zfcp_module_init(void)if (!zfcp_data.gid_pn_cache) goto out_gid_cache; - zfcp_data.work_queue =create_singlethread_workqueue ("zfcp_wq" ); -sema_init (&zfcp_data.config_sema,1 );rwlock_init (&zfcp_data.config_lock);
@@ -458,6 +456,27 @@ static void zfcp_print_sl(struct seq_fil adapter->fsf_lic_version); } +static int zfcp_setup_adapter_work_queue (struct zfcp_adapter *adapter) +{ +char name[TASK_COMM_LEN ]; + +snprintf (name,sizeof (name),"zfcp_q_%s" , +dev_name (&adapter->ccw_device->dev)); + adapter->work_queue =create_singlethread_workqueue (name); + +if (adapter->work_queue) +return 0 ; +return -ENOMEM ; +} + +static void zfcp_destroy_adapter_work_queue (struct zfcp_adapter *adapter) +{ +if (adapter->work_queue) +destroy_workqueue (adapter->work_queue); + adapter->work_queue =NULL ; + +} +/** * zfcp_adapter_enqueue - enqueue a new adapter to the list * @ccw_device: pointer to the struct cc_device
@@ -504,6 +523,9 @@ int zfcp_adapter_enqueue(struct ccw_deviif (zfcp_adapter_debug_register (adapter)) goto debug_register_failed; +if (zfcp_setup_adapter_work_queue (adapter)) + goto work_queue_failed; +init_waitqueue_head (&adapter->remove_wq);init_waitqueue_head (&adapter->erp_thread_wqh);init_waitqueue_head (&adapter->erp_done_wqh);
@@ -543,6 +565,8 @@ int zfcp_adapter_enqueue(struct ccw_devireturn 0 ; sysfs_failed: +zfcp_destroy_adapter_work_queue (adapter); +work_queue_failed:zfcp_adapter_debug_unregister (adapter); debug_register_failed:dev_set_drvdata (&ccw_device->dev,NULL );
@@ -579,6 +603,7 @@ void zfcp_adapter_dequeue(struct zfcp_adif (!retval)return ; +zfcp_destroy_adapter_work_queue (adapter);zfcp_adapter_debug_unregister (adapter);zfcp_qdio_free (adapter);zfcp_free_low_mem_buffers (adapter);
drivers/s390/scsi/zfcp_def.h +1 -1
@@ -485,6 +485,7 @@ struct zfcp_adapter {struct work_struct scan_work;struct service_level service_level;atomic_t qdio_outb_full;/* queue full incidents */ +struct workqueue_struct *work_queue; };struct zfcp_port {
@@ -573,7 +574,6 @@ struct zfcp_data {struct kmem_cache *qtcb_cache;struct kmem_cache *sr_buffer_cache;struct kmem_cache *gid_pn_cache; -struct workqueue_struct *work_queue; };/********************** ZFCP SPECIFIC DEFINES ********************************/
drivers/s390/scsi/zfcp_erp.c +1 -1
@@ -875,7 +875,7 @@ static int zfcp_erp_port_strategy_open_creturn zfcp_erp_open_ptp_port (act);if (!port->d_id) {zfcp_port_get (port); -if (!queue_work (zfcp_data.work_queue, +if (!queue_work (adapter->work_queue, &port->gid_pn_work))zfcp_port_put (port);return ZFCP_ERP_CONTINUES ;
drivers/s390/scsi/zfcp_fc.c +1 -1
@@ -480,7 +480,7 @@ out:void zfcp_test_link (struct zfcp_port *port) {zfcp_port_get (port); -if (!queue_work (zfcp_data.work_queue, &port->test_link_work)) +if (!queue_work (port->adapter->work_queue, &port->test_link_work))zfcp_port_put (port); }
drivers/s390/scsi/zfcp_fsf.c +1 -1
@@ -305,7 +305,7 @@ static void zfcp_fsf_status_read_handlerzfcp_fsf_req_free (req);atomic_inc (&adapter->stat_miss); -queue_work (zfcp_data.work_queue, &adapter->stat_work); +queue_work (adapter->work_queue, &adapter->stat_work); }static void zfcp_fsf_fsfstatus_qual_eval (struct zfcp_fsf_req *req)
drivers/s390/scsi/zfcp_scsi.c +3 -2
@@ -572,7 +572,7 @@ void zfcp_scsi_schedule_rport_register(szfcp_port_get (port); port->rport_task =RPORT_ADD ; -if (!queue_work (zfcp_data.work_queue, &port->rport_work)) +if (!queue_work (port->adapter->work_queue, &port->rport_work))zfcp_port_put (port); }
@@ -581,7 +581,8 @@ void zfcp_scsi_schedule_rport_block(struzfcp_port_get (port); port->rport_task =RPORT_DEL ; -if (port->rport &&queue_work (zfcp_data.work_queue, &port->rport_work)) +if (port->rport &&queue_work (port->adapter->work_queue, + &port->rport_work))return ;zfcp_port_put (port);
PATCH 13/27 zfcp: Separate qdio attributes from zfcp_fsf_req
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
Split all qdio related attributes out of zfcp_fsf_req and put it in new structure.
---
drivers/s390/scsi/zfcp_dbf.c | 6 +- drivers/s390/scsi/zfcp_def.h | 84 ++++++++++++++++++++++++------------- drivers/s390/scsi/zfcp_ext.h | 11 +++- drivers/s390/scsi/zfcp_fsf.c | 79 ++++++++++++++++++---------------- drivers/s390/scsi/zfcp_qdio.c | 95 ++++++++++++++++++++++-------------------- 5 files changed, 160 insertions(+), 115 deletions(-)
drivers/s390/scsi/zfcp_dbf.c +3 -3
@@ -152,9 +152,9 @@ void _zfcp_hba_dbf_event_fsf_response(comemcpy (response->fsf_status_qual, fsf_status_qual,FSF_STATUS_QUALIFIER_SIZE ); response->fsf_req_status = fsf_req->status; - response->sbal_first = fsf_req->sbal_first; - response->sbal_last = fsf_req->sbal_last; - response->sbal_response = fsf_req->sbal_response; + response->sbal_first = fsf_req->queue_req.sbal_first; + response->sbal_last = fsf_req->queue_req.sbal_last; + response->sbal_response = fsf_req->queue_req.sbal_response; response->pool = fsf_req->pool !=NULL ; response->erp_action = (unsigned long )fsf_req->erp_action;
drivers/s390/scsi/zfcp_def.h +56 -28
92 lines not on this page · raw message
drivers/s390/scsi/zfcp_ext.h +7 -4
@@ -142,10 +142,13 @@ extern void zfcp_fsf_reqid_check(struct/* zfcp_qdio.c */ extern int zfcp_qdio_allocate (struct zfcp_adapter *);extern void zfcp_qdio_free (struct zfcp_adapter *); -extern int zfcp_qdio_send (struct zfcp_fsf_req *); -extern struct qdio_buffer_element *zfcp_qdio_sbale_req (struct zfcp_fsf_req *); -extern struct qdio_buffer_element *zfcp_qdio_sbale_curr (struct zfcp_fsf_req *); -extern int zfcp_qdio_sbals_from_sg (struct zfcp_fsf_req *,unsigned long , +extern int zfcp_qdio_send (struct zfcp_adapter *,struct zfcp_queue_req *); +extern struct qdio_buffer_element + *zfcp_qdio_sbale_req (struct zfcp_adapter *,struct zfcp_queue_req *); +extern struct qdio_buffer_element + *zfcp_qdio_sbale_curr (struct zfcp_adapter *,struct zfcp_queue_req *); +extern int zfcp_qdio_sbals_from_sg (struct zfcp_adapter *, +struct zfcp_queue_req *,unsigned long ,struct scatterlist *,int );extern int zfcp_qdio_open (struct zfcp_adapter *);extern void zfcp_qdio_close (struct zfcp_adapter *);
drivers/s390/scsi/zfcp_fsf.c +42 -37
234 lines not on this page · raw message
drivers/s390/scsi/zfcp_qdio.c +52 -43
196 lines not on this page · raw message
PATCH 14/27 zfcp: Move qdio related data out of zfcp_adapter
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
The zfcp_adapter structure was growing over time to a size of almost one memory page. To reduce the size of the data structure and to seperate different layers, put all qdio related data in the new zfcp_qdio data structure.
---
drivers/s390/scsi/zfcp_aux.c | 20 +- drivers/s390/scsi/zfcp_dbf.c | 6 drivers/s390/scsi/zfcp_def.h | 34 +++- drivers/s390/scsi/zfcp_erp.c | 8 - drivers/s390/scsi/zfcp_ext.h | 26 +-- drivers/s390/scsi/zfcp_fsf.c | 299 +++++++++++++++++++++-------------------- drivers/s390/scsi/zfcp_qdio.c | 222 ++++++++++++++++-------------- drivers/s390/scsi/zfcp_scsi.c | 6 drivers/s390/scsi/zfcp_sysfs.c | 16 +- 9 files changed, 342 insertions(+), 295 deletions(-)
drivers/s390/scsi/zfcp_aux.c +14 -6
@@ -428,7 +428,7 @@ static void zfcp_free_low_mem_buffers(stint zfcp_status_read_refill (struct zfcp_adapter *adapter) {while (atomic_read (&adapter->stat_miss) >0 ) -if (zfcp_fsf_status_read (adapter)) { +if (zfcp_fsf_status_read (adapter->qdio)) {if (atomic_read (&adapter->stat_miss) >=16 ) {zfcp_erp_adapter_reopen (adapter,0 ,"axsref1" ,NULL );
@@ -507,11 +507,16 @@ int zfcp_adapter_enqueue(struct ccw_devireturn -ENOMEM ; } + adapter->qdio =kzalloc (sizeof (struct zfcp_qdio ),GFP_KERNEL ); +if (!adapter->qdio) + goto qdio_mem_failed; + + adapter->qdio->adapter = adapter; ccw_device->handler =NULL ; adapter->ccw_device = ccw_device;atomic_set (&adapter->refcount,0 ); -if (zfcp_qdio_allocate (adapter)) +if (zfcp_qdio_allocate (adapter->qdio, ccw_device)) goto qdio_allocate_failed;if (zfcp_allocate_low_mem_buffers (adapter))
@@ -536,8 +541,8 @@ int zfcp_adapter_enqueue(struct ccw_devispin_lock_init (&adapter->req_list_lock); -spin_lock_init (&adapter->req_q_lock); -spin_lock_init (&adapter->qdio_stat_lock); +spin_lock_init (&adapter->qdio->req_q_lock); +spin_lock_init (&adapter->qdio->stat_lock);rwlock_init (&adapter->erp_lock);rwlock_init (&adapter->abort_lock);
@@ -574,7 +579,9 @@ debug_register_failed: failed_low_mem_buffers:zfcp_free_low_mem_buffers (adapter); qdio_allocate_failed: -zfcp_qdio_free (adapter); +zfcp_qdio_free (adapter->qdio); +kfree (adapter->qdio); +qdio_mem_failed:kfree (adapter);return -ENOMEM ; }
@@ -605,12 +612,13 @@ void zfcp_adapter_dequeue(struct zfcp_adzfcp_destroy_adapter_work_queue (adapter);zfcp_adapter_debug_unregister (adapter); -zfcp_qdio_free (adapter); +zfcp_qdio_free (adapter->qdio);zfcp_free_low_mem_buffers (adapter);kfree (adapter->req_list);kfree (adapter->fc_stats);kfree (adapter->stats_reset_data);kfree (adapter->gs); +kfree (adapter->qdio);kfree (adapter); }
drivers/s390/scsi/zfcp_dbf.c +3 -3
@@ -274,16 +274,16 @@ void _zfcp_hba_dbf_event_fsf_unsol(const/** * zfcp_hba_dbf_event_qdio - trace event for QDIO related failure -* @adapter: adapter affected by this QDIO related event +* @qdio: qdio structure affected by this QDIO related event * @qdio_error: as passed by qdio module * @sbal_index: first buffer with error condition, as passed by qdio module * @sbal_count: number of buffers affected, as passed by qdio module */ -void zfcp_hba_dbf_event_qdio (struct zfcp_adapter *adapter, +void zfcp_hba_dbf_event_qdio (struct zfcp_qdio *qdio,unsigned int qdio_error,int sbal_index,int sbal_count) { -struct zfcp_dbf *dbf = adapter->dbf; +struct zfcp_dbf *dbf = qdio->adapter->dbf;struct zfcp_hba_dbf_record *r = &dbf->hba_dbf_buf;unsigned long flags;
drivers/s390/scsi/zfcp_def.h +24 -10
@@ -428,6 +428,29 @@ struct zfcp_latencies {spinlock_t lock; }; +/** struct zfcp_qdio - basic QDIO data structure +* @resp_q: response queue +* @req_q: request queue +* @stat_lock: lock to protect req_q_util and req_q_time +* @req_q_lock; lock to serialize access to request queue +* @req_q_time: time of last fill level change +* @req_q_util: used for accounting +* @req_q_full: queue full incidents +* @req_q_wq: used to wait for SBAL availability +* @adapter: adapter used in conjunction with this QDIO structure +*/ +struct zfcp_qdio { +struct zfcp_qdio_queue resp_q; +struct zfcp_qdio_queue req_q; +spinlock_t stat_lock; +spinlock_t req_q_lock; +ktime_t req_q_time; +u64 req_q_util; +atomic_t req_q_full; +wait_queue_head_t req_q_wq; +struct zfcp_adapter *adapter; +}; +struct zfcp_adapter {atomic_t refcount;/* reference count */ wait_queue_head_t remove_wq;/* can be used to wait for
@@ -436,6 +459,7 @@ struct zfcp_adapter {u64 peer_wwpn;/* P2P peer WWPN */ u32 peer_d_id;/* P2P peer D_ID */ struct ccw_device *ccw_device;/* S/390 ccw device */ +struct zfcp_qdio *qdio;u32 hydra_version;/* Hydra version */ u32 fsf_lic_version;u32 adapter_features;/* FCP channel features */
@@ -447,15 +471,7 @@ struct zfcp_adapter {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 req_q;/* request queue */ -spinlock_t req_q_lock;/* for operations on queue */ -ktime_t req_q_time;/* time of last fill level change */ -u64 req_q_util;/* for accounting */ -spinlock_t qdio_stat_lock;u32 fsf_req_seq_no;/* FSF cmnd seq number */ -wait_queue_head_t request_wq;/* can be used to wait for -more avaliable SBALs */ -struct zfcp_qdio_queue resp_q;/* response queue */ rwlock_t abort_lock;/* Protects against SCSI stack abort/command completion races */
@@ -478,13 +494,11 @@ struct zfcp_adapter {struct zfcp_wka_ports *gs;/* generic services */ struct zfcp_dbf *dbf;/* debug traces */ struct zfcp_adapter_mempool pool;/* Adapter memory pools */ -struct qdio_initialize qdio_init_data;/* for qdio_establish */ struct fc_host_statistics *fc_stats;struct fsf_qtcb_bottom_port *stats_reset_data;unsigned long stats_reset;struct work_struct scan_work;struct service_level service_level; -atomic_t qdio_outb_full;/* queue full incidents */ struct workqueue_struct *work_queue; };
drivers/s390/scsi/zfcp_erp.c +5 -3
@@ -603,9 +603,11 @@ static void zfcp_erp_wakeup(struct zfcp_static int zfcp_erp_adapter_strategy_open_qdio (struct zfcp_erp_action *act) { -if (zfcp_qdio_open (act->adapter)) +struct zfcp_qdio *qdio = act->adapter->qdio; + +if (zfcp_qdio_open (qdio))return ZFCP_ERP_FAILED ; -init_waitqueue_head (&act->adapter->request_wq); +init_waitqueue_head (&qdio->req_q_wq);atomic_set_mask (ZFCP_STATUS_ADAPTER_QDIOUP , &act->adapter->status);return ZFCP_ERP_SUCCEEDED ; }
@@ -710,7 +712,7 @@ static void zfcp_erp_adapter_strategy_clstruct zfcp_adapter *adapter = act->adapter;/* close queues to ensure that buffers are not accessed by adapter */ -zfcp_qdio_close (adapter); +zfcp_qdio_close (adapter->qdio);zfcp_fsf_req_dismiss_all (adapter); adapter->fsf_req_seq_no =0 ;zfcp_fc_wka_ports_force_offline (adapter->gs);
drivers/s390/scsi/zfcp_ext.h +13 -13
@@ -51,7 +51,7 @@ extern void _zfcp_hba_dbf_event_fsf_respextern void _zfcp_hba_dbf_event_fsf_unsol (const char *,int level,struct zfcp_adapter *,struct fsf_status_read_buffer *); -extern void zfcp_hba_dbf_event_qdio (struct zfcp_adapter *,unsigned int ,int , +extern void zfcp_hba_dbf_event_qdio (struct zfcp_qdio *,unsigned int ,int ,int );extern void zfcp_hba_dbf_event_berr (struct zfcp_adapter *,struct zfcp_fsf_req *);
@@ -118,15 +118,15 @@ extern int zfcp_fsf_close_physical_port(extern int zfcp_fsf_open_unit (struct zfcp_erp_action *);extern int zfcp_fsf_close_unit (struct zfcp_erp_action *);extern int zfcp_fsf_exchange_config_data (struct zfcp_erp_action *); -extern int zfcp_fsf_exchange_config_data_sync (struct zfcp_adapter *, +extern int zfcp_fsf_exchange_config_data_sync (struct zfcp_qdio *,struct fsf_qtcb_bottom_config *);extern int zfcp_fsf_exchange_port_data (struct zfcp_erp_action *); -extern int zfcp_fsf_exchange_port_data_sync (struct zfcp_adapter *, +extern int zfcp_fsf_exchange_port_data_sync (struct zfcp_qdio *,struct fsf_qtcb_bottom_port *);extern struct zfcp_fsf_req *zfcp_fsf_control_file (struct zfcp_adapter *,struct zfcp_fsf_cfdc *);extern void zfcp_fsf_req_dismiss_all (struct zfcp_adapter *); -extern int zfcp_fsf_status_read (struct zfcp_adapter *); +extern int zfcp_fsf_status_read (struct zfcp_qdio *);extern int zfcp_status_read_refill (struct zfcp_adapter *adapter);extern int zfcp_fsf_send_ct (struct zfcp_send_ct *,mempool_t *,struct zfcp_erp_action *);
@@ -137,21 +137,21 @@ extern void zfcp_fsf_req_free(struct zfcextern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm (struct zfcp_unit *,u8 );extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command (unsigned long ,struct zfcp_unit *); -extern void zfcp_fsf_reqid_check (struct zfcp_adapter *,int ); +extern void zfcp_fsf_reqid_check (struct zfcp_qdio *,int );/* zfcp_qdio.c */ -extern int zfcp_qdio_allocate (struct zfcp_adapter *); -extern void zfcp_qdio_free (struct zfcp_adapter *); -extern int zfcp_qdio_send (struct zfcp_adapter *,struct zfcp_queue_req *); +extern int zfcp_qdio_allocate (struct zfcp_qdio *,struct ccw_device *); +extern void zfcp_qdio_free (struct zfcp_qdio *); +extern int zfcp_qdio_send (struct zfcp_qdio *,struct zfcp_queue_req *);extern struct qdio_buffer_element - *zfcp_qdio_sbale_req (struct zfcp_adapter *,struct zfcp_queue_req *); + *zfcp_qdio_sbale_req (struct zfcp_qdio *,struct zfcp_queue_req *);extern struct qdio_buffer_element - *zfcp_qdio_sbale_curr (struct zfcp_adapter *,struct zfcp_queue_req *); -extern int zfcp_qdio_sbals_from_sg (struct zfcp_adapter *, + *zfcp_qdio_sbale_curr (struct zfcp_qdio *,struct zfcp_queue_req *); +extern int zfcp_qdio_sbals_from_sg (struct zfcp_qdio *,struct zfcp_queue_req *,unsigned long ,struct scatterlist *,int ); -extern int zfcp_qdio_open (struct zfcp_adapter *); -extern void zfcp_qdio_close (struct zfcp_adapter *); +extern int zfcp_qdio_open (struct zfcp_qdio *); +extern void zfcp_qdio_close (struct zfcp_qdio *);/* zfcp_scsi.c */ extern struct zfcp_data zfcp_data;
drivers/s390/scsi/zfcp_fsf.c +154 -145
830 lines not on this page · raw message
drivers/s390/scsi/zfcp_qdio.c +118 -104
470 lines not on this page · raw message
drivers/s390/scsi/zfcp_scsi.c +3 -3
@@ -225,7 +225,7 @@ static int zfcp_task_mgmt_function(struc {struct zfcp_unit *unit = scpnt->device->hostdata;struct zfcp_adapter *adapter = unit->port->adapter; -struct zfcp_fsf_req *fsf_req; +struct zfcp_fsf_req *fsf_req =NULL ;int retval =SUCCESS ;int retry =3 ;
@@ -429,7 +429,7 @@ static struct fc_host_statistics *zfcp_gif (!data)return NULL ; - ret =zfcp_fsf_exchange_port_data_sync (adapter, data); + ret =zfcp_fsf_exchange_port_data_sync (adapter->qdio, data);if (ret) {kfree (data);return NULL ;
@@ -458,7 +458,7 @@ static void zfcp_reset_fc_host_stats(strif (!data)return ; - ret =zfcp_fsf_exchange_port_data_sync (adapter, data); + ret =zfcp_fsf_exchange_port_data_sync (adapter->qdio, data);if (ret)kfree (data);else {
drivers/s390/scsi/zfcp_sysfs.c +8 -8
@@ -425,7 +425,7 @@ static ssize_t zfcp_sysfs_adapter_util_sif (!qtcb_port)return -ENOMEM ; - retval =zfcp_fsf_exchange_port_data_sync (adapter, qtcb_port); + retval =zfcp_fsf_exchange_port_data_sync (adapter->qdio, qtcb_port);if (!retval) retval =sprintf (buf,"%u %u %u\n" , qtcb_port->cp_util, qtcb_port->cb_util, qtcb_port->a_util);
@@ -451,7 +451,7 @@ static int zfcp_sysfs_adapter_ex_config(if (!qtcb_config)return -ENOMEM ; - retval =zfcp_fsf_exchange_config_data_sync (adapter, qtcb_config); + retval =zfcp_fsf_exchange_config_data_sync (adapter->qdio, qtcb_config);if (!retval) *stat_inf = qtcb_config->stat_info;
@@ -492,15 +492,15 @@ static ssize_t zfcp_sysfs_adapter_q_full char *buf) {struct Scsi_Host *scsi_host =class_to_shost (dev); -struct zfcp_adapter *adapter = - (struct zfcp_adapter *) scsi_host->hostdata[0 ]; +struct zfcp_qdio *qdio = + ((struct zfcp_adapter *) scsi_host->hostdata[0 ])->qdio;u64 util; -spin_lock_bh (&adapter->qdio_stat_lock); - util = adapter->req_q_util; -spin_unlock_bh (&adapter->qdio_stat_lock); +spin_lock_bh (&qdio->stat_lock); + util = qdio->req_q_util; +spin_unlock_bh (&qdio->stat_lock); -return sprintf (buf,"%d %llu\n" ,atomic_read (&adapter->qdio_outb_full), +return sprintf (buf,"%d %llu\n" ,atomic_read (&qdio->req_q_full), (unsigned long long )util); } static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);
PATCH 15/27 zfcp: Decouple gid_pn requests from erp
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Don't let the erp wait for gid_pn requests to complete. Instead, queue the gid_pn work, exit erp and let the finished gid_pn work trigger a new port reopen.
drivers/s390/scsi/zfcp_aux.c +7 -2
@@ -362,6 +362,11 @@ static int zfcp_allocate_low_mem_buffersif (!adapter->pool.erp_req)return -ENOMEM ; + adapter->pool.gid_pn_req = +mempool_create_kmalloc_pool (1 ,sizeof (struct zfcp_fsf_req )); +if (!adapter->pool.gid_pn_req) +return -ENOMEM ; + adapter->pool.scsi_req =mempool_create_kmalloc_pool (1 ,sizeof (struct zfcp_fsf_req ));if (!adapter->pool.scsi_req)
@@ -379,7 +384,7 @@ static int zfcp_allocate_low_mem_buffersreturn -ENOMEM ; adapter->pool.qtcb_pool = -mempool_create_slab_pool (3 , zfcp_data.qtcb_cache); +mempool_create_slab_pool (4 , zfcp_data.qtcb_cache);if (!adapter->pool.qtcb_pool)return -ENOMEM ;
@@ -652,7 +657,7 @@ struct zfcp_port *zfcp_port_enqueue(struinit_waitqueue_head (&port->remove_wq);INIT_LIST_HEAD (&port->unit_list_head); -INIT_WORK (&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup); +INIT_WORK (&port->gid_pn_work, zfcp_fc_port_did_lookup);INIT_WORK (&port->test_link_work, zfcp_fc_link_test_work);INIT_WORK (&port->rport_work, zfcp_scsi_rport_work);
drivers/s390/scsi/zfcp_def.h +1 -0
@@ -265,6 +265,7 @@ struct zfcp_fsf_req;/* holds various memory pools of an adapter */ struct zfcp_adapter_mempool {mempool_t *erp_req; +mempool_t *gid_pn_req;mempool_t *scsi_req;mempool_t *scsi_abort;mempool_t *status_read_req;
drivers/s390/scsi/zfcp_erp.c +1 -27
@@ -26,7 +26,6 @@ enum zfcp_erp_steps {ZFCP_ERP_STEP_FSF_XCONFIG =0x0001 ,ZFCP_ERP_STEP_PHYS_PORT_CLOSING =0x0010 ,ZFCP_ERP_STEP_PORT_CLOSING =0x0100 , -ZFCP_ERP_STEP_NAMESERVER_LOOKUP =0x0400 ,ZFCP_ERP_STEP_PORT_OPENING =0x0800 ,ZFCP_ERP_STEP_UNIT_CLOSING =0x1000 , ZFCP_ERP_STEP_UNIT_OPENING = 0x2000,
@@ -842,27 +841,6 @@ static int zfcp_erp_open_ptp_port(structreturn zfcp_erp_port_strategy_open_port (act); } -void zfcp_erp_port_strategy_open_lookup (struct work_struct *work) -{ -int retval; - struct zfcp_port *port = container_of(work, struct zfcp_port, - gid_pn_work); - - retval =zfcp_fc_ns_gid_pn (&port->erp_action); -if (!retval) { - port->erp_action.step =ZFCP_ERP_STEP_NAMESERVER_LOOKUP ; - goto out; - } -if (retval == -ENOMEM ) { -zfcp_erp_notify (&port->erp_action,ZFCP_STATUS_ERP_LOWMEM ); - goto out; - } -/* all other error condtions */ -zfcp_erp_notify (&port->erp_action,0 ); -out: -zfcp_port_put (port); -} -static int zfcp_erp_port_strategy_open_common (struct zfcp_erp_action *act) {struct zfcp_adapter *adapter = act->adapter;
@@ -880,12 +858,8 @@ static int zfcp_erp_port_strategy_open_cif (!queue_work (adapter->work_queue, &port->gid_pn_work))zfcp_port_put (port); -return ZFCP_ERP_CONTINUES ; +return ZFCP_ERP_EXIT ; } -/* fall through */ -case ZFCP_ERP_STEP_NAMESERVER_LOOKUP : -if (!port->d_id) -return ZFCP_ERP_FAILED ;return zfcp_erp_port_strategy_open_port (act);case ZFCP_ERP_STEP_PORT_OPENING :
drivers/s390/scsi/zfcp_ext.h +2 -4
@@ -94,13 +94,12 @@ extern void zfcp_erp_unit_access_denied(extern void zfcp_erp_adapter_access_changed (struct zfcp_adapter *,char *,void *);extern void zfcp_erp_timeout_handler (unsigned long ); -extern void zfcp_erp_port_strategy_open_lookup (struct work_struct *);/* zfcp_fc.c */ extern int zfcp_scan_ports (struct zfcp_adapter *);extern void _zfcp_scan_ports_later (struct work_struct *);extern void zfcp_fc_incoming_els (struct zfcp_fsf_req *); -extern int zfcp_fc_ns_gid_pn (struct zfcp_erp_action *); +extern void zfcp_fc_port_did_lookup (struct work_struct *);extern void zfcp_fc_plogi_evaluate (struct zfcp_port *,struct fsf_plogi *);extern void zfcp_test_link (struct zfcp_port *);extern void zfcp_fc_link_test_work (struct work_struct *);
@@ -128,8 +127,7 @@ extern struct zfcp_fsf_req *zfcp_fsf_conextern void zfcp_fsf_req_dismiss_all (struct zfcp_adapter *);extern int zfcp_fsf_status_read (struct zfcp_qdio *);extern int zfcp_status_read_refill (struct zfcp_adapter *adapter); -extern int zfcp_fsf_send_ct (struct zfcp_send_ct *,mempool_t *, -struct zfcp_erp_action *); +extern int zfcp_fsf_send_ct (struct zfcp_send_ct *,mempool_t *);extern int zfcp_fsf_send_els (struct zfcp_send_els *);extern int zfcp_fsf_send_fcp_command_task (struct zfcp_unit *,struct scsi_cmnd *);
drivers/s390/scsi/zfcp_fc.c +34 -11
102 lines not on this page · raw message
drivers/s390/scsi/zfcp_fsf.c +2 -12
@@ -1069,10 +1069,8 @@ static int zfcp_fsf_setup_ct_els_sbals(s* zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS) * @ct: pointer to struct zfcp_send_ct with data for request * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req -* @erp_action: if non-null the Generic Service request sent within ERP */ -int zfcp_fsf_send_ct (struct zfcp_send_ct *ct,mempool_t *pool, -struct zfcp_erp_action *erp_action) +int zfcp_fsf_send_ct (struct zfcp_send_ct *ct,mempool_t *pool) {struct zfcp_wka_port *wka_port = ct->wka_port;struct zfcp_qdio *qdio = wka_port->adapter->qdio;
@@ -1103,13 +1101,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct req->data = ct;zfcp_san_dbf_event_ct_request (req); - -if (erp_action) { - erp_action->fsf_req = req; - req->erp_action = erp_action; -zfcp_fsf_start_erp_timer (req); - }else -zfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT ); +zfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT ); ret =zfcp_fsf_req_send (req);if (ret)
@@ -1119,8 +1111,6 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct failed_send:zfcp_fsf_req_free (req); -if (erp_action) - erp_action->fsf_req =NULL ; out:spin_unlock_bh (&qdio->req_q_lock);return ret;
PATCH 16/27 zfcp: Update dbf calls
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
Change the dbf data and functions to use the zfcp_dbf prefix throughout the code. Also change the calls to dbf to use zfcp_dbf instead of zfcp_adapter.
---
drivers/s390/scsi/zfcp_aux.c | 7 drivers/s390/scsi/zfcp_dbf.c | 408 +++++++++++++++++++----------------------- drivers/s390/scsi/zfcp_dbf.h | 152 +++++++-------- drivers/s390/scsi/zfcp_erp.c | 49 ++--- drivers/s390/scsi/zfcp_ext.h | 52 ++--- drivers/s390/scsi/zfcp_fc.c | 2 drivers/s390/scsi/zfcp_fsf.c | 24 +- drivers/s390/scsi/zfcp_qdio.c | 6 drivers/s390/scsi/zfcp_scsi.c | 27 +- 9 files changed, 347 insertions(+), 380 deletions(-)
drivers/s390/scsi/zfcp_aux.c +4 -3
@@ -517,6 +517,7 @@ int zfcp_adapter_enqueue(struct ccw_devi goto qdio_mem_failed; adapter->qdio->adapter = adapter; + ccw_device->handler =NULL ; adapter->ccw_device = ccw_device;atomic_set (&adapter->refcount,0 );
@@ -530,7 +531,7 @@ int zfcp_adapter_enqueue(struct ccw_deviif (zfcp_reqlist_alloc (adapter)) goto failed_low_mem_buffers; -if (zfcp_adapter_debug_register (adapter)) +if (zfcp_dbf_adapter_register (adapter)) goto debug_register_failed;if (zfcp_setup_adapter_work_queue (adapter))
@@ -577,7 +578,7 @@ int zfcp_adapter_enqueue(struct ccw_devi sysfs_failed:zfcp_destroy_adapter_work_queue (adapter); work_queue_failed: -zfcp_adapter_debug_unregister (adapter); +zfcp_dbf_adapter_unregister (adapter->dbf); debug_register_failed:dev_set_drvdata (&ccw_device->dev,NULL );kfree (adapter->req_list);
@@ -616,7 +617,7 @@ void zfcp_adapter_dequeue(struct zfcp_adreturn ;zfcp_destroy_adapter_work_queue (adapter); -zfcp_adapter_debug_unregister (adapter); +zfcp_dbf_adapter_unregister (adapter->dbf);zfcp_qdio_free (adapter->qdio);zfcp_free_low_mem_buffers (adapter);kfree (adapter->req_list);
drivers/s390/scsi/zfcp_dbf.c +192 -216
833 lines not on this page · raw message
drivers/s390/scsi/zfcp_dbf.h +73 -79
316 lines not on this page · raw message
drivers/s390/scsi/zfcp_erp.c +24 -25
157 lines not on this page · raw message
drivers/s390/scsi/zfcp_ext.h +24 -28
59 lines not on this page · raw message
drivers/s390/scsi/zfcp_fc.c +1 -1
@@ -242,7 +242,7 @@ void zfcp_fc_incoming_els(struct zfcp_fs (struct fsf_status_read_buffer *) fsf_req->data;unsigned int els_type = status_buffer->payload.data[0 ]; -zfcp_san_dbf_event_incoming_els (fsf_req); +zfcp_dbf_san_incoming_els (fsf_req);if (els_type ==LS_PLOGI )zfcp_fc_incoming_plogi (fsf_req);else if (els_type ==LS_LOGO )
drivers/s390/scsi/zfcp_fsf.c +12 -12
@@ -248,13 +248,13 @@ static void zfcp_fsf_status_read_handlerstruct fsf_status_read_buffer *sr_buf = req->data;if (req->status &ZFCP_STATUS_FSFREQ_DISMISSED ) { -zfcp_hba_dbf_event_fsf_unsol ("dism" , adapter, sr_buf); +zfcp_dbf_hba_fsf_unsol ("dism" , adapter->dbf, sr_buf);mempool_free (sr_buf, adapter->pool.status_read_data);zfcp_fsf_req_free (req);return ; } -zfcp_hba_dbf_event_fsf_unsol ("read" , adapter, sr_buf); +zfcp_dbf_hba_fsf_unsol ("read" , adapter->dbf, sr_buf);switch (sr_buf->status_type) {case FSF_STATUS_READ_PORT_CLOSED :
@@ -269,7 +269,7 @@ static void zfcp_fsf_status_read_handlerdev_warn (&adapter->ccw_device->dev,"The error threshold for checksum statistics " "has been exceeded\n" ); -zfcp_hba_dbf_event_berr (adapter, req); +zfcp_dbf_hba_berr (adapter->dbf, req);break ;case FSF_STATUS_READ_LINK_DOWN :zfcp_fsf_status_read_link_down (req);
@@ -355,7 +355,7 @@ static void zfcp_fsf_protstatus_eval(strstruct fsf_qtcb *qtcb = req->qtcb;union fsf_prot_status_qual *psq = &qtcb->prefix.prot_status_qual; -zfcp_hba_dbf_event_fsf_response (req); +zfcp_dbf_hba_fsf_response (req);if (req->status &ZFCP_STATUS_FSFREQ_DISMISSED ) { req->status |= ZFCP_STATUS_FSFREQ_ERROR |
@@ -848,7 +848,7 @@ failed_req_send:mempool_free (sr_buf, adapter->pool.status_read_data); failed_buf:zfcp_fsf_req_free (req); -zfcp_hba_dbf_event_fsf_unsol ("fail" , adapter,NULL ); +zfcp_dbf_hba_fsf_unsol ("fail" , adapter->dbf,NULL ); out:spin_unlock_bh (&qdio->req_q_lock);return retval;
@@ -968,7 +968,7 @@ static void zfcp_fsf_send_ct_handler(strswitch (header->fsf_status) {case FSF_GOOD : -zfcp_san_dbf_event_ct_response (req); +zfcp_dbf_san_ct_response (req); send_ct->status =0 ;break ;case FSF_SERVICE_CLASS_NOT_SUPPORTED :
@@ -1100,7 +1100,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct req->qtcb->bottom.support.timeout = ct->timeout; req->data = ct; -zfcp_san_dbf_event_ct_request (req); +zfcp_dbf_san_ct_request (req);zfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT ); ret =zfcp_fsf_req_send (req);
@@ -1129,7 +1129,7 @@ static void zfcp_fsf_send_els_handler(stswitch (header->fsf_status) {case FSF_GOOD : -zfcp_san_dbf_event_els_response (req); +zfcp_dbf_san_els_response (req); send_els->status =0 ;break ;case FSF_SERVICE_CLASS_NOT_SUPPORTED :
@@ -1203,7 +1203,7 @@ int zfcp_fsf_send_els(struct zfcp_send_e bottom->timeout =2 *R_A_TOV ; req->data = els; -zfcp_san_dbf_event_els_request (req); +zfcp_dbf_san_els_request (req);zfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT ); ret =zfcp_fsf_req_send (req);
@@ -2213,11 +2213,11 @@ static void zfcp_fsf_send_fcp_command_ta } skip_fsfstatus:if (scpnt->result !=0 ) -zfcp_scsi_dbf_event_result ("erro" ,3 , req->adapter, scpnt, req); +zfcp_dbf_scsi_result ("erro" ,3 , req->adapter->dbf, scpnt, req);else if (scpnt->retries >0 ) -zfcp_scsi_dbf_event_result ("retr" ,4 , req->adapter, scpnt, req); +zfcp_dbf_scsi_result ("retr" ,4 , req->adapter->dbf, scpnt, req);else -zfcp_scsi_dbf_event_result ("norm" ,6 , req->adapter, scpnt, req); +zfcp_dbf_scsi_result ("norm" ,6 , req->adapter->dbf, scpnt, req); scpnt->host_scribble =NULL ; (scpnt->scsi_done) (scpnt);
drivers/s390/scsi/zfcp_qdio.c +4 -2
@@ -101,7 +101,8 @@ static void zfcp_qdio_int_req(struct ccwstruct zfcp_qdio_queue *queue = &qdio->req_q;if (unlikely (qdio_err)) { -zfcp_hba_dbf_event_qdio (qdio, qdio_err, first, count); +zfcp_dbf_hba_qdio (qdio->adapter->dbf, qdio_err, first, + count);zfcp_qdio_handler_error (qdio,"qdireq1" );return ; }
@@ -143,7 +144,8 @@ static void zfcp_qdio_int_resp(struct ccint sbal_idx, sbal_no;if (unlikely (qdio_err)) { -zfcp_hba_dbf_event_qdio (qdio, qdio_err, first, count); +zfcp_dbf_hba_qdio (qdio->adapter->dbf, qdio_err, first, + count);zfcp_qdio_handler_error (qdio,"qdires1" );return ; }
drivers/s390/scsi/zfcp_scsi.c +13 -14
@@ -53,11 +53,11 @@ static int zfcp_scsi_slave_configure(strstatic void zfcp_scsi_command_fail (struct scsi_cmnd *scpnt,int result) { +struct zfcp_adapter *adapter = + (struct zfcp_adapter *) scpnt->device->host->hostdata[0 ];set_host_byte (scpnt, result);if ((scpnt->device !=NULL ) && (scpnt->device->host !=NULL )) -zfcp_scsi_dbf_event_result ("fail" ,4 , - (struct zfcp_adapter *) scpnt->device->host->hostdata[0 ], - scpnt,NULL ); +zfcp_dbf_scsi_result ("fail" ,4 , adapter->dbf, scpnt,NULL );/* return directly */ scpnt->scsi_done (scpnt); }
@@ -93,7 +93,7 @@ static int zfcp_scsi_queuecommand(struct scsi_result =fc_remote_port_chkready (rport);if (unlikely (scsi_result)) { scpnt->result = scsi_result; -zfcp_scsi_dbf_event_result ("fail" ,4 , adapter, scpnt,NULL ); +zfcp_dbf_scsi_result ("fail" ,4 , adapter->dbf, scpnt,NULL ); scpnt->scsi_done (scpnt);return 0 ; }
@@ -181,8 +181,8 @@ static int zfcp_scsi_eh_abort_handler(stspin_unlock (&adapter->req_list_lock);if (!old_req) {write_unlock_irqrestore (&adapter->abort_lock, flags); -zfcp_scsi_dbf_event_abort ("lte1" , adapter, scpnt,NULL , - old_reqid); +zfcp_dbf_scsi_abort ("lte1" , adapter->dbf, scpnt,NULL , + old_reqid);return FAILED ;/* completion could be in progress */ } old_req->data =NULL ;
@@ -198,8 +198,8 @@ static int zfcp_scsi_eh_abort_handler(stzfcp_erp_wait (adapter);if (!(atomic_read (&adapter->status) &ZFCP_STATUS_COMMON_RUNNING )) { -zfcp_scsi_dbf_event_abort ("nres" , adapter, scpnt,NULL , - old_reqid); +zfcp_dbf_scsi_abort ("nres" , adapter->dbf, scpnt,NULL , + old_reqid);return SUCCESS ; } }
@@ -216,7 +216,7 @@ static int zfcp_scsi_eh_abort_handler(st dbf_tag ="fail" ; retval =FAILED ; } -zfcp_scsi_dbf_event_abort (dbf_tag, adapter, scpnt, abrt_req, old_reqid); +zfcp_dbf_scsi_abort (dbf_tag, adapter->dbf, scpnt, abrt_req, old_reqid);zfcp_fsf_req_free (abrt_req);return retval; }
@@ -237,8 +237,7 @@ static int zfcp_task_mgmt_function(struczfcp_erp_wait (adapter);if (!(atomic_read (&adapter->status) &ZFCP_STATUS_COMMON_RUNNING )) { -zfcp_scsi_dbf_event_devreset ("nres" , tm_flags, unit, - scpnt); +zfcp_dbf_scsi_devreset ("nres" , tm_flags, unit, scpnt);return SUCCESS ; } }
@@ -248,13 +247,13 @@ static int zfcp_task_mgmt_function(strucwait_for_completion (&fsf_req->completion);if (fsf_req->status &ZFCP_STATUS_FSFREQ_TMFUNCFAILED ) { -zfcp_scsi_dbf_event_devreset ("fail" , tm_flags, unit, scpnt); +zfcp_dbf_scsi_devreset ("fail" , tm_flags, unit, scpnt); retval =FAILED ; }else if (fsf_req->status &ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP ) { -zfcp_scsi_dbf_event_devreset ("nsup" , tm_flags, unit, scpnt); +zfcp_dbf_scsi_devreset ("nsup" , tm_flags, unit, scpnt); retval =FAILED ; }else -zfcp_scsi_dbf_event_devreset ("okay" , tm_flags, unit, scpnt); +zfcp_dbf_scsi_devreset ("okay" , tm_flags, unit, scpnt);zfcp_fsf_req_free (fsf_req);return retval;
PATCH 17/27 zfcp: introduce _setup, _destroy for qdio and FC
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
Extract independent data structures and introduce common _setup and _destroy routines for QDIO and Fibre Channel related data structures
---
drivers/s390/scsi/zfcp_aux.c | 42 ++++++++----------------- drivers/s390/scsi/zfcp_ext.h | 7 ++-- drivers/s390/scsi/zfcp_fc.c | 36 +++++++++++++++------- drivers/s390/scsi/zfcp_qdio.c | 68 ++++++++++++++++++++++++++++-------------- 4 files changed, 89 insertions(+), 64 deletions(-)
drivers/s390/scsi/zfcp_aux.c +14 -28
@@ -506,30 +506,18 @@ int zfcp_adapter_enqueue(struct ccw_deviif (!adapter)return -ENOMEM ; - adapter->gs =kzalloc (sizeof (struct zfcp_wka_ports ),GFP_KERNEL ); -if (!adapter->gs) { -kfree (adapter); -return -ENOMEM ; - } - - adapter->qdio =kzalloc (sizeof (struct zfcp_qdio ),GFP_KERNEL ); -if (!adapter->qdio) - goto qdio_mem_failed; - - adapter->qdio->adapter = adapter; - ccw_device->handler =NULL ; adapter->ccw_device = ccw_device;atomic_set (&adapter->refcount,0 ); -if (zfcp_qdio_allocate (adapter->qdio, ccw_device)) - goto qdio_allocate_failed; +if (zfcp_qdio_setup (adapter)) + goto qdio_failed;if (zfcp_allocate_low_mem_buffers (adapter)) - goto failed_low_mem_buffers; + goto low_mem_buffers_failed;if (zfcp_reqlist_alloc (adapter)) - goto failed_low_mem_buffers; + goto low_mem_buffers_failed;if (zfcp_dbf_adapter_register (adapter)) goto debug_register_failed;
@@ -537,6 +525,9 @@ int zfcp_adapter_enqueue(struct ccw_deviif (zfcp_setup_adapter_work_queue (adapter)) goto work_queue_failed; +if (zfcp_fc_gs_setup (adapter)) + goto generic_services_failed; +init_waitqueue_head (&adapter->remove_wq);init_waitqueue_head (&adapter->erp_thread_wqh);init_waitqueue_head (&adapter->erp_done_wqh);
@@ -547,9 +538,6 @@ int zfcp_adapter_enqueue(struct ccw_devispin_lock_init (&adapter->req_list_lock); -spin_lock_init (&adapter->qdio->req_q_lock); -spin_lock_init (&adapter->qdio->stat_lock); -rwlock_init (&adapter->erp_lock);rwlock_init (&adapter->abort_lock);
@@ -570,24 +558,23 @@ int zfcp_adapter_enqueue(struct ccw_devi goto sysfs_failed;atomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , &adapter->status); -zfcp_fc_wka_ports_init (adapter);if (!zfcp_adapter_scsi_register (adapter))return 0 ; sysfs_failed: +zfcp_fc_gs_destroy (adapter); +generic_services_failed:zfcp_destroy_adapter_work_queue (adapter); work_queue_failed:zfcp_dbf_adapter_unregister (adapter->dbf); debug_register_failed:dev_set_drvdata (&ccw_device->dev,NULL );kfree (adapter->req_list); -failed_low_mem_buffers: +low_mem_buffers_failed:zfcp_free_low_mem_buffers (adapter); -qdio_allocate_failed: -zfcp_qdio_free (adapter->qdio); -kfree (adapter->qdio); -qdio_mem_failed: +qdio_failed: +zfcp_qdio_destroy (adapter->qdio);kfree (adapter);return -ENOMEM ; }
@@ -616,15 +603,14 @@ void zfcp_adapter_dequeue(struct zfcp_adif (!retval)return ; +zfcp_fc_gs_destroy (adapter);zfcp_destroy_adapter_work_queue (adapter);zfcp_dbf_adapter_unregister (adapter->dbf); -zfcp_qdio_free (adapter->qdio);zfcp_free_low_mem_buffers (adapter); +zfcp_qdio_destroy (adapter->qdio);kfree (adapter->req_list);kfree (adapter->fc_stats);kfree (adapter->stats_reset_data); -kfree (adapter->gs); -kfree (adapter->qdio);kfree (adapter); }
drivers/s390/scsi/zfcp_ext.h +4 -3
@@ -100,7 +100,8 @@ extern void zfcp_fc_plogi_evaluate(strucextern void zfcp_test_link (struct zfcp_port *);extern void zfcp_fc_link_test_work (struct work_struct *);extern void zfcp_fc_wka_ports_force_offline (struct zfcp_wka_ports *); -extern void zfcp_fc_wka_ports_init (struct zfcp_adapter *); +extern int zfcp_fc_gs_setup (struct zfcp_adapter *); +extern void zfcp_fc_gs_destroy (struct zfcp_adapter *);extern int zfcp_fc_execute_els_fc_job (struct fc_bsg_job *);extern int zfcp_fc_execute_ct_fc_job (struct fc_bsg_job *);
@@ -134,8 +135,8 @@ extern struct zfcp_fsf_req *zfcp_fsf_aboextern void zfcp_fsf_reqid_check (struct zfcp_qdio *,int );/* zfcp_qdio.c */ -extern int zfcp_qdio_allocate (struct zfcp_qdio *,struct ccw_device *); -extern void zfcp_qdio_free (struct zfcp_qdio *); +extern int zfcp_qdio_setup (struct zfcp_adapter *); +extern void zfcp_qdio_destroy (struct zfcp_qdio *);extern int zfcp_qdio_send (struct zfcp_qdio *,struct zfcp_queue_req *);extern struct qdio_buffer_element *zfcp_qdio_sbale_req (struct zfcp_qdio *,struct zfcp_queue_req *);
drivers/s390/scsi/zfcp_fc.c +25 -11
@@ -141,17 +141,6 @@ void zfcp_fc_wka_ports_force_offline(strzfcp_fc_wka_port_force_offline (&gs->ks); } -void zfcp_fc_wka_ports_init (struct zfcp_adapter *adapter) -{ -struct zfcp_wka_ports *gs = adapter->gs; - -zfcp_fc_wka_port_init (&gs->ms,FC_FID_MGMT_SERV , adapter); -zfcp_fc_wka_port_init (&gs->ts,FC_FID_TIME_SERV , adapter); -zfcp_fc_wka_port_init (&gs->ds,FC_FID_DIR_SERV , adapter); -zfcp_fc_wka_port_init (&gs->as,FC_FID_ALIASES , adapter); -zfcp_fc_wka_port_init (&gs->ks,FC_FID_SEC_KEY , adapter); -} -static void _zfcp_fc_incoming_rscn (struct zfcp_fsf_req *fsf_req,u32 range,struct fcp_rscn_element *elem) {
@@ -870,3 +859,28 @@ int zfcp_fc_execute_ct_fc_job(struct fc_ }return ret; } + +int zfcp_fc_gs_setup (struct zfcp_adapter *adapter) +{ +struct zfcp_wka_ports *wka_ports; + + wka_ports =kzalloc (sizeof (struct zfcp_wka_ports ),GFP_KERNEL ); +if (!wka_ports) +return -ENOMEM ; + + adapter->gs = wka_ports; +zfcp_fc_wka_port_init (&wka_ports->ms,FC_FID_MGMT_SERV , adapter); +zfcp_fc_wka_port_init (&wka_ports->ts,FC_FID_TIME_SERV , adapter); +zfcp_fc_wka_port_init (&wka_ports->ds,FC_FID_DIR_SERV , adapter); +zfcp_fc_wka_port_init (&wka_ports->as,FC_FID_ALIASES , adapter); +zfcp_fc_wka_port_init (&wka_ports->ks,FC_FID_SEC_KEY , adapter); + +return 0 ; +} + +void zfcp_fc_gs_destroy (struct zfcp_adapter *adapter) +{ +kfree (adapter->gs); + adapter->gs =NULL ; +} +
drivers/s390/scsi/zfcp_qdio.c +46 -22
83 lines not on this page · raw message
PATCH 18/27 zfcp: Apply common naming conventions to zfcp_fc
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
Update the Fibre Channel related code to use the zfcp_fc prefix.
---
drivers/s390/scsi/zfcp_aux.c | 2 - drivers/s390/scsi/zfcp_ext.h | 6 ++-- drivers/s390/scsi/zfcp_fc.c | 51 ++++++++++++++++++++--------------------- drivers/s390/scsi/zfcp_fsf.c | 10 ++++---- drivers/s390/scsi/zfcp_sysfs.c | 2 - 5 files changed, 35 insertions(+), 36 deletions(-)
drivers/s390/scsi/zfcp_aux.c +1 -1
@@ -544,7 +544,7 @@ int zfcp_adapter_enqueue(struct ccw_devisema_init (&adapter->erp_ready_sem,0 );INIT_WORK (&adapter->stat_work, _zfcp_status_read_scheduler); -INIT_WORK (&adapter->scan_work, _zfcp_scan_ports_later); +INIT_WORK (&adapter->scan_work, _zfcp_fc_scan_ports_later); adapter->service_level.seq_print = zfcp_print_sl;
drivers/s390/scsi/zfcp_ext.h +3 -3
@@ -92,12 +92,12 @@ extern void zfcp_erp_adapter_access_chanextern void zfcp_erp_timeout_handler (unsigned long );/* zfcp_fc.c */ -extern int zfcp_scan_ports (struct zfcp_adapter *); -extern void _zfcp_scan_ports_later (struct work_struct *); +extern int zfcp_fc_scan_ports (struct zfcp_adapter *); +extern void _zfcp_fc_scan_ports_later (struct work_struct *);extern void zfcp_fc_incoming_els (struct zfcp_fsf_req *);extern void zfcp_fc_port_did_lookup (struct work_struct *);extern void zfcp_fc_plogi_evaluate (struct zfcp_port *,struct fsf_plogi *); -extern void zfcp_test_link (struct zfcp_port *); +extern void zfcp_fc_test_link (struct zfcp_port *);extern void zfcp_fc_link_test_work (struct work_struct *);extern void zfcp_fc_wka_ports_force_offline (struct zfcp_wka_ports *);extern int zfcp_fc_gs_setup (struct zfcp_adapter *);
drivers/s390/scsi/zfcp_fc.c +25 -26
177 lines not on this page · raw message
drivers/s390/scsi/zfcp_fsf.c +5 -5
@@ -892,7 +892,7 @@ static void zfcp_fsf_abort_fcp_command_hcase FSF_ADAPTER_STATUS_AVAILABLE :switch (fsq->word[0 ]) {case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE : -zfcp_test_link (unit->port); +zfcp_fc_test_link (unit->port);/* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED : req->status |=ZFCP_STATUS_FSFREQ_ERROR ;
@@ -1139,7 +1139,7 @@ static void zfcp_fsf_send_els_handler(stswitch (header->fsf_status_qual.word[0 ]){case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE :if (port && (send_els->ls_code !=ZFCP_LS_ADISC )) -zfcp_test_link (port); +zfcp_fc_test_link (port);/*fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED :case FSF_SQ_RETRY_IF_POSSIBLE :
@@ -1889,7 +1889,7 @@ static void zfcp_fsf_open_unit_handler(scase FSF_ADAPTER_STATUS_AVAILABLE :switch (header->fsf_status_qual.word[0 ]) {case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE : -zfcp_test_link (unit->port); +zfcp_fc_test_link (unit->port);/* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED : req->status |=ZFCP_STATUS_FSFREQ_ERROR ;
@@ -2024,7 +2024,7 @@ static void zfcp_fsf_close_unit_handler(case FSF_ADAPTER_STATUS_AVAILABLE :switch (req->qtcb->header.fsf_status_qual.word[0 ]) {case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE : -zfcp_test_link (unit->port); +zfcp_fc_test_link (unit->port);/* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED : req->status |=ZFCP_STATUS_FSFREQ_ERROR ;
@@ -2307,7 +2307,7 @@ static void zfcp_fsf_send_fcp_command_hacase FSF_ADAPTER_STATUS_AVAILABLE :if (header->fsf_status_qual.word[0 ] ==FSF_SQ_INVOKE_LINK_TEST_PROCEDURE ) -zfcp_test_link (unit->port); +zfcp_fc_test_link (unit->port); req->status |=ZFCP_STATUS_FSFREQ_ERROR ;break ; }
drivers/s390/scsi/zfcp_sysfs.c +1 -1
@@ -126,7 +126,7 @@ static ssize_t zfcp_sysfs_port_rescan_stif (atomic_read (&adapter->status) &ZFCP_STATUS_COMMON_REMOVE )return -EBUSY ; - ret =zfcp_scan_ports (adapter); + ret =zfcp_fc_scan_ports (adapter);return ret ? ret : (ssize_t ) count; } static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
PATCH 19/27 zfcp: resolve false usage of dd_data in fc_rport
In reply to Christof SchmittFrom: Swen Schillig <[email protected]>
The fc_rport structure reserves a reference where a LLD can put information required in a situation where the fc transport class is triggering LLD callbacks. The zfcp driver was using this variable directly which is discouraged. This patch solves this issue by making this reference unnecessary. In addition the dev_loss_tmo callback is removed, it is not required: zfcp does not access the fc_rport after calling fc_remote_port_delete.
---
drivers/s390/scsi/zfcp_aux.c | 4 ---- drivers/s390/scsi/zfcp_fc.c | 2 +- drivers/s390/scsi/zfcp_scsi.c | 22 ++++------------------ 3 files changed, 5 insertions(+), 23 deletions(-)
drivers/s390/scsi/zfcp_aux.c +0 -4
@@ -709,10 +709,6 @@ void zfcp_port_dequeue(struct zfcp_portwrite_lock_irq (&zfcp_data.config_lock);list_del (&port->list);write_unlock_irq (&zfcp_data.config_lock); -if (port->rport) { - port->rport->dd_data =NULL ; - port->rport =NULL ; - }wait_event (port->remove_wq,atomic_read (&port->refcount) ==0 );cancel_work_sync (&port->rport_work);/* usually not necessary */ zfcp_adapter_put (port->adapter);
drivers/s390/scsi/zfcp_fc.c +1 -1
@@ -752,7 +752,7 @@ int zfcp_fc_execute_els_fc_job(struct fc els_fc_job->els.adapter = adapter;if (rport) {read_lock_irq (&zfcp_data.config_lock); - port = rport->dd_data; + port =zfcp_get_port_by_wwpn (adapter, rport->port_name);if (port) els_fc_job->els.d_id = port->d_id;read_unlock_irq (&zfcp_data.config_lock);
drivers/s390/scsi/zfcp_scsi.c +4 -18
@@ -491,21 +491,6 @@ static void zfcp_set_rport_dev_loss_tmo( }/** -* zfcp_scsi_dev_loss_tmo_callbk - Free any reference to rport -* @rport: The rport that is about to be deleted. -*/ -static void zfcp_scsi_dev_loss_tmo_callbk (struct fc_rport *rport) -{ -struct zfcp_port *port; - -write_lock_irq (&zfcp_data.config_lock); - port = rport->dd_data; -if (port) - port->rport =NULL ; -write_unlock_irq (&zfcp_data.config_lock); -} - -/** * zfcp_scsi_terminate_rport_io - Terminate all I/O on a rport * @rport: The FC rport where to teminate I/O *
@@ -516,9 +501,12 @@ static void zfcp_scsi_dev_loss_tmo_callbstatic void zfcp_scsi_terminate_rport_io (struct fc_rport *rport) {struct zfcp_port *port; +struct Scsi_Host *shost =rport_to_shost (rport); +struct zfcp_adapter *adapter = + (struct zfcp_adapter *)shost->hostdata[0 ];write_lock_irq (&zfcp_data.config_lock); - port = rport->dd_data; + port =zfcp_get_port_by_wwpn (adapter, rport->port_name);if (port)zfcp_port_get (port);write_unlock_irq (&zfcp_data.config_lock);
@@ -550,7 +538,6 @@ static void zfcp_scsi_rport_register(strreturn ; } - rport->dd_data = port; rport->maxframe_size = port->maxframe_size; rport->supported_classes = port->supported_classes; port->rport = rport;
@@ -663,7 +650,6 @@ struct fc_function_template zfcp_transpo .reset_fc_host_stats = zfcp_reset_fc_host_stats, .set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo, .get_host_port_state = zfcp_get_host_port_state, - .dev_loss_tmo_callbk = zfcp_scsi_dev_loss_tmo_callbk, .terminate_rport_io = zfcp_scsi_terminate_rport_io, .show_host_port_state = 1, .bsg_request = zfcp_execute_fc_job,
PATCH 20/27 zfcp: Use kthread API for zfcp erp thread
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Switch the creation of the zfcp erp thread from the deprecated kernel_thread API to the kthread API. This allows also the removal of some flags in zfcp since the kthread API handles thread creation and shutdown internally. To allow the usage of the kthread_stop function, replace the erp ready semaphore with a waitqueue for waiting until erp actions arrive on the ready queue.
---
drivers/s390/scsi/zfcp_aux.c | 4 -- drivers/s390/scsi/zfcp_def.h | 6 +--- drivers/s390/scsi/zfcp_erp.c | 62 ++++++++++++++++--------------------------- 3 files changed, 27 insertions(+), 45 deletions(-)
drivers/s390/scsi/zfcp_aux.c +1 -3
@@ -529,7 +529,7 @@ int zfcp_adapter_enqueue(struct ccw_devi goto generic_services_failed;init_waitqueue_head (&adapter->remove_wq); -init_waitqueue_head (&adapter->erp_thread_wqh); +init_waitqueue_head (&adapter->erp_ready_wq);init_waitqueue_head (&adapter->erp_done_wqh);INIT_LIST_HEAD (&adapter->port_list_head);
@@ -541,8 +541,6 @@ int zfcp_adapter_enqueue(struct ccw_devirwlock_init (&adapter->erp_lock);rwlock_init (&adapter->abort_lock); -sema_init (&adapter->erp_ready_sem,0 ); -INIT_WORK (&adapter->stat_work, _zfcp_status_read_scheduler);INIT_WORK (&adapter->scan_work, _zfcp_fc_scan_ports_later);
drivers/s390/scsi/zfcp_def.h +2 -4
@@ -222,8 +222,6 @@ struct zfcp_ls_adisc {#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008#define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010 -#define ZFCP_STATUS_ADAPTER_ERP_THREAD_UP 0x00000020 -#define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL 0x00000080#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
@@ -481,10 +479,9 @@ struct zfcp_adapter {atomic_t status;/* status of this adapter */ struct list_head erp_ready_head;/* error recovery for this adapter/devices */ +wait_queue_head_t erp_ready_wq;struct list_head erp_running_head;rwlock_t erp_lock; -struct semaphore erp_ready_sem; -wait_queue_head_t erp_thread_wqh;wait_queue_head_t erp_done_wqh;struct zfcp_erp_action erp_action;/* pending error recovery */ atomic_t erp_counter;
@@ -492,6 +489,7 @@ struct zfcp_adapter {actions */ u32 erp_low_mem_count;/* nr of erp actions waiting for memory */ +struct task_struct *erp_thread;struct zfcp_wka_ports *gs;/* generic services */ struct zfcp_dbf *dbf;/* debug traces */ struct zfcp_adapter_mempool pool;/* Adapter memory pools */
drivers/s390/scsi/zfcp_erp.c +24 -38
130 lines not on this page · raw message
PATCH 21/27 zfcp: Simplify and update ct/gs and els timeout handling
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The recommendation for a timeout of 2 * R_A_TOV is the same for ct/gs and els requests, so set it in the common function used for initializing both request types. Besides, the timer inside zfcp should only run longer than the timeout set for the channel, so 10 seconds more should be enough (instead of 60 seconds).
---
drivers/s390/scsi/zfcp_def.h | 5 ----- drivers/s390/scsi/zfcp_fc.c | 3 --- drivers/s390/scsi/zfcp_fsf.c | 15 ++++++--------- 3 files changed, 6 insertions(+), 17 deletions(-)
drivers/s390/scsi/zfcp_def.h +0 -5
@@ -73,9 +73,6 @@/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/ -/* timeout for name-server lookup (in seconds) */ -#define ZFCP_NS_GID_PN_TIMEOUT 10 -/* task attribute values in FCP-2 FCP_CMND IU */ #define SIMPLE_Q 0#define HEAD_OF_Q 1
@@ -319,7 +316,6 @@ struct ct_iu_gpn_ft_req {* @resp: scatter-gather list for response * @handler: handler function (called for response to the request) * @handler_data: data passed to handler function -* @timeout: FSF timeout for this request * @completion: completion for synchronization purposes * @status: used to pass error status to calling function */
@@ -329,7 +325,6 @@ struct zfcp_send_ct {struct scatterlist *resp;void (*handler)(unsigned long );unsigned long handler_data; -int timeout;struct completion *completion;int status; };
drivers/s390/scsi/zfcp_fc.c +0 -3
@@ -283,7 +283,6 @@ static int zfcp_fc_ns_gid_pn_request(str gid_pn->ct.wka_port = &adapter->gs->ds; gid_pn->ct.handler = zfcp_fc_ns_handler; gid_pn->ct.handler_data = (unsigned long ) &compl_rec; - gid_pn->ct.timeout =ZFCP_NS_GID_PN_TIMEOUT ; gid_pn->ct.req = &gid_pn->req; gid_pn->ct.resp = &gid_pn->resp; sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req,
@@ -556,7 +555,6 @@ static int zfcp_fc_send_gpn_ft(struct zf ct->wka_port = &adapter->gs->ds; ct->handler = zfcp_fc_ns_handler; ct->handler_data = (unsigned long )&compl_rec; - ct->timeout =10 ; ct->req = &gpn_ft->sg_req; ct->resp = gpn_ft->sg_resp;
@@ -845,7 +843,6 @@ int zfcp_fc_execute_ct_fc_job(struct fc_ ct_fc_job->ct.req = job->request_payload.sg_list; ct_fc_job->ct.resp = job->reply_payload.sg_list; - ct_fc_job->ct.timeout =ZFCP_FSF_REQUEST_TIMEOUT ; ct_fc_job->ct.handler = zfcp_fc_generic_ct_handler; ct_fc_job->ct.handler_data = (unsigned long ) ct_fc_job; ct_fc_job->ct.completion =NULL ;
drivers/s390/scsi/zfcp_fsf.c +6 -9
@@ -1060,7 +1060,12 @@ static int zfcp_fsf_setup_ct_els_sbals(s sg_resp, max_sbals);if (bytes <=0 )return -EIO ; + +/* common settings for ct/gs and els requests */ req->qtcb->bottom.support.resp_buf_length = bytes; + req->qtcb->bottom.support.service_class =FSF_CLASS_3 ; + req->qtcb->bottom.support.timeout =2 *R_A_TOV ; +zfcp_fsf_start_timer (req,2 *R_A_TOV +10 );return 0 ; }
@@ -1096,12 +1101,9 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct req->handler = zfcp_fsf_send_ct_handler; req->qtcb->header.port_handle = wka_port->handle; - req->qtcb->bottom.support.service_class =FSF_CLASS_3 ; - req->qtcb->bottom.support.timeout = ct->timeout; req->data = ct;zfcp_dbf_san_ct_request (req); -zfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT ); ret =zfcp_fsf_req_send (req);if (ret)
@@ -1176,7 +1178,6 @@ int zfcp_fsf_send_els(struct zfcp_send_e {struct zfcp_fsf_req *req;struct zfcp_qdio *qdio = els->adapter->qdio; -struct fsf_qtcb_bottom_support *bottom;int ret = -EIO ;spin_lock_bh (&qdio->req_q_lock);
@@ -1196,16 +1197,12 @@ int zfcp_fsf_send_els(struct zfcp_send_eif (ret) goto failed_send; - bottom = &req->qtcb->bottom.support; + req->qtcb->bottom.support.d_id = els->d_id; req->handler = zfcp_fsf_send_els_handler; - bottom->d_id = els->d_id; - bottom->service_class =FSF_CLASS_3 ; - bottom->timeout =2 *R_A_TOV ; req->data = els;zfcp_dbf_san_els_request (req); -zfcp_fsf_start_timer (req,ZFCP_FSF_REQUEST_TIMEOUT ); ret =zfcp_fsf_req_send (req);if (ret) goto failed_send;
PATCH 22/27 zfcp: Defer resource allocation to first ccw_set_online call
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
So far, zfcp allocated all resources required for FCP adapters/subchannels when the device was discovered in the ccw_probe callback. If there are lots of unused FCP subchannels attached to a system, this is a waste of resources. To alleviate this, defer the resource allocation to the first call to ccw_set_online. To avoid disruptions during possible following calls to ccw_set_offline and then ccw_set_online, keep the adapter resources until the device is finally being removed via ccw_remove. While doing this, also manage the zfcp erp thread together with all other adapter resources in zfcp_adapter_enqueue/dequeue.
drivers/s390/scsi/zfcp_aux.c +6 -0
@@ -541,6 +541,9 @@ int zfcp_adapter_enqueue(struct ccw_devirwlock_init (&adapter->erp_lock);rwlock_init (&adapter->abort_lock); +if (zfcp_erp_thread_setup (adapter)) + goto erp_thread_failed; +INIT_WORK (&adapter->stat_work, _zfcp_status_read_scheduler);INIT_WORK (&adapter->scan_work, _zfcp_fc_scan_ports_later);
@@ -561,6 +564,8 @@ int zfcp_adapter_enqueue(struct ccw_devireturn 0 ; sysfs_failed: +zfcp_erp_thread_kill (adapter); +erp_thread_failed:zfcp_fc_gs_destroy (adapter); generic_services_failed:zfcp_destroy_adapter_work_queue (adapter);
@@ -602,6 +607,7 @@ void zfcp_adapter_dequeue(struct zfcp_adreturn ;zfcp_fc_gs_destroy (adapter); +zfcp_erp_thread_kill (adapter);zfcp_destroy_adapter_work_queue (adapter);zfcp_dbf_adapter_unregister (adapter->dbf);zfcp_free_low_mem_buffers (adapter);
drivers/s390/scsi/zfcp_ccw.c +43 -31
145 lines not on this page · raw message
drivers/s390/scsi/zfcp_erp.c +5 -0
@@ -150,6 +150,9 @@ static int zfcp_erp_required_act(int wan a_status =atomic_read (&adapter->status);if (a_status &ZFCP_STATUS_COMMON_ERP_INUSE )return 0 ; +if (!(a_status &ZFCP_STATUS_COMMON_RUNNING ) && + !(a_status &ZFCP_STATUS_COMMON_OPEN )) +return 0 ;/* shutdown requested for closed adapter */ }return need;
@@ -1349,6 +1352,8 @@ void zfcp_erp_thread_kill(struct zfcp_ad {kthread_stop (adapter->erp_thread); adapter->erp_thread =NULL ; +WARN_ON (!list_empty (&adapter->erp_ready_head)); +WARN_ON (!list_empty (&adapter->erp_running_head)); }/**
PATCH 23/27 zfcp: Replace config semaphore with mutex
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The config semaphore is only used as a mutex, so replace it with a simple mutex.
---
drivers/s390/scsi/zfcp_aux.c | 22 +++++++++++----------- drivers/s390/scsi/zfcp_ccw.c | 20 ++++++++++---------- drivers/s390/scsi/zfcp_def.h | 3 +-- drivers/s390/scsi/zfcp_fc.c | 4 ++-- drivers/s390/scsi/zfcp_sysfs.c | 16 ++++++++-------- 5 files changed, 32 insertions(+), 33 deletions(-)
drivers/s390/scsi/zfcp_aux.c +11 -11
@@ -84,7 +84,7 @@ static void __init zfcp_init_device_confstruct zfcp_port *port;struct zfcp_unit *unit; -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex);read_lock_irq (&zfcp_data.config_lock); adapter =zfcp_get_adapter_by_busid (busid);if (adapter)
@@ -99,20 +99,20 @@ static void __init zfcp_init_device_conf unit =zfcp_unit_enqueue (port, lun);if (IS_ERR (unit)) goto out_unit; -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex);ccw_device_set_online (adapter->ccw_device);zfcp_erp_wait (adapter);flush_work (&unit->scsi_work); -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex);zfcp_unit_put (unit); out_unit:zfcp_port_put (port); out_port:zfcp_adapter_put (adapter); out_adapter: -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex);return ; }
@@ -176,7 +176,7 @@ static int __init zfcp_module_init(void)if (!zfcp_data.gid_pn_cache) goto out_gid_cache; -sema_init (&zfcp_data.config_sema,1 ); +mutex_init (&zfcp_data.config_mutex);rwlock_init (&zfcp_data.config_lock); zfcp_data.scsi_transport_template =
@@ -266,7 +266,7 @@ static void zfcp_sysfs_unit_release(stru* @port: pointer to port where unit is added * @fcp_lun: FCP LUN of unit to be enqueued * Returns: pointer to enqueued unit on success, ERR_PTR on error -* Locks: config_sema must be held to serialize changes to the unit list +* Locks: config_mutex must be held to serialize changes to the unit list * * Sets up some unit internal structures and creates sysfs entry. */
@@ -356,7 +356,7 @@ void zfcp_unit_dequeue(struct zfcp_unitstatic int zfcp_allocate_low_mem_buffers (struct zfcp_adapter *adapter) { -/* must only be called with zfcp_data.config_sema taken */ +/* must only be called with zfcp_data.config_mutex taken */ adapter->pool.erp_req =mempool_create_kmalloc_pool (1 ,sizeof (struct zfcp_fsf_req ));if (!adapter->pool.erp_req)
@@ -404,7 +404,7 @@ static int zfcp_allocate_low_mem_buffersstatic void zfcp_free_low_mem_buffers (struct zfcp_adapter *adapter) { -/* zfcp_data.config_sema must be held */ +/* zfcp_data.config_mutex must be held */ if (adapter->pool.erp_req)mempool_destroy (adapter->pool.erp_req);if (adapter->pool.scsi_req)
@@ -491,7 +491,7 @@ static void zfcp_destroy_adapter_work_qu* Enqueues an adapter at the end of the adapter list in the driver data. * All adapter internal structures are set up. * Proc-fs entries are also created. -* locks: config_sema must be held to serialise changes to the adapter list +* locks: config_mutex must be held to serialize changes to the adapter list */ int zfcp_adapter_enqueue (struct ccw_device *ccw_device) {
@@ -499,7 +499,7 @@ int zfcp_adapter_enqueue(struct ccw_devi/* * Note: It is safe to release the list_lock, as any list changes -* are protected by the config_sema, which must be held to get here +* are protected by the config_mutex, which must be held to get here */ adapter =kzalloc (sizeof (struct zfcp_adapter ),GFP_KERNEL );
@@ -630,7 +630,7 @@ static void zfcp_sysfs_port_release(stru* @status: initial status for the port * @d_id: destination id of the remote port to be enqueued * Returns: pointer to enqueued port on success, ERR_PTR on error -* Locks: config_sema must be held to serialize changes to the port list +* Locks: config_mutex must be held to serialize changes to the port list * * All port internal structures are set up and the sysfs entry is generated. * d_id is used to enqueue ports with a well known address like the Directory
drivers/s390/scsi/zfcp_ccw.c +10 -10
@@ -21,12 +21,12 @@ static int zfcp_ccw_suspend(struct ccw_dif (!adapter)return 0 ; -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex);zfcp_erp_adapter_shutdown (adapter,0 ,"ccsusp1" ,NULL );zfcp_erp_wait (adapter); -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex);return 0 ; }
@@ -98,7 +98,7 @@ static void zfcp_ccw_remove(struct ccw_dccw_device_set_offline (ccw_device); -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex); adapter =dev_get_drvdata (&ccw_device->dev);if (!adapter) goto out;
@@ -128,7 +128,7 @@ static void zfcp_ccw_remove(struct ccw_dzfcp_adapter_dequeue (adapter); out: -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex); }/**
@@ -149,7 +149,7 @@ static int zfcp_ccw_set_online(struct ccstruct zfcp_adapter *adapter;int ret =0 ; -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex); adapter =dev_get_drvdata (&ccw_device->dev);if (!adapter) {
@@ -173,7 +173,7 @@ static int zfcp_ccw_set_online(struct cc "ccsonl2", NULL);zfcp_erp_wait (adapter); out: -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex);if (!ret)flush_work (&adapter->scan_work);return ret;
@@ -190,14 +190,14 @@ static int zfcp_ccw_set_offline(struct c {struct zfcp_adapter *adapter; -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex); adapter =dev_get_drvdata (&ccw_device->dev);if (!adapter) goto out;zfcp_erp_adapter_shutdown (adapter,0 ,"ccsoff1" ,NULL );zfcp_erp_wait (adapter); -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex); out:return 0 ; }
@@ -251,12 +251,12 @@ static void zfcp_ccw_shutdown(struct ccw {struct zfcp_adapter *adapter; -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex); adapter =dev_get_drvdata (&cdev->dev);zfcp_erp_adapter_shutdown (adapter,0 ,"ccshut1" ,NULL );zfcp_erp_wait (adapter);zfcp_erp_thread_kill (adapter); -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex); }static struct ccw_driver zfcp_ccw_driver = {
drivers/s390/scsi/zfcp_def.h +1 -2
@@ -604,8 +604,7 @@ struct zfcp_data {rwlock_t config_lock;/* serialises changes to adapter/port/unit lists */ -struct semaphore config_sema;/* serialises configuration -changes */ +struct mutex config_mutex;struct kmem_cache *gpn_ft_cache;struct kmem_cache *qtcb_cache;struct kmem_cache *sr_buffer_cache;
drivers/s390/scsi/zfcp_fc.c +2 -2
@@ -613,7 +613,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfreturn -E2BIG ; } -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex);/* first entry is the header */ for (x =1 ; x < max_entries && !last; x++) {
@@ -647,7 +647,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfzfcp_erp_wait (adapter);list_for_each_entry_safe (port, tmp, &adapter->port_list_head, list)zfcp_fc_validate_port (port); -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex);return ret; }
drivers/s390/scsi/zfcp_sysfs.c +8 -8
@@ -88,7 +88,7 @@ static ssize_t zfcp_sysfs_##_feat##_failunsigned long val; \int retval =0 ; \ \ -down (&zfcp_data.config_sema); \ +mutex_lock (&zfcp_data.config_mutex); \if (atomic_read (&_feat->status) &ZFCP_STATUS_COMMON_REMOVE ) { \ retval = -EBUSY ; \ goto out; \
@@ -105,7 +105,7 @@ static ssize_t zfcp_sysfs_##_feat##_fail _reopen_id, NULL); \zfcp_erp_wait (_adapter); \ out: \ -up (&zfcp_data.config_sema); \ +mutex_unlock (&zfcp_data.config_mutex); \return retval ? retval : (ssize_t ) count; \ } \ static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \
@@ -142,7 +142,7 @@ static ssize_t zfcp_sysfs_port_remove_stint retval =0 ;LIST_HEAD (port_remove_lh); -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex);if (atomic_read (&adapter->status) &ZFCP_STATUS_COMMON_REMOVE ) { retval = -EBUSY ; goto out;
@@ -173,7 +173,7 @@ static ssize_t zfcp_sysfs_port_remove_stzfcp_port_put (port);zfcp_port_dequeue (port); out: -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex);return retval ? retval : (ssize_t ) count; } static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL,
@@ -207,7 +207,7 @@ static ssize_t zfcp_sysfs_unit_add_storeu64 fcp_lun;int retval = -EINVAL ; -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex);if (atomic_read (&port->status) &ZFCP_STATUS_COMMON_REMOVE ) { retval = -EBUSY ; goto out;
@@ -226,7 +226,7 @@ static ssize_t zfcp_sysfs_unit_add_storezfcp_erp_wait (unit->port->adapter);zfcp_unit_put (unit); out: -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex);return retval ? retval : (ssize_t ) count; } static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
@@ -241,7 +241,7 @@ static ssize_t zfcp_sysfs_unit_remove_stint retval =0 ;LIST_HEAD (unit_remove_lh); -down (&zfcp_data.config_sema); +mutex_lock (&zfcp_data.config_mutex);if (atomic_read (&port->status) &ZFCP_STATUS_COMMON_REMOVE ) { retval = -EBUSY ; goto out;
@@ -282,7 +282,7 @@ static ssize_t zfcp_sysfs_unit_remove_stzfcp_unit_put (unit);zfcp_unit_dequeue (unit); out: -up (&zfcp_data.config_sema); +mutex_unlock (&zfcp_data.config_mutex);return retval ? retval : (ssize_t ) count; } static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
PATCH 24/27 zfcp: proper use of device register
In reply to Christof SchmittFrom: Sebastian Ott <[email protected]>
Don't use kfree directly after device registration started.
---
drivers/s390/scsi/zfcp_aux.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/s390/scsi/zfcp_aux.c +8 -4
@@ -309,8 +309,10 @@ struct zfcp_unit *zfcp_unit_enqueue(stru }read_unlock_irq (&zfcp_data.config_lock); -if (device_register (&unit->sysfs_device)) - goto err_out_free; +if (device_register (&unit->sysfs_device)) { +put_device (&unit->sysfs_device); +return ERR_PTR (-EINVAL ); + }if (sysfs_create_group (&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs)) {
@@ -675,8 +677,10 @@ struct zfcp_port *zfcp_port_enqueue(stru }read_unlock_irq (&zfcp_data.config_lock); -if (device_register (&port->sysfs_device)) - goto err_out_free; +if (device_register (&port->sysfs_device)) { +put_device (&port->sysfs_device); + goto err_out; + } retval =sysfs_create_group (&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
PATCH 25/27 zfcp: Handle failures during device allocation correctly
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
dev_set_name tries to allocate memory, so check the return value for allocation failures. After dev_set_name succeeds, call device_register as next step to be able to use put_device during error handling.
---
drivers/s390/scsi/zfcp_aux.c | 65 +++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 36 deletions(-)
drivers/s390/scsi/zfcp_aux.c +29 -36
@@ -274,6 +274,13 @@ struct zfcp_unit *zfcp_unit_enqueue(stru {struct zfcp_unit *unit; +read_lock_irq (&zfcp_data.config_lock); +if (zfcp_get_unit_by_lun (port, fcp_lun)) { +read_unlock_irq (&zfcp_data.config_lock); +return ERR_PTR (-EINVAL ); + } +read_unlock_irq (&zfcp_data.config_lock); + unit =kzalloc (sizeof (struct zfcp_unit ),GFP_KERNEL );if (!unit)return ERR_PTR (-ENOMEM );
@@ -285,8 +292,11 @@ struct zfcp_unit *zfcp_unit_enqueue(stru unit->port = port; unit->fcp_lun = fcp_lun; -dev_set_name (&unit->sysfs_device,"0x%016llx" , - (unsigned long long ) fcp_lun); +if (dev_set_name (&unit->sysfs_device,"0x%016llx" , + (unsigned long long ) fcp_lun)) { +kfree (unit); +return ERR_PTR (-ENOMEM ); + } unit->sysfs_device.parent = &port->sysfs_device; unit->sysfs_device.release = zfcp_sysfs_unit_release;dev_set_drvdata (&unit->sysfs_device, unit);
@@ -302,13 +312,6 @@ struct zfcp_unit *zfcp_unit_enqueue(stru unit->latencies.cmd.channel.min =0xFFFFFFFF ; unit->latencies.cmd.fabric.min =0xFFFFFFFF ; -read_lock_irq (&zfcp_data.config_lock); -if (zfcp_get_unit_by_lun (port, fcp_lun)) { -read_unlock_irq (&zfcp_data.config_lock); - goto err_out_free; - } -read_unlock_irq (&zfcp_data.config_lock); -if (device_register (&unit->sysfs_device)) {put_device (&unit->sysfs_device);return ERR_PTR (-EINVAL );
@@ -317,7 +320,7 @@ struct zfcp_unit *zfcp_unit_enqueue(struif (sysfs_create_group (&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs)) {device_unregister (&unit->sysfs_device); -return ERR_PTR (-EIO ); +return ERR_PTR (-EINVAL ); }zfcp_unit_get (unit);
@@ -332,10 +335,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struzfcp_port_get (port);return unit; - -err_out_free: -kfree (unit); -return ERR_PTR (-EINVAL ); }/**
@@ -642,7 +641,13 @@ struct zfcp_port *zfcp_port_enqueue(stru u32 status, u32 d_id) {struct zfcp_port *port; -int retval; + +read_lock_irq (&zfcp_data.config_lock); +if (zfcp_get_port_by_wwpn (adapter, wwpn)) { +read_unlock_irq (&zfcp_data.config_lock); +return ERR_PTR (-EINVAL ); + } +read_unlock_irq (&zfcp_data.config_lock); port =kzalloc (sizeof (struct zfcp_port ),GFP_KERNEL );if (!port)
@@ -663,31 +668,24 @@ struct zfcp_port *zfcp_port_enqueue(struatomic_set_mask (status |ZFCP_STATUS_COMMON_REMOVE , &port->status);atomic_set (&port->refcount,0 ); -dev_set_name (&port->sysfs_device,"0x%016llx" , - (unsigned long long )wwpn); +if (dev_set_name (&port->sysfs_device,"0x%016llx" , + (unsigned long long )wwpn)) { +kfree (port); +return ERR_PTR (-ENOMEM ); + } port->sysfs_device.parent = &adapter->ccw_device->dev; - port->sysfs_device.release = zfcp_sysfs_port_release;dev_set_drvdata (&port->sysfs_device, port); -read_lock_irq (&zfcp_data.config_lock); -if (zfcp_get_port_by_wwpn (adapter, wwpn)) { -read_unlock_irq (&zfcp_data.config_lock); - goto err_out_free; - } -read_unlock_irq (&zfcp_data.config_lock); -if (device_register (&port->sysfs_device)) {put_device (&port->sysfs_device); - goto err_out; +return ERR_PTR (-EINVAL ); } - retval =sysfs_create_group (&port->sysfs_device.kobj, - &zfcp_sysfs_port_attrs); - -if (retval) { +if (sysfs_create_group (&port->sysfs_device.kobj, + &zfcp_sysfs_port_attrs)) {device_unregister (&port->sysfs_device); - goto err_out; +return ERR_PTR (-EINVAL ); }zfcp_port_get (port);
@@ -701,11 +699,6 @@ struct zfcp_port *zfcp_port_enqueue(struzfcp_adapter_get (adapter);return port; - -err_out_free: -kfree (port); -err_out: -return ERR_PTR (-EINVAL ); }/**
PATCH 26/27 zfcp: Remove duplicated code for debug timestamps
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The timestamp calculation used for s390dbf output is the same in a private zfcp function and in debug.c. Replace both with a common inline function.
---
arch/s390/include/asm/timex.h | 8 ++++++++ arch/s390/kernel/debug.c | 8 +------- arch/s390/kernel/time.c | 1 + drivers/s390/scsi/zfcp_dbf.c | 19 +++---------------- 4 files changed, 13 insertions(+), 23 deletions(-)
arch/s390/include/asm/timex.h +8 -0
@@ -88,6 +88,14 @@ int get_sync_clock(unsigned long long *cvoid init_cpu_timer (void );unsigned long long monotonic_clock (void ); +void tod_to_timeval (__u64 ,struct timespec *); + +static inline +void stck_to_timespec (unsigned long long stck,struct timespec *ts) +{ +tod_to_timeval (stck -TOD_UNIX_EPOCH , ts); +} +extern u64 sched_clock_base_cc;#endif
arch/s390/kernel/debug.c +1 -7
@@ -63,8 +63,6 @@ typedef struct } debug_sprintf_entry_t; -extern void tod_to_timeval (uint64_t todval,struct timespec *xtime); -/* internal function prototyes */ static int debug_init (void );
@@ -1450,17 +1448,13 @@ debug_dflt_header_fn(debug_info_t * id, int area, debug_entry_t * entry, char *out_buf) { struct timespec time_spec; -unsigned long long time;char *except_str;unsigned long caller;int rc =0 ;unsigned int level; level = entry->id.fields.level; - time = entry->id.stck; -/* adjust todclock to 1970 */ - time -=0x8126d60e46000000LL - (0x3c26700LL *1000000 *4096 ); -tod_to_timeval (time, &time_spec); +stck_to_timespec (entry->id.stck, &time_spec);if (entry->id.fields.exception) except_str ="*" ;
arch/s390/kernel/time.c +1 -0
@@ -90,6 +90,7 @@ void tod_to_timeval(__u64 todval, struct todval -= (sec *1000000 ) <<12 ; xtime->tv_nsec = ((todval *1000 ) >>12 ); } +EXPORT_SYMBOL (tod_to_timeval);void clock_comparator_work (void ) {
drivers/s390/scsi/zfcp_dbf.c +3 -16
@@ -38,19 +38,6 @@ static void zfcp_dbf_hexdump(debug_info_ } } -/* FIXME: this duplicate this code in s390 debug feature */ -static void zfcp_dbf_timestamp (unsigned long long stck,struct timespec *time) -{ -unsigned long long sec; - - stck -=0x8126d60e46000000LL - (0x3c26700LL *1000000 *4096 ); - sec = stck >>12 ; -do_div (sec,1000000 ); - time->tv_sec = sec; - stck -= (sec *1000000 ) <<12 ; - time->tv_nsec = ((stck *1000 ) >>12 ); -} -static void zfcp_dbf_tag (char **p,const char *label,const char *tag) {int i;
@@ -107,7 +94,7 @@ static int zfcp_dbf_view_header(debug_inchar *p = out_buf;if (strncmp (dump->tag,"dump" ,ZFCP_DBF_TAG_SIZE ) !=0 ) { -zfcp_dbf_timestamp (entry->id.stck, &t); +stck_to_timespec (entry->id.stck, &t);zfcp_dbf_out (&p,"timestamp" ,"%011lu:%06lu" , t.tv_sec, t.tv_nsec);zfcp_dbf_out (&p,"cpu" ,"%02i" , entry->id.fields.cpuid);
@@ -320,7 +307,7 @@ static void zfcp_dbf_hba_view_response(czfcp_dbf_out (p,"fsf_command" ,"0x%08x" , r->fsf_command);zfcp_dbf_out (p,"fsf_reqid" ,"0x%0Lx" , r->fsf_reqid);zfcp_dbf_out (p,"fsf_seqno" ,"0x%08x" , r->fsf_seqno); -zfcp_dbf_timestamp (r->fsf_issued, &t); +stck_to_timespec (r->fsf_issued, &t);zfcp_dbf_out (p,"fsf_issued" ,"%011lu:%06lu" , t.tv_sec, t.tv_nsec);zfcp_dbf_out (p,"fsf_prot_status" ,"0x%08x" , r->fsf_prot_status);zfcp_dbf_out (p,"fsf_status" ,"0x%08x" , r->fsf_status);
@@ -976,7 +963,7 @@ static int zfcp_dbf_scsi_view_format(debzfcp_dbf_out (&p,"old_fsf_reqid" ,"0x%0Lx" , r->old_fsf_reqid);zfcp_dbf_out (&p,"fsf_reqid" ,"0x%0Lx" , r->fsf_reqid);zfcp_dbf_out (&p,"fsf_seqno" ,"0x%08x" , r->fsf_seqno); -zfcp_dbf_timestamp (r->fsf_issued, &t); +stck_to_timespec (r->fsf_issued, &t);zfcp_dbf_out (&p,"fsf_issued" ,"%011lu:%06lu" , t.tv_sec, t.tv_nsec);if (strncmp (r->tag,"rslt" ,ZFCP_DBF_TAG_SIZE ) ==0 ) {
PATCH 27/27 zfcp: optimize zfcp_qdio_account
In reply to Christof SchmittFrom: Heiko Carstens <[email protected]>
Remove expensive ktime_get()/ktime_us_delta() functions from the hot path and use get_clock_monotonic() instead. This elimates seven function calls and avoids a lot of unnecessary calculations.
---
drivers/s390/scsi/zfcp_def.h | 2 +- drivers/s390/scsi/zfcp_qdio.c | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-)
drivers/s390/scsi/zfcp_def.h +1 -1
@@ -438,7 +438,7 @@ struct zfcp_qdio {struct zfcp_qdio_queue req_q;spinlock_t stat_lock;spinlock_t req_q_lock; -ktime_t req_q_time; +unsigned long long req_q_time;u64 req_q_util;atomic_t req_q_full;wait_queue_head_t req_q_wq;
drivers/s390/scsi/zfcp_qdio.c +5 -6
@@ -56,16 +56,15 @@ static void zfcp_qdio_zero_sbals(struct }/* this needs to be called prior to updating the queue fill level */ -static void zfcp_qdio_account (struct zfcp_qdio *qdio) +static inline void zfcp_qdio_account (struct zfcp_qdio *qdio) { -ktime_t now; -s64 span; +unsigned long long now, span;int free, used;spin_lock (&qdio->stat_lock); - now =ktime_get (); - span =ktime_us_delta (now, qdio->req_q_time); - free =max (0 ,atomic_read (&qdio->req_q.count)); + now =get_clock_monotonic (); + span = (now - qdio->req_q_time) >>12 ; + free =atomic_read (&qdio->req_q.count); used =QDIO_MAX_BUFFERS_PER_Q - free; qdio->req_q_util += used * span; qdio->req_q_time = now;