Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -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 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
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);
}

+3 −3
Original line number Diff line number Diff line
@@ -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;

+24 −10
Original line number Diff line number Diff line
@@ -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;
};

+5 −3
Original line number Diff line number Diff line
@@ -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);
+13 −13
Original line number Diff line number Diff line
@@ -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;
Loading