Skip to content

Commit

Permalink
[SCSI] zfcp: attach and release SAN nameserver port on demand
Browse files Browse the repository at this point in the history
Changing the zfcp behaviour from always having the nameserver port
open to an on-demand strategy.  This strategy reduces the use of
limited resources like port connections. The patch provides a common
infrastructure which could be used for all WKA ports in future.

Also reduce the number of nameserver lookups by changing the zfcp
behaviour of always querying the nameserver for the corresponding
destination ID of the remote port.  If the destination ID has changed
during the reopen process we will be informed and then trigger a
nameserver query on demand.

Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
Swen Schillig authored and James Bottomley committed Oct 3, 2008
1 parent 44cc76f commit 5ab944f
Show file tree
Hide file tree
Showing 8 changed files with 362 additions and 275 deletions.
65 changes: 7 additions & 58 deletions drivers/s390/scsi/zfcp_aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,19 +450,6 @@ static void _zfcp_status_read_scheduler(struct work_struct *work)
stat_work));
}

static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter)
{
struct zfcp_port *port;

port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA,
ZFCP_DID_DIRECTORY_SERVICE);
if (IS_ERR(port))
return PTR_ERR(port);
zfcp_port_put(port);

return 0;
}

/**
* zfcp_adapter_enqueue - enqueue a new adapter to the list
* @ccw_device: pointer to the struct cc_device
Expand Down Expand Up @@ -552,7 +539,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)

zfcp_data.adapters++;

zfcp_nameserver_enqueue(adapter);
zfcp_fc_nameserver_init(adapter);

return 0;

Expand Down Expand Up @@ -638,7 +625,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
{
struct zfcp_port *port;
int retval;
char *bus_id;

port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
if (!port)
Expand All @@ -648,6 +634,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,

INIT_LIST_HEAD(&port->unit_list_head);
INIT_LIST_HEAD(&port->unit_remove_lh);
INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup);

port->adapter = adapter;
port->d_id = d_id;
Expand All @@ -657,34 +644,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
atomic_set(&port->refcount, 0);

if (status & ZFCP_STATUS_PORT_WKA) {
switch (d_id) {
case ZFCP_DID_DIRECTORY_SERVICE:
bus_id = "directory";
break;
case ZFCP_DID_MANAGEMENT_SERVICE:
bus_id = "management";
break;
case ZFCP_DID_KEY_DISTRIBUTION_SERVICE:
bus_id = "key_distribution";
break;
case ZFCP_DID_ALIAS_SERVICE:
bus_id = "alias";
break;
case ZFCP_DID_TIME_SERVICE:
bus_id = "time";
break;
default:
kfree(port);
return ERR_PTR(-EINVAL);
}
snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "%s", bus_id);
port->sysfs_device.parent = &adapter->generic_services;
} else {
snprintf(port->sysfs_device.bus_id,
BUS_ID_SIZE, "0x%016llx", wwpn);
port->sysfs_device.parent = &adapter->ccw_device->dev;
}
snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", wwpn);
port->sysfs_device.parent = &adapter->ccw_device->dev;

port->sysfs_device.release = zfcp_sysfs_port_release;
dev_set_drvdata(&port->sysfs_device, port);
Expand All @@ -700,12 +661,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
if (device_register(&port->sysfs_device))
goto err_out_free;

if (status & ZFCP_STATUS_PORT_WKA)
retval = sysfs_create_group(&port->sysfs_device.kobj,
&zfcp_sysfs_ns_port_attrs);
else
retval = sysfs_create_group(&port->sysfs_device.kobj,
&zfcp_sysfs_port_attrs);
retval = sysfs_create_group(&port->sysfs_device.kobj,
&zfcp_sysfs_port_attrs);

if (retval) {
device_unregister(&port->sysfs_device);
Expand All @@ -718,9 +675,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn,
list_add_tail(&port->list, &adapter->port_list_head);
atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
if (d_id == ZFCP_DID_DIRECTORY_SERVICE)
if (!adapter->nameserver_port)
adapter->nameserver_port = port;
adapter->ports++;

write_unlock_irq(&zfcp_data.config_lock);
Expand Down Expand Up @@ -749,12 +703,7 @@ void zfcp_port_dequeue(struct zfcp_port *port)
fc_remote_port_delete(port->rport);
port->rport = NULL;
zfcp_adapter_put(port->adapter);
if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)
sysfs_remove_group(&port->sysfs_device.kobj,
&zfcp_sysfs_ns_port_attrs);
else
sysfs_remove_group(&port->sysfs_device.kobj,
&zfcp_sysfs_port_attrs);
sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
device_unregister(&port->sysfs_device);
}

Expand Down
14 changes: 7 additions & 7 deletions drivers/s390/scsi/zfcp_dbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ static const char *zfcp_rec_dbf_ids[] = {
[75] = "physical port recovery escalation after failed port "
"recovery",
[76] = "port recovery escalation after failed unit recovery",
[77] = "recovery opening nameserver port",
[77] = "",
[78] = "duplicate request id",
[79] = "link down",
[80] = "exclusive read-only unit access unsupported",
Expand Down Expand Up @@ -829,8 +829,8 @@ void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
struct zfcp_port *port = ct->port;
struct zfcp_adapter *adapter = port->adapter;
struct zfcp_wka_port *wka_port = ct->wka_port;
struct zfcp_adapter *adapter = wka_port->adapter;
struct ct_hdr *hdr = sg_virt(ct->req);
struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req;
Expand All @@ -842,7 +842,7 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
r->fsf_reqid = (unsigned long)fsf_req;
r->fsf_seqno = fsf_req->seq_no;
r->s_id = fc_host_port_id(adapter->scsi_host);
r->d_id = port->d_id;
r->d_id = wka_port->d_id;
oct->cmd_req_code = hdr->cmd_rsp_code;
oct->revision = hdr->revision;
oct->gs_type = hdr->gs_type;
Expand All @@ -863,8 +863,8 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
struct zfcp_port *port = ct->port;
struct zfcp_adapter *adapter = port->adapter;
struct zfcp_wka_port *wka_port = ct->wka_port;
struct zfcp_adapter *adapter = wka_port->adapter;
struct ct_hdr *hdr = sg_virt(ct->resp);
struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp;
Expand All @@ -875,7 +875,7 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
r->fsf_reqid = (unsigned long)fsf_req;
r->fsf_seqno = fsf_req->seq_no;
r->s_id = port->d_id;
r->s_id = wka_port->d_id;
r->d_id = fc_host_port_id(adapter->scsi_host);
rct->cmd_rsp_code = hdr->cmd_rsp_code;
rct->revision = hdr->revision;
Expand Down
31 changes: 23 additions & 8 deletions drivers/s390/scsi/zfcp_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ struct zfcp_ls_adisc {
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200

/* FC-PH/FC-GS well-known address identifiers for generic services */
#define ZFCP_DID_WKA 0xFFFFF0
#define ZFCP_DID_MANAGEMENT_SERVICE 0xFFFFFA
#define ZFCP_DID_TIME_SERVICE 0xFFFFFB
#define ZFCP_DID_DIRECTORY_SERVICE 0xFFFFFC
Expand All @@ -264,13 +265,15 @@ struct zfcp_ls_adisc {
#define ZFCP_STATUS_PORT_DID_DID 0x00000002
#define ZFCP_STATUS_PORT_PHYS_CLOSING 0x00000004
#define ZFCP_STATUS_PORT_NO_WWPN 0x00000008
#define ZFCP_STATUS_PORT_NO_SCSI_ID 0x00000010
#define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020

/* for ports with well known addresses */
#define ZFCP_STATUS_PORT_WKA \
(ZFCP_STATUS_PORT_NO_WWPN | \
ZFCP_STATUS_PORT_NO_SCSI_ID)
/* well known address (WKA) port status*/
enum zfcp_wka_status {
ZFCP_WKA_PORT_OFFLINE,
ZFCP_WKA_PORT_CLOSING,
ZFCP_WKA_PORT_OPENING,
ZFCP_WKA_PORT_ONLINE,
};

/* logical unit status */
#define ZFCP_STATUS_UNIT_SHARED 0x00000004
Expand Down Expand Up @@ -340,7 +343,7 @@ typedef void (*zfcp_send_ct_handler_t)(unsigned long);

/**
* struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct
* @port: port where the request is sent to
* @wka_port: port where the request is sent to
* @req: scatter-gather list for request
* @resp: scatter-gather list for response
* @req_count: number of elements in request scatter-gather list
Expand All @@ -352,7 +355,7 @@ typedef void (*zfcp_send_ct_handler_t)(unsigned long);
* @status: used to pass error status to calling function
*/
struct zfcp_send_ct {
struct zfcp_port *port;
struct zfcp_wka_port *wka_port;
struct scatterlist *req;
struct scatterlist *resp;
unsigned int req_count;
Expand Down Expand Up @@ -406,6 +409,17 @@ struct zfcp_send_els {
int status;
};

struct zfcp_wka_port {
struct zfcp_adapter *adapter;
wait_queue_head_t completion_wq;
enum zfcp_wka_status status;
atomic_t refcount;
u32 d_id;
u32 handle;
struct mutex mutex;
struct delayed_work work;
};

struct zfcp_qdio_queue {
struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */
u8 first; /* index of next free bfr
Expand Down Expand Up @@ -496,7 +510,7 @@ struct zfcp_adapter {
actions */
u32 erp_low_mem_count; /* nr of erp actions waiting
for memory */
struct zfcp_port *nameserver_port; /* adapter's nameserver */
struct zfcp_wka_port nsp; /* adapter's nameserver */
debug_info_t *rec_dbf;
debug_info_t *hba_dbf;
debug_info_t *san_dbf; /* debug feature areas */
Expand Down Expand Up @@ -540,6 +554,7 @@ struct zfcp_port {
atomic_t erp_counter;
u32 maxframe_size;
u32 supported_classes;
struct work_struct gid_pn_work;
};

struct zfcp_unit {
Expand Down
Loading

0 comments on commit 5ab944f

Please sign in to comment.