zfcp updates for 2.6.35 merge window
Subsystems (3)
cover zfcp updates for 2.6.35 merge window
James,
here is a series of zfcp patches for the 2.6.35 merge. The patches apply on top of the current scsi-misc tree.
--
Christof
PATCH 1/5 zfcp: Report scatter-gather limits to SCSI and block layer
From: Christof Schmitt <[email protected]>
Instead of dealing with large segments in the scatter-gather lists in zfcp_qdio.c, report the limits to the upper layers. With these limits in place, the code for mapping large data blocks to multiple sbales can be removed.
---
drivers/s390/scsi/zfcp_aux.c | 4 +++ drivers/s390/scsi/zfcp_def.h | 1 drivers/s390/scsi/zfcp_qdio.c | 45 ++++++++++-------------------------------- drivers/s390/scsi/zfcp_qdio.h | 2 + drivers/s390/scsi/zfcp_scsi.c | 1 5 files changed, 19 insertions(+), 34 deletions(-)
drivers/s390/scsi/zfcp_aux.c +4 -0
@@ -545,6 +545,10 @@ struct zfcp_adapter *zfcp_adapter_enqueu &zfcp_sysfs_adapter_attrs)) goto failed; +/* report size limit per scatter-gather segment */ + adapter->dma_parms.max_segment_size =ZFCP_QDIO_SBALE_LEN ; + adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; +if (!zfcp_adapter_scsi_register (adapter))return adapter;
drivers/s390/scsi/zfcp_def.h +1 -0
@@ -205,6 +205,7 @@ struct zfcp_adapter {struct work_struct scan_work;struct service_level service_level;struct workqueue_struct *work_queue; +struct device_dma_parameters dma_parms; };struct zfcp_port {
drivers/s390/scsi/zfcp_qdio.c +11 -34
63 lines not on this page · raw message
drivers/s390/scsi/zfcp_qdio.h +2 -0
@@ -11,6 +11,8 @@#include <asm/qdio.h> +#define ZFCP_QDIO_SBALE_LEN PAGE_SIZE +/** * struct zfcp_qdio_queue - qdio queue buffer, zfcp index and free count * @sbal: qdio buffers
drivers/s390/scsi/zfcp_scsi.c +1 -0
@@ -682,6 +682,7 @@ struct zfcp_data zfcp_data = { .use_clustering = 1, .sdev_attrs = zfcp_sysfs_sdev_attrs, .max_sectors = (ZFCP_MAX_SBALES_PER_REQ * 8), + .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, .shost_attrs = zfcp_sysfs_shost_attrs, }, };
PATCH 2/5 zfcp: Move sbale handling to zfcp_qdio files
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Move the code accessing the qdio sbales and zfcp_qdio_req struct to the zfcp_qdio files and provide helper functions for accessing the qdio related parts.
---
drivers/s390/scsi/zfcp_def.h | 17 --- drivers/s390/scsi/zfcp_ext.h | 5 - drivers/s390/scsi/zfcp_fsf.c | 180 +++++++++++++++--------------------------- drivers/s390/scsi/zfcp_fsf.h | 9 +- drivers/s390/scsi/zfcp_qdio.c | 25 ++--- drivers/s390/scsi/zfcp_qdio.h | 102 +++++++++++++++++++++++ drivers/s390/scsi/zfcp_scsi.c | 4 7 files changed, 191 insertions(+), 151 deletions(-)
drivers/s390/scsi/zfcp_def.h +0 -17
@@ -44,23 +44,6 @@ struct zfcp_reqlist;/********************* SCSI SPECIFIC DEFINES *********************************/ #define ZFCP_SCSI_ER_TIMEOUT (10*HZ) -/********************* CIO/QDIO SPECIFIC DEFINES *****************************/ - -/* DMQ bug workaround: don't use last SBALE */ -#define ZFCP_MAX_SBALES_PER_SBAL (QDIO_MAX_ELEMENTS_PER_BUFFER - 1) - -/* index of last SBALE (with respect to DMQ bug workaround) */ -#define ZFCP_LAST_SBALE_PER_SBAL (ZFCP_MAX_SBALES_PER_SBAL - 1) - -/* max. number of (data buffer) SBALEs in largest SBAL chain */ -#define ZFCP_MAX_SBALES_PER_REQ \ - (FSF_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2) -/* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */ - -#define ZFCP_MAX_SECTORS (ZFCP_MAX_SBALES_PER_REQ * 8) -/* max. number of (data buffer) SBALEs in largest SBAL chain -multiplied with number of sectors per 4k block */ -/********************* FSF SPECIFIC DEFINES *********************************/ /* ATTENTION: value must not be used by hardware */
drivers/s390/scsi/zfcp_ext.h +2 -3
@@ -3,7 +3,7 @@* * External function declarations. * -* Copyright IBM Corporation 2002, 2009 +* Copyright IBM Corporation 2002, 2010 */ #ifndef ZFCP_EXT_H
@@ -144,8 +144,7 @@ extern void zfcp_fsf_reqid_check(structextern 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_qdio_req *); -extern int zfcp_qdio_sbals_from_sg (struct zfcp_qdio *, -struct zfcp_qdio_req *,unsigned long , +extern int zfcp_qdio_sbals_from_sg (struct zfcp_qdio *,struct zfcp_qdio_req *,struct scatterlist *,int );extern int zfcp_qdio_open (struct zfcp_qdio *);extern void zfcp_qdio_close (struct zfcp_qdio *);
drivers/s390/scsi/zfcp_fsf.c +67 -113
564 lines not on this page · raw message
drivers/s390/scsi/zfcp_fsf.h +7 -2
@@ -3,7 +3,7 @@* * Interface to the FSF support functions. * -* Copyright IBM Corporation 2002, 2009 +* Copyright IBM Corporation 2002, 2010 */ #ifndef FSF_H
@@ -152,7 +152,12 @@#define FSF_CLASS_3 0x00000003/* SBAL chaining */ -#define FSF_MAX_SBALS_PER_REQ 36 +#define ZFCP_FSF_MAX_SBALS_PER_REQ 36 + +/* max. number of (data buffer) SBALEs in largest SBAL chain +* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */ +#define ZFCP_FSF_MAX_SBALES_PER_REQ \ + (ZFCP_FSF_MAX_SBALS_PER_REQ * ZFCP_QDIO_MAX_SBALES_PER_SBAL - 2)/* logging space behind QTCB */ #define FSF_QTCB_LOG_SIZE 1024
drivers/s390/scsi/zfcp_qdio.c +11 -14
@@ -3,7 +3,7 @@* * Setup and helper functions to access QDIO. * -* Copyright IBM Corporation 2002, 2009 +* Copyright IBM Corporation 2002, 2010 */ #define KMSG_COMPONENT "zfcp"
@@ -151,8 +151,7 @@ static void zfcp_qdio_sbal_limit(struct }static struct qdio_buffer_element * -zfcp_qdio_sbal_chain (struct zfcp_qdio *qdio,struct zfcp_qdio_req *q_req, -unsigned long sbtype) +zfcp_qdio_sbal_chain (struct zfcp_qdio *qdio,struct zfcp_qdio_req *q_req) {struct qdio_buffer_element *sbale;
@@ -180,17 +179,16 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *q/* set storage-block type for new SBAL */ sbale =zfcp_qdio_sbale_curr (qdio, q_req); - sbale->flags |= sbtype; + sbale->flags |= q_req->sbtype;return sbale; }static struct qdio_buffer_element * -zfcp_qdio_sbale_next (struct zfcp_qdio *qdio,struct zfcp_qdio_req *q_req, -unsigned int sbtype) +zfcp_qdio_sbale_next (struct zfcp_qdio *qdio,struct zfcp_qdio_req *q_req) { -if (q_req->sbale_curr ==ZFCP_LAST_SBALE_PER_SBAL ) -return zfcp_qdio_sbal_chain (qdio, q_req, sbtype); +if (q_req->sbale_curr ==ZFCP_QDIO_LAST_SBALE_PER_SBAL ) +return zfcp_qdio_sbal_chain (qdio, q_req); q_req->sbale_curr++;return zfcp_qdio_sbale_curr (qdio, q_req); }
@@ -208,15 +206,14 @@ static void zfcp_qdio_undo_sbals(struct/** * zfcp_qdio_sbals_from_sg - fill SBALs from scatter-gather list -* @fsf_req: request to be processed -* @sbtype: SBALE flags +* @qdio: pointer to struct zfcp_qdio +* @q_req: pointer to struct zfcp_qdio_req * @sg: scatter-gather list * @max_sbals: upper bound for number of SBALs to be used * Returns: number of bytes, or error (negativ) */ int zfcp_qdio_sbals_from_sg (struct zfcp_qdio *qdio,struct zfcp_qdio_req *q_req, -unsigned long sbtype,struct scatterlist *sg, -int max_sbals) +struct scatterlist *sg,int max_sbals) {struct qdio_buffer_element *sbale;int bytes =0 ;
@@ -226,10 +223,10 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_/* set storage-block type for this request */ sbale =zfcp_qdio_sbale_req (qdio, q_req); - sbale->flags |= sbtype; + sbale->flags |= q_req->sbtype;for (; sg; sg =sg_next (sg)) { - sbale =zfcp_qdio_sbale_next (qdio, q_req, sbtype); + sbale =zfcp_qdio_sbale_next (qdio, q_req);if (!sbale) {atomic_inc (&qdio->req_q_full);zfcp_qdio_undo_sbals (qdio, q_req);
drivers/s390/scsi/zfcp_qdio.h +102 -0
124 lines not on this page · raw message
drivers/s390/scsi/zfcp_scsi.c +2 -2
@@ -677,11 +677,11 @@ struct zfcp_data zfcp_data = { .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, .can_queue = 4096, .this_id = -1, - .sg_tablesize = ZFCP_MAX_SBALES_PER_REQ, + .sg_tablesize = ZFCP_FSF_MAX_SBALES_PER_REQ, .cmd_per_lun = 1, .use_clustering = 1, .sdev_attrs = zfcp_sysfs_sdev_attrs, - .max_sectors = (ZFCP_MAX_SBALES_PER_REQ * 8), + .max_sectors = (ZFCP_FSF_MAX_SBALES_PER_REQ * 8), .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, .shost_attrs = zfcp_sysfs_shost_attrs, },
PATCH 3/5 zfcp: Move sbal_get function to zfcp_qdio.c
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
Waiting for a free sbal is a operation on the qdio queue. Move the code implementing the wait to zfcp_qdio.c and rename the functions accordingly.
---
drivers/s390/scsi/zfcp_ext.h | 1 drivers/s390/scsi/zfcp_fsf.c | 65 ++++++++++-------------------------------- drivers/s390/scsi/zfcp_qdio.c | 40 +++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 48 deletions(-)
drivers/s390/scsi/zfcp_ext.h +1 -0
@@ -143,6 +143,7 @@ extern void zfcp_fsf_reqid_check(struct/* zfcp_qdio.c */ extern int zfcp_qdio_setup (struct zfcp_adapter *);extern void zfcp_qdio_destroy (struct zfcp_qdio *); +extern int zfcp_qdio_sbal_get (struct zfcp_qdio *);extern int zfcp_qdio_send (struct zfcp_qdio *,struct zfcp_qdio_req *);extern int zfcp_qdio_sbals_from_sg (struct zfcp_qdio *,struct zfcp_qdio_req *,struct scatterlist *,int );
drivers/s390/scsi/zfcp_fsf.c +17 -48
173 lines not on this page · raw message
drivers/s390/scsi/zfcp_qdio.c +40 -0
@@ -246,6 +246,46 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_return bytes; } +static int zfcp_qdio_sbal_check (struct zfcp_qdio *qdio) +{ +struct zfcp_qdio_queue *req_q = &qdio->req_q; + +spin_lock_bh (&qdio->req_q_lock); +if (atomic_read (&req_q->count)) +return 1 ; +spin_unlock_bh (&qdio->req_q_lock); +return 0 ; +} + +/** +* zfcp_qdio_sbal_get - get free sbal in request queue, wait if necessary +* @qdio: pointer to struct zfcp_qdio +* +* The req_q_lock must be held by the caller of this function, and +* this function may only be called from process context; it will +* sleep when waiting for a free sbal. +* +* Returns: 0 on success, -EIO if there is no free sbal after waiting. +*/ +int zfcp_qdio_sbal_get (struct zfcp_qdio *qdio) +{ +long ret; + +spin_unlock_bh (&qdio->req_q_lock); + ret =wait_event_interruptible_timeout (qdio->req_q_wq, +zfcp_qdio_sbal_check (qdio),5 *HZ ); +if (ret >0 ) +return 0 ; +if (!ret) { +atomic_inc (&qdio->req_q_full); +/* assume hanging outbound queue, try queue recovery */ +zfcp_erp_adapter_reopen (qdio->adapter,0 ,"qdsbg_1" ,NULL ); + } + +spin_lock_bh (&qdio->req_q_lock); +return -EIO ; +} +/** * zfcp_qdio_send - set PCI flag in first SBALE and send req to QDIO * @qdio: pointer to struct zfcp_qdio
PATCH 4/5 zfcp: Use status_read_buf_num provided by FCP channel
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
The FCP channel provides the number of status read buffers to issue. Use the provided number instead of the hardcoded number in zfcp.
---
drivers/s390/scsi/zfcp_aux.c | 3 ++- drivers/s390/scsi/zfcp_def.h | 1 + drivers/s390/scsi/zfcp_erp.c | 2 +- drivers/s390/scsi/zfcp_fsf.c | 1 + drivers/s390/scsi/zfcp_fsf.h | 2 +- 5 files changed, 6 insertions(+), 3 deletions(-)
drivers/s390/scsi/zfcp_aux.c +2 -1
@@ -425,7 +425,8 @@ int zfcp_status_read_refill(struct zfcp_ {while (atomic_read (&adapter->stat_miss) >0 )if (zfcp_fsf_status_read (adapter->qdio)) { -if (atomic_read (&adapter->stat_miss) >=16 ) { +if (atomic_read (&adapter->stat_miss) >= + adapter->stat_read_buf_num) {zfcp_erp_adapter_reopen (adapter,0 ,"axsref1" ,NULL );return 1 ;
drivers/s390/scsi/zfcp_def.h +1 -0
@@ -164,6 +164,7 @@ struct zfcp_adapter {stack abort/command completion races */ atomic_t stat_miss;/* # missing status reads*/ +unsigned int stat_read_buf_num;struct work_struct stat_work;atomic_t status;/* status of this adapter */ struct list_head erp_ready_head;/* error recovery for this
drivers/s390/scsi/zfcp_erp.c +1 -1
@@ -714,7 +714,7 @@ static int zfcp_erp_adapter_strategy_opeif (zfcp_erp_adapter_strategy_open_fsf_xport (act) ==ZFCP_ERP_FAILED )return ZFCP_ERP_FAILED ; -atomic_set (&act->adapter->stat_miss,16 ); +atomic_set (&act->adapter->stat_miss, act->adapter->stat_read_buf_num);if (zfcp_status_read_refill (act->adapter))return ZFCP_ERP_FAILED ;
drivers/s390/scsi/zfcp_fsf.c +1 -0
@@ -496,6 +496,7 @@ static int zfcp_fsf_exchange_config_eval adapter->hydra_version = bottom->adapter_type; adapter->timer_ticks = bottom->timer_interval; + adapter->stat_read_buf_num =max (bottom->status_read_buf_num, (u16 )16 );if (fc_host_permanent_port_name (shost) ==-1 )fc_host_permanent_port_name (shost) =fc_host_port_name (shost);
drivers/s390/scsi/zfcp_fsf.h +1 -1
@@ -366,7 +366,7 @@ struct fsf_qtcb_bottom_config {u32 adapter_type;u8 res0;u8 peer_d_id[3 ]; -u8 res1[2 ]; +u16 status_read_buf_num;u16 timer_interval;u8 res2[9 ];u8 s_id[3 ];
PATCH 5/5 zfcp: Zero memory for gpn_ft and adisc requests
In reply to Christof SchmittFrom: Christof Schmitt <[email protected]>
With debug kernels, the memory allocated with kmem_cache_alloc might be initialized with the poison values 6b and a5. Use kmem_cache_zalloc instead of kmem_cache_alloc to get zeroed memory and not send invalid requests.
--- drivers/s390/scsi/zfcp_fc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/s390/scsi/zfcp_fc.c +2 -2
@@ -400,7 +400,7 @@ static int zfcp_fc_adisc(struct zfcp_porstruct zfcp_adapter *adapter = port->adapter;int ret; - adisc =kmem_cache_alloc (zfcp_data.adisc_cache,GFP_ATOMIC ); + adisc =kmem_cache_zalloc (zfcp_data.adisc_cache,GFP_ATOMIC );if (!adisc)return -ENOMEM ;
@@ -493,7 +493,7 @@ static struct zfcp_fc_gpn_ft *zfcp_allocif (!gpn_ft)return NULL ; - req =kmem_cache_alloc (zfcp_data.gpn_ft_cache,GFP_KERNEL ); + req =kmem_cache_zalloc (zfcp_data.gpn_ft_cache,GFP_KERNEL );if (!req) {kfree (gpn_ft); gpn_ft =NULL ;