Commit 564e1c86 authored by Swen Schillig's avatar Swen Schillig Committed by James Bottomley

[SCSI] zfcp: Move qdio related data out of zfcp_adapter

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.
Signed-off-by: default avatarSwen Schillig <swen@vnet.ibm.com>
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 42428f74
......@@ -428,7 +428,7 @@ static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
int 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_device *ccw_device)
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))
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_device *ccw_device)
spin_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_adapter *adapter)
zfcp_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);
}
......
......@@ -274,16 +274,16 @@ void _zfcp_hba_dbf_event_fsf_unsol(const char *tag, int level,
/**
* 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;
......
......@@ -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;
};
......
......@@ -603,9 +603,11 @@ static void zfcp_erp_wakeup(struct zfcp_adapter *adapter)
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_close(struct zfcp_erp_action *act)
struct 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);
......
......@@ -51,7 +51,7 @@ extern void _zfcp_hba_dbf_event_fsf_response(const char *, int level,
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,
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(struct zfcp_erp_action *);
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 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);
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;
......
This diff is collapsed.
This diff is collapsed.
......@@ -225,7 +225,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
{
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_get_fc_host_stats(struct Scsi_Host *host)
if (!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(struct Scsi_Host *shost)
if (!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 {
......
......@@ -425,7 +425,7 @@ static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev,
if (!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(struct device *dev,
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_show(struct device *dev,
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment