IB SRP initiator patches for kernel 3.12
Subsystems (3)
cover IB SRP initiator patches for kernel 3.12
The purpose of this InfiniBand SRP initiator patch series is as follows:
- Make the SRP initiator driver better suited for use in a H.A. setup. Add fast_io_fail_tmo, dev_loss_tmo and reconnect_delay parameters. With the default values of these parameters failover happens significantly faster. The dev_loss mechanism can be disabled which makes it possible to avoid device removal which is necessary when e.g. using initiator side mirroring.
- Improve performance by making the queue size configurable.
- Make it possible to figure out which SCSI host corresponds to which SRP initiator port by making the SGID (source GID) available in sysfs.
The changes since the previous version of this patch series are as follows (see also http://thread.gmane.org/gmane.linux.drivers.rdma/17058/):
- Split the scsi_transport_srp changes in two patches to make review
easier.
- Added a patch for exporting the SGID via sysfs.
- Included a few fixes for the rport state transition algorithm for
issues discovered while testing this patch series on a larger setup
(initiator with 4 IB ports and target with 8 IB ports or 32 SRP
paths between initiator and target in total).
The individual patches in this series are:
0001-IB-srp-Make-transport-layer-retry-count-configurable.patch 0002-IB-srp-Keep-rport-as-long-as-the-IB-transport-layer.patch 0003-scsi_transport_srp-Add-transport-layer-error-handlin.patch 0004-IB-srp-Use-SRP-transport-layer-error-recovery.patch 0005-IB-srp-Start-timers-if-a-transport-layer-error-occur.patch 0006-scsi_transport_srp-Add-periodic-reconnect-support.patch 0007-IB-srp-Add-periodic-reconnect-functionality.patch 0008-IB-srp-Export-sgid-to-sysfs.patch 0009-IB-srp-Introduce-srp_alloc_req_data.patch 0010-IB-srp-Make-queue-size-configurable.patch
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/10 IB/srp: Make transport layer retry count configurable
From: Vu Pham <vuhuong-VPRAkNaXOzVWk0Htik3J/[email protected]>
Allow the InfiniBand RC retry count to be configured by the user as an option in the target login string. Reducing this retry count allows to reduce the path failover time.
--- Documentation/ABI/stable/sysfs-driver-ib_srp | 2 ++ drivers/infiniband/ulp/srp/ib_srp.c | 24 +++++++++++++++++++++++- drivers/infiniband/ulp/srp/ib_srp.h | 1 + 3 files changed, 26 insertions(+), 1 deletion(-)
Documentation/ABI/stable/sysfs-driver-ib_srp +2 -0
@@ -61,6 +61,8 @@ Description: Interface for making ib_srp connect to a new target. interrupt is handled by a different CPU then the comp_vector parameter can be used to spread the SRP completion workload over multiple CPU's. + * tl_retry_count, a number in the range 2..7 specifying the + IB RC retry count. What: /sys/class/infiniband_srp/srp-<hca>-<port_number>/ibdev Date: January 2, 2006
drivers/infiniband/ulp/srp/ib_srp.c +23 -1
@@ -390,7 +390,7 @@ static int srp_send_req(struct srp_target_port *target) req->param.responder_resources =4 ; req->param.remote_cm_response_timeout =20 ; req->param.local_cm_response_timeout =20 ; - req->param.retry_count =7 ; + req->param.retry_count = target->tl_retry_count; req->param.rnr_retry_count =7 ; req->param.max_cm_retries =15 ;
@@ -1907,6 +1907,14 @@ static ssize_t show_comp_vector(struct device *dev,return sprintf (buf,"%d\n" , target->comp_vector); } +static ssize_t show_tl_retry_count (struct device *dev, +struct device_attribute *attr,char *buf) +{ +struct srp_target_port *target =host_to_target (class_to_shost (dev)); + +return sprintf (buf,"%d\n" , target->tl_retry_count); +} +static ssize_t show_cmd_sg_entries (struct device *dev,struct device_attribute *attr,char *buf) {
@@ -1934,6 +1942,7 @@ static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); static DEVICE_ATTR(comp_vector, S_IRUGO, show_comp_vector, NULL); +static DEVICE_ATTR(tl_retry_count, S_IRUGO, show_tl_retry_count, NULL); static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL); static DEVICE_ATTR(allow_ext_sg, S_IRUGO, show_allow_ext_sg, NULL);
@@ -1949,6 +1958,7 @@ static struct device_attribute *srp_host_attrs[] = { &dev_attr_local_ib_port, &dev_attr_local_ib_device, &dev_attr_comp_vector, + &dev_attr_tl_retry_count, &dev_attr_cmd_sg_entries, &dev_attr_allow_ext_sg,NULL
@@ -2073,6 +2083,7 @@ enum {SRP_OPT_ALLOW_EXT_SG =1 <<10 ,SRP_OPT_SG_TABLESIZE =1 <<11 ,SRP_OPT_COMP_VECTOR =1 <<12 , +SRP_OPT_TL_RETRY_COUNT =1 <<13 , SRP_OPT_ALL = (SRP_OPT_ID_EXT | SRP_OPT_IOC_GUID | SRP_OPT_DGID |
@@ -2094,6 +2105,7 @@ static const match_table_t srp_opt_tokens = { { SRP_OPT_ALLOW_EXT_SG, "allow_ext_sg=%u" }, { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" }, { SRP_OPT_COMP_VECTOR, "comp_vector=%u" }, + { SRP_OPT_TL_RETRY_COUNT, "tl_retry_count=%u" }, { SRP_OPT_ERR, NULL } };
@@ -2257,6 +2269,15 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) target->comp_vector = token;break ; +case SRP_OPT_TL_RETRY_COUNT : +if (match_int (args, &token) || token <2 || token >7 ) { +pr_warn ("bad tl_retry_count parameter '%s' (must be a number between 2 and 7)\n" , + p); + goto out; + } + target->tl_retry_count = token; +break ; +default :pr_warn ("unknown parameter or missing value '%s' in target creation request\n" , p);
@@ -2311,6 +2332,7 @@ static ssize_t srp_create_target(struct device *dev, target->cmd_sg_cnt = cmd_sg_entries; target->sg_tablesize = indirect_sg_entries ? : cmd_sg_entries; target->allow_ext_sg = allow_ext_sg; + target->tl_retry_count =7 ; ret =srp_parse_options (buf, target);if (ret)
drivers/infiniband/ulp/srp/ib_srp.h +1 -0
@@ -157,6 +157,7 @@ struct srp_target_port {unsigned int scsi_id;unsigned int sg_tablesize;int comp_vector; +int tl_retry_count;struct ib_sa_path_rec path;__be16 orig_dgid[8 ];
Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/10 scsi_transport_srp: Add transport layer error handling
In reply to a message not in the archiveAdd the necessary functions in the SRP transport module to allow an SRP initiator driver to implement transport layer error handling similar to the functionality already provided by the FC transport layer. This includes:
- Support for implementing fast_io_fail_tmo, the time that should elapse after having detected a transport layer problem and before failing I/O.
- Support for implementing dev_loss_tmo, the time that should elapse after having detected a transport layer problem and before removing a remote port.
--- Documentation/ABI/stable/sysfs-transport-srp | 31 ++ drivers/scsi/scsi_transport_srp.c | 429 ++++++++++++++++++++++++++- include/scsi/scsi_transport_srp.h | 74 ++++- 3 files changed, 531 insertions(+), 3 deletions(-)
Documentation/ABI/stable/sysfs-transport-srp +31 -0
@@ -5,6 +5,24 @@ Contact: [email protected], [email protected] Description: Instructs an SRP initiator to disconnect from a target and to remove all LUNs imported from that target. +What: /sys/class/srp_remote_ports/port-<h>:<n>/dev_loss_tmo +Date: December 1, 2013 +KernelVersion: 3.12 +Contact: [email protected], [email protected] +Description: Number of seconds the SCSI layer will wait after a transport + layer error has been observed before removing a target port. + Zero means immediate removal. Setting this attribute to "off" + will disable the dev_loss timer. + +What: /sys/class/srp_remote_ports/port-<h>:<n>/fast_io_fail_tmo +Date: December 1, 2013 +KernelVersion: 3.12 +Contact: [email protected], [email protected] +Description: Number of seconds the SCSI layer will wait after a transport + layer error has been observed before failing I/O. Zero means + failing I/O immediately. Setting this attribute to "off" will + disable the fast_io_fail timer. + What: /sys/class/srp_remote_ports/port-<h>:<n>/port_id Date: June 27, 2007 KernelVersion: 2.6.24
@@ -17,3 +35,16 @@ Date: June 27, 2007 KernelVersion: 2.6.24 Contact: [email protected] Description: Role of the remote port. Either "SRP Initiator" or "SRP Target". + +What: /sys/class/srp_remote_ports/port-<h>:<n>/state +Date: December 1, 2013 +KernelVersion: 3.12 +Contact: [email protected], [email protected] +Description: State of the transport layer used for communication with the + remote port. "running" if the transport layer is operational; + "blocked" if a transport layer error has been encountered but + the fail_io_fast_tmo timer has not yet fired; "fail-fast" + after the fail_io_fast_tmo timer has fired and before the + "dev_loss_tmo" timer has fired; "lost" after the + "dev_loss_tmo" timer has fired and before the port is finally + removed.
drivers/scsi/scsi_transport_srp.c +428 -1
499 lines not on this page · raw message
include/scsi/scsi_transport_srp.h +72 -2
96 lines not on this page · raw message
Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 03/10] scsi_transport_srp: Add transport layer error handling
Quoted 10 lines · Bart Van Assche
Add the necessary functions in the SRP transport module to allow an SRP initiator driver to implement transport layer error handling similar to the functionality already provided by the FC transport layer. This includes:
- Support for implementingfast_io_fail_tmo, the time that should elapse after having detected a transport layer problem and before failing I/O.
- Support for implementingdev_loss_tmo, the time that should elapse after having detected a transport layer problem and before removing a remote port.
[ ... ]
(replying to my own e-mail)
Since it takes some work to figure out the state transitions from the source code, I have tried to draw a diagram representing all state transitions. I have attached that diagram to this e-mail. That diagram probably will make it easier to review this code.
Bart.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 03/10] scsi_transport_srp: Add transport layer error handling
Quoted 4 lines · Bart Van Assche
Since it takes some work to figure out the state transitions from the source code, I have tried to draw a diagram representing all state transitions. I have attached that diagram to this e-mail. That diagram probably will make it easier to review this code.
This is handy, Bart -- could you put it in a patch? I suppose it belongs under Documentation/infiniband...
Thanks!
Signature · 9 lines
Dave Dillow National Center for Computational Science Oak Ridge National Laboratory (865) 241-6602 office -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Bart Van Assche
maintainerRe: [PATCH 03/10] scsi_transport_srp: Add transport layer error handling
Quoted 8 lines · David Dillow
Quoted 4 lines · Bart Van Assche
Since it takes some work to figure out the state transitions from the source code, I have tried to draw a diagram representing all state transitions. I have attached that diagram to this e-mail. That diagram probably will make it easier to review this code.
This is handy, Bart -- could you put it in a patch? I suppose it belongs under
Documentation/infiniband...
Hello Dave,
That sounds like a good idea to me. I will post such a patch as soon as possible - the coming two weeks I will be traveling.
Bart.
PATCH 4/10 IB/srp: Use SRP transport layer error recovery
In reply to a message not in the archiveEnable fast_io_fail_tmo and dev_loss_tmo functionality for the IB SRP initiator. Add kernel module parameters that allow to specify default values for these parameters.
--- drivers/infiniband/ulp/srp/ib_srp.c | 141 ++++++++++++++++++++++++++---------- drivers/infiniband/ulp/srp/ib_srp.h | 1 - 2 files changed, 101 insertions(+), 41 deletions(-)
drivers/infiniband/ulp/srp/ib_srp.c +101 -40
@@ -86,6 +86,27 @@ module_param(topspin_workarounds, int, 0444);MODULE_PARM_DESC (topspin_workarounds,"Enable workarounds for Topspin/Cisco SRP target bugs if != 0" ); +static struct kernel_param_ops srp_tmo_ops; + +static int srp_fast_io_fail_tmo =15 ; +module_param_cb (fast_io_fail_tmo, &srp_tmo_ops, &srp_fast_io_fail_tmo, +S_IRUGO |S_IWUSR ); +MODULE_PARM_DESC (fast_io_fail_tmo, +"Number of seconds between the observation of a transport" +" layer error and failing all I/O. \"off\" means that this" +" functionality is disabled." ); + +static int srp_dev_loss_tmo =60 ; +module_param_cb (dev_loss_tmo, &srp_tmo_ops, &srp_dev_loss_tmo, +S_IRUGO |S_IWUSR ); +MODULE_PARM_DESC (dev_loss_tmo, + "Maximum number of seconds that the SRP transport should" + " insulate transport layer errors. After this time has been" + " exceeded the SCSI host is removed. Should be" + " between 1 and " __stringify(SCSI_DEVICE_BLOCK_MAX_TIMEOUT) +" if fast_io_fail_tmo has not been set. \"off\" means that" +" this functionality is disabled." ); +static void srp_add_one (struct ib_device *device);static void srp_remove_one (struct ib_device *device);static void srp_recv_completion (struct ib_cq *cq,void *target_ptr);
@@ -102,6 +123,44 @@ static struct ib_client srp_client = {static struct ib_sa_client srp_sa_client; +static int srp_tmo_get (char *buffer,const struct kernel_param *kp) +{ +int tmo = *(int *)kp->arg; + +if (tmo >=0 ) +return sprintf (buffer,"%d" , tmo); +else +return sprintf (buffer,"off" ); +} + +static int srp_tmo_set (const char *val,const struct kernel_param *kp) +{ +int tmo, res; + +if (strncmp (val,"off" ,3 ) !=0 ) { + res =kstrtoint (val,0 , &tmo); +if (res) + goto out; + }else { + tmo =-1 ; + } +if (kp->arg == &srp_fast_io_fail_tmo) + res =srp_tmo_valid (tmo, srp_dev_loss_tmo); +else + res =srp_tmo_valid (srp_fast_io_fail_tmo, tmo); +if (res) + goto out; + *(int *)kp->arg = tmo; + +out: +return res; +} + +static struct kernel_param_ops srp_tmo_ops = { + .get = srp_tmo_get, + .set = srp_tmo_set, +}; +static inline struct srp_target_port *host_to_target (struct Scsi_Host *host) {return (struct srp_target_port *) host->hostdata;
@@ -689,23 +748,42 @@ static void srp_free_req(struct srp_target_port *target,spin_unlock_irqrestore (&target->lock, flags); } -static void srp_reset_req (struct srp_target_port *target,struct srp_request *req) +static void srp_finish_req (struct srp_target_port *target, +struct srp_request *req,int result) {struct scsi_cmnd *scmnd =srp_claim_req (target, req,NULL );if (scmnd) {srp_free_req (target, req, scmnd,0 ); - scmnd->result =DID_RESET <<16 ; + scmnd->result = result; scmnd->scsi_done (scmnd); } } -static int srp_reconnect_target (struct srp_target_port *target) +static void srp_terminate_io (struct srp_rport *rport) { -struct Scsi_Host *shost = target->scsi_host; -int i, ret; +struct srp_target_port *target = rport->lld_data; +int i; + +for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { +struct srp_request *req = &target->req_ring[i]; +srp_finish_req (target, req,DID_TRANSPORT_FAILFAST <<16 ); + } +} -scsi_target_block (&shost->shost_gendev); +/* +* It is up to the caller to ensure that srp_rport_reconnect() calls are +* serialized and that no concurrent srp_queuecommand(), srp_abort(), +* srp_reset_device() or srp_reset_host() calls will occur while this function +* is in progress. One way to realize that is not to call this function +* directly but to call srp_reconnect_rport() instead since that last function +* serializes calls of this function via rport->mutex and also blocks +* srp_queuecommand() calls before invoking this function. +*/ +static int srp_rport_reconnect (struct srp_rport *rport) +{ +struct srp_target_port *target = rport->lld_data; +int i, ret;srp_disconnect_target (target);/*
@@ -726,8 +804,7 @@ static int srp_reconnect_target(struct srp_target_port *target)for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) {struct srp_request *req = &target->req_ring[i]; -if (req->scmnd) -srp_reset_req (target, req); +srp_finish_req (target, req,DID_RESET <<16 ); }INIT_LIST_HEAD (&target->free_tx);
@@ -737,28 +814,9 @@ static int srp_reconnect_target(struct srp_target_port *target)if (ret ==0 ) ret =srp_connect_target (target); -scsi_target_unblock (&shost->shost_gendev, ret ==0 ?SDEV_RUNNING : -SDEV_TRANSPORT_OFFLINE ); - target->transport_offline = !!ret; - -if (ret) - goto err; - -shost_printk (KERN_INFO , target->scsi_host,PFX "reconnect succeeded\n" ); - -return ret; - -err: -shost_printk (KERN_ERR , target->scsi_host, -PFX "reconnect failed (%d), removing target port.\n" , ret); - -/* -* We couldn't reconnect, so kill our target port off. -* However, we have to defer the real removal because we -* are in the context of the SCSI error handler now, which -* will deadlock if we call scsi_remove_host(). -*/ -srp_queue_remove_work (target); +if (ret ==0 ) +shost_printk (KERN_INFO , target->scsi_host, +PFX "reconnect succeeded\n" );return ret; }
@@ -1356,10 +1414,11 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)struct srp_cmd *cmd;struct ib_device *dev;unsigned long flags; -int len; +int len, result; -if (unlikely (target->transport_offline)) { - scmnd->result =DID_NO_CONNECT <<16 ; + result =srp_chkready (target->rport); +if (unlikely (result)) { + scmnd->result = result; scmnd->scsi_done (scmnd);return 0 ; }
@@ -1757,7 +1816,7 @@ static int srp_abort(struct scsi_cmnd *scmnd)if (srp_send_tsk_mgmt (target, req->index, scmnd->device->lun,SRP_TSK_ABORT_TASK ) ==0 ) ret =SUCCESS ; -else if (target->transport_offline) +else if (target->rport->state ==SRP_RPORT_LOST ) ret =FAST_IO_FAIL ;else ret =FAILED ;
@@ -1784,7 +1843,7 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) {struct srp_request *req = &target->req_ring[i];if (req->scmnd && req->scmnd->device == scmnd->device) -srp_reset_req (target, req); +srp_finish_req (target, req,DID_RESET <<16 ); }return SUCCESS ;
@@ -1793,14 +1852,10 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)static int srp_reset_host (struct scsi_cmnd *scmnd) {struct srp_target_port *target =host_to_target (scmnd->device->host); -int ret =FAILED ;shost_printk (KERN_ERR , target->scsi_host,PFX "SRP reset_host called\n" ); -if (!srp_reconnect_target (target)) - ret =SUCCESS ; - -return ret; +return srp_reconnect_rport (target->rport) ==0 ?SUCCESS :FAILED ; }static int srp_slave_configure (struct scsi_device *sdev)
@@ -2637,7 +2692,13 @@ static void srp_remove_one(struct ib_device *device) }static struct srp_function_template ib_srp_transport_functions = { + .has_rport_state = true, + .reset_timer_if_blocked = true, + .fast_io_fail_tmo = &srp_fast_io_fail_tmo, + .dev_loss_tmo = &srp_dev_loss_tmo, + .reconnect = srp_rport_reconnect, .rport_delete = srp_rport_delete, + .terminate_rport_io = srp_terminate_io, };static int __init srp_init_module (void )
drivers/infiniband/ulp/srp/ib_srp.h +0 -1
@@ -140,7 +140,6 @@ struct srp_target_port {unsigned int cmd_sg_cnt;unsigned int indirect_size;bool allow_ext_sg; -bool transport_offline;/* Everything above this point is used in the hot path of * command processing. Try to keep them packed into cachelines.
Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/10 IB/srp: Start timers if a transport layer error occurs
In reply to a message not in the archiveStart the reconnect timer, fast_io_fail timer and dev_loss timers if a transport layer error occurs.
--- drivers/infiniband/ulp/srp/ib_srp.c | 19 +++++++++++++++++++ drivers/infiniband/ulp/srp/ib_srp.h | 1 + 2 files changed, 20 insertions(+)
drivers/infiniband/ulp/srp/ib_srp.c +19 -0
@@ -593,6 +593,7 @@ static void srp_remove_target(struct srp_target_port *target)srp_disconnect_target (target);ib_destroy_cm_id (target->cm_id);srp_free_target_ib (target); +cancel_work_sync (&target->tl_err_work);srp_rport_put (target->rport);srp_free_req_data (target);
@@ -1363,6 +1364,21 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) PFX "Recv failed with error code %d\n", res); } +/** +* srp_tl_err_work() - handle a transport layer error +* +* Note: This function may get invoked before the rport has been created, +* hence the target->rport test. +*/ +static void srp_tl_err_work (struct work_struct *work) +{ +struct srp_target_port *target; + + target = container_of(work, struct srp_target_port, tl_err_work); +if (target->rport) +srp_start_tl_fail_timers (target->rport); +} +static void srp_handle_qp_err (enum ib_wc_status wc_status,bool send_err,struct srp_target_port *target) {
@@ -1371,6 +1387,7 @@ static void srp_handle_qp_err(enum ib_wc_status wc_status, bool send_err,PFX "failed %s status %d\n" , send_err ?"send" :"receive" , wc_status); +queue_work (system_long_wq, &target->tl_err_work); } target->qp_in_error = true; }
@@ -1733,6 +1750,7 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)if (ib_send_cm_drep (cm_id,NULL ,0 ))shost_printk (KERN_ERR , target->scsi_host,PFX "Sending CM DREP failed\n" ); +queue_work (system_long_wq, &target->tl_err_work);break ;case IB_CM_TIMEWAIT_EXIT :
@@ -2419,6 +2437,7 @@ static ssize_t srp_create_target(struct device *dev,sizeof (struct srp_indirect_buf ) + target->cmd_sg_cnt *sizeof (struct srp_direct_buf ); +INIT_WORK (&target->tl_err_work, srp_tl_err_work);INIT_WORK (&target->remove_work, srp_remove_work);spin_lock_init (&target->lock);INIT_LIST_HEAD (&target->free_tx);
drivers/infiniband/ulp/srp/ib_srp.h +1 -0
@@ -177,6 +177,7 @@ struct srp_target_port {struct srp_iu *rx_ring[SRP_RQ_SIZE ];struct srp_request req_ring[SRP_CMD_SQ_SIZE ]; +struct work_struct tl_err_work;struct work_struct remove_work;struct list_head list;
Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/10 scsi_transport_srp: Add periodic reconnect support
In reply to a message not in the archiveAdd support for periodically reconnecting to an SRP target until the dev_loss timer expires. After the tenth reconnection attempt, gradually slow down subsequent reconnect attempts.
--- drivers/scsi/scsi_transport_srp.c | 106 +++++++++++++++++++++++++++++++++++--- include/scsi/scsi_transport_srp.h | 11 +++- 2 files changed, 108 insertions(+), 9 deletions(-)
drivers/scsi/scsi_transport_srp.c +99 -7
@@ -41,7 +41,7 @@ struct srp_host_attrs {#define to_srp_host_attrs (host) ((struct srp_host_attrs *)(host)->shost_data)#define SRP_HOST_ATTRS 0 -#define SRP_RPORT_ATTRS 6 +#define SRP_RPORT_ATTRS 8struct srp_internal {struct scsi_transport_template t;
@@ -69,11 +69,13 @@ static inline struct Scsi_Host *rport_to_shost(struct srp_rport *r)* are finished in a reasonable time. Hence do not allow the fast I/O fail * timeout to exceed SCSI_DEVICE_BLOCK_MAX_TIMEOUT. Furthermore, these * parameters must be such that multipath can detect failed paths timely. -* Hence do not allow both parameters to be disabled simultaneously. +* Hence do not allow all three parameters to be disabled simultaneously. */ -int srp_tmo_valid (int fast_io_fail_tmo,int dev_loss_tmo) +int srp_tmo_valid (int reconnect_delay,int fast_io_fail_tmo,int dev_loss_tmo) { -if (fast_io_fail_tmo <0 && dev_loss_tmo <0 ) +if (reconnect_delay <0 && fast_io_fail_tmo <0 && dev_loss_tmo <0 ) +return -EINVAL ; +if (reconnect_delay ==0 )return -EINVAL ;if (fast_io_fail_tmo >SCSI_DEVICE_BLOCK_MAX_TIMEOUT )return -EINVAL ;
@@ -202,6 +204,56 @@ static int srp_parse_tmo(int *tmo, const char *buf)return res; } +static ssize_t show_reconnect_delay (struct device *dev, +struct device_attribute *attr,char *buf) +{ +struct srp_rport *rport =transport_class_to_srp_rport (dev); + +return srp_show_tmo (buf, rport->reconnect_delay); +} + +static ssize_t store_reconnect_delay (struct device *dev, +struct device_attribute *attr, +const char *buf,const size_t count) +{ +struct srp_rport *rport =transport_class_to_srp_rport (dev); +int res, delay; + + res =srp_parse_tmo (&delay, buf); +if (res) + goto out; + res =srp_tmo_valid (delay, rport->fast_io_fail_tmo, + rport->dev_loss_tmo); +if (res) + goto out; + +if (rport->reconnect_delay <=0 && delay >0 && + rport->state !=SRP_RPORT_RUNNING ) { +queue_delayed_work (system_long_wq, &rport->reconnect_work, + delay *HZ ); + }else if (delay <=0 ) { +cancel_delayed_work (&rport->reconnect_work); + } + rport->reconnect_delay = delay; + res = count; + +out: +return res; +} + +static DEVICE_ATTR(reconnect_delay, S_IRUGO | S_IWUSR, show_reconnect_delay, + store_reconnect_delay); + +static ssize_t show_failed_reconnects (struct device *dev, +struct device_attribute *attr,char *buf) +{ +struct srp_rport *rport =transport_class_to_srp_rport (dev); + +return sprintf (buf,"%d\n" , rport->failed_reconnects); +} + +static DEVICE_ATTR(failed_reconnects, S_IRUGO, show_failed_reconnects, NULL); +static ssize_t show_srp_rport_fast_io_fail_tmo (struct device *dev,struct device_attribute *attr,char *buf)
@@ -222,7 +274,8 @@ static ssize_t store_srp_rport_fast_io_fail_tmo(struct device *dev, res =srp_parse_tmo (&fast_io_fail_tmo, buf);if (res) goto out; - res =srp_tmo_valid (fast_io_fail_tmo, rport->dev_loss_tmo); + res =srp_tmo_valid (rport->reconnect_delay, fast_io_fail_tmo, + rport->dev_loss_tmo);if (res) goto out; rport->fast_io_fail_tmo = fast_io_fail_tmo;
@@ -256,7 +309,8 @@ static ssize_t store_srp_rport_dev_loss_tmo(struct device *dev, res =srp_parse_tmo (&dev_loss_tmo, buf);if (res) goto out; - res =srp_tmo_valid (rport->fast_io_fail_tmo, dev_loss_tmo); + res =srp_tmo_valid (rport->reconnect_delay, rport->fast_io_fail_tmo, + dev_loss_tmo);if (res) goto out; rport->dev_loss_tmo = dev_loss_tmo;
@@ -312,6 +366,29 @@ invalid:return -EINVAL ; } +/** +* srp_reconnect_work() - reconnect and schedule a new attempt if necessary +*/ +static void srp_reconnect_work (struct work_struct *work) +{ +struct srp_rport *rport =container_of (to_delayed_work (work), + struct srp_rport, reconnect_work); +struct Scsi_Host *shost =rport_to_shost (rport); +int delay, res; + + res =srp_reconnect_rport (rport); +if (res !=0 ) { +shost_printk (KERN_ERR , shost, +"reconnect attempt %d failed (%d)\n" , + ++rport->failed_reconnects, res); + delay = rport->reconnect_delay * +min (100 ,max (1 , rport->failed_reconnects -10 )); +if (delay >0 ) +queue_delayed_work (system_long_wq, + &rport->reconnect_work, delay *HZ ); + } +} +static void __rport_fail_io_fast (struct srp_rport *rport) {struct Scsi_Host *shost =rport_to_shost (rport);
@@ -370,16 +447,21 @@ static void rport_dev_loss_timedout(struct work_struct *work)static void __srp_start_tl_fail_timers (struct srp_rport *rport) {struct Scsi_Host *shost =rport_to_shost (rport); -int fast_io_fail_tmo, dev_loss_tmo; +int delay, fast_io_fail_tmo, dev_loss_tmo;lockdep_assert_held (&rport->mutex);if (!rport->deleted) { + delay = rport->reconnect_delay; fast_io_fail_tmo = rport->fast_io_fail_tmo; dev_loss_tmo = rport->dev_loss_tmo;pr_debug ("%s current state: %d\n" ,dev_name (&shost->shost_gendev), rport->state); +if (delay >0 ) +queue_delayed_work (system_long_wq, + &rport->reconnect_work, +1UL * delay *HZ );if (fast_io_fail_tmo >=0 &&srp_rport_set_state (rport,SRP_RPORT_BLOCKED ) ==0 ) { pr_debug("%s new state: %d\n",
@@ -480,6 +562,7 @@ int srp_reconnect_rport(struct srp_rport *rport)cancel_delayed_work (&rport->fast_io_fail_work);cancel_delayed_work (&rport->dev_loss_work); + rport->failed_reconnects =0 ;srp_rport_set_state (rport,SRP_RPORT_RUNNING );scsi_target_unblock (&shost->shost_gendev,SDEV_RUNNING );/*
@@ -538,6 +621,7 @@ static void srp_rport_release(struct device *dev) {struct srp_rport *rport =dev_to_rport (dev); +cancel_delayed_work_sync (&rport->reconnect_work);cancel_delayed_work_sync (&rport->fast_io_fail_work);cancel_delayed_work_sync (&rport->dev_loss_work);
@@ -634,6 +718,10 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost,memcpy (rport->port_id, ids->port_id,sizeof (rport->port_id)); rport->roles = ids->roles; +if (i->f->reconnect) + rport->reconnect_delay = i->f->reconnect_delay ? + *i->f->reconnect_delay :10 ; +INIT_DELAYED_WORK (&rport->reconnect_work, srp_reconnect_work); rport->fast_io_fail_tmo = i->f->fast_io_fail_tmo ? *i->f->fast_io_fail_tmo :15 ; rport->dev_loss_tmo = i->f->dev_loss_tmo ? *i->f->dev_loss_tmo :60 ;
@@ -772,6 +860,10 @@ srp_attach_transport(struct srp_function_template *ft) i->rport_attrs[count++] = &dev_attr_fast_io_fail_tmo; i->rport_attrs[count++] = &dev_attr_dev_loss_tmo; } +if (ft->reconnect) { + i->rport_attrs[count++] = &dev_attr_reconnect_delay; + i->rport_attrs[count++] = &dev_attr_failed_reconnects; + }if (ft->rport_delete) i->rport_attrs[count++] = &dev_attr_delete; i->rport_attrs[count++] =NULL ;
include/scsi/scsi_transport_srp.h +9 -2
@@ -31,7 +31,8 @@ enum srp_rport_state {/** * struct srp_rport * @lld_data: LLD private data. -* @mutex: Protects against concurrent rport fast_io_fail / dev_loss_tmo. +* @mutex: Protects against concurrent rport reconnect / fast_io_fail / +* dev_loss_tmo activity. */ struct srp_rport {/* for initiator and target drivers */
@@ -48,6 +49,9 @@ struct srp_rport {struct mutex mutex;enum srp_rport_state state;bool deleted; +int reconnect_delay; +int failed_reconnects; +struct delayed_work reconnect_work;int fast_io_fail_tmo;int dev_loss_tmo;struct delayed_work fast_io_fail_work;
@@ -60,6 +64,7 @@ struct srp_rport {* dev_loss_tmo sysfs attribute for an rport. * @reset_timer_if_blocked: Whether or srp_timed_out() should reset the command * timer if the device on which it has been queued is blocked. +* @reconnect_delay: If not NULL, points to the default reconnect_delay value. * @fast_io_fail_tmo: If not NULL, points to the default fast_io_fail_tmo value. * @dev_loss_tmo: If not NULL, points to the default dev_loss_tmo value. * @reconnect: Callback function for reconnecting to the target. See also
@@ -71,6 +76,7 @@ struct srp_function_template {/* for initiator drivers */ bool has_rport_state;bool reset_timer_if_blocked; +int *reconnect_delay;int *fast_io_fail_tmo;int *dev_loss_tmo;int (*reconnect)(struct srp_rport *rport);
@@ -90,7 +96,8 @@ extern void srp_rport_put(struct srp_rport *rport);extern struct srp_rport *srp_rport_add (struct Scsi_Host *,struct srp_rport_identifiers *);extern void srp_rport_del (struct srp_rport *); -extern int srp_tmo_valid (int fast_io_fail_tmo,int dev_loss_tmo); +extern int srp_tmo_valid (int reconnect_delay,int fast_io_fail_tmo, +int dev_loss_tmo);extern int srp_reconnect_rport (struct srp_rport *rport);extern void srp_start_tl_fail_timers (struct srp_rport *rport);extern void srp_remove_host (struct Scsi_Host *);
Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 7/10 IB/srp: Add periodic reconnect functionality
In reply to a message not in the archiveAfter a transport layer occurred, periodically try to reconnect to the target until the dev_loss timer expires. Protect the callback functions that can be invoked from inside the SCSI EH against concurrent invocation with srp_reconnect_rport() via the rport mutex. Change the default dev_loss_tmo from 60s into 600s to give the reconnect mechanism a chance to kick in.
--- Documentation/ABI/stable/sysfs-transport-srp | 8 +++++ drivers/infiniband/ulp/srp/ib_srp.c | 52 ++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 6 deletions(-)
Documentation/ABI/stable/sysfs-transport-srp +8 -0
@@ -30,6 +30,14 @@ Contact: [email protected] Description: 16-byte local SRP port identifier in hexadecimal format. An example: 4c:49:4e:55:58:20:56:49:4f:00:00:00:00:00:00:00. +What: /sys/class/srp_remote_ports/port-<h>:<n>/reconnect_delay +Date: December 1, 2013 +KernelVersion: 3.12 +Contact: [email protected], [email protected] +Description: Number of seconds the SCSI layer will wait after a reconnect + attempt failed before retrying. Setting this attribute to + "off" will disable time-based reconnecting. + What: /sys/class/srp_remote_ports/port-<h>:<n>/roles Date: June 27, 2007 KernelVersion: 2.6.24
drivers/infiniband/ulp/srp/ib_srp.c +46 -6
131 lines not on this page · raw message
Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 8/10 IB/srp: Export sgid to sysfs
In reply to a message not in the archiveOn an initiator system with multiple IB ports it is not yet possible to figure out what the originating port of an SRP connection is. Hence make the source GID available in sysfs.
--- Documentation/ABI/stable/sysfs-driver-ib_srp | 7 +++++++ drivers/infiniband/ulp/srp/ib_srp.c | 10 ++++++++++ 2 files changed, 17 insertions(+)
Documentation/ABI/stable/sysfs-driver-ib_srp +7 -0
@@ -155,6 +155,13 @@ Contact: [email protected] Description: InfiniBand service ID used for establishing communication with the SRP target. +What: /sys/class/scsi_host/host<n>/sgid +Date: December 1, 2013 +KernelVersion: 3.12 +Contact: [email protected] +Description: InfiniBand GID of the source port used for communication with + the SRP target. + What: /sys/class/scsi_host/host<n>/zero_req_lim Date: September 20, 2006 KernelVersion: 2.6.18
drivers/infiniband/ulp/srp/ib_srp.c +10 -0
@@ -1965,6 +1965,14 @@ static ssize_t show_pkey(struct device *dev, struct device_attribute *attr,return sprintf (buf,"0x%04x\n" ,be16_to_cpu (target->path.pkey)); } +static ssize_t show_sgid (struct device *dev,struct device_attribute *attr, +char *buf) +{ +struct srp_target_port *target =host_to_target (class_to_shost (dev)); + +return sprintf (buf,"%pI6\n" , target->path.sgid.raw); +} +static ssize_t show_dgid (struct device *dev,struct device_attribute *attr,char *buf) {
@@ -2049,6 +2057,7 @@ static DEVICE_ATTR(id_ext, S_IRUGO, show_id_ext, NULL); static DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); static DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); +static DEVICE_ATTR(sgid, S_IRUGO, show_sgid, NULL); static DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL); static DEVICE_ATTR(orig_dgid, S_IRUGO, show_orig_dgid, NULL); static DEVICE_ATTR(req_lim, S_IRUGO, show_req_lim, NULL);
@@ -2065,6 +2074,7 @@ static struct device_attribute *srp_host_attrs[] = { &dev_attr_ioc_guid, &dev_attr_service_id, &dev_attr_pkey, + &dev_attr_sgid, &dev_attr_dgid, &dev_attr_orig_dgid, &dev_attr_req_lim,
Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 9/10 IB/srp: Introduce srp_alloc_req_data()
In reply to a message not in the archiveThis patch does not change any functionality.
--- drivers/infiniband/ulp/srp/ib_srp.c | 64 +++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 24 deletions(-)
drivers/infiniband/ulp/srp/ib_srp.c +40 -24
@@ -576,6 +576,42 @@ static void srp_free_req_data(struct srp_target_port *target) } } +static int srp_alloc_req_data (struct srp_target_port *target) +{ +struct srp_device *srp_dev = target->srp_host->srp_dev; +struct ib_device *ibdev = srp_dev->dev; +struct srp_request *req; +dma_addr_t dma_addr; +int i, ret = -ENOMEM ; + +INIT_LIST_HEAD (&target->free_reqs); + +for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { + req = &target->req_ring[i]; + req->fmr_list =kmalloc (target->cmd_sg_cnt *sizeof (void *), +GFP_KERNEL ); + req->map_page =kmalloc (SRP_FMR_SIZE *sizeof (void *), +GFP_KERNEL ); + req->indirect_desc =kmalloc (target->indirect_size,GFP_KERNEL ); +if (!req->fmr_list || !req->map_page || !req->indirect_desc) + goto out; + + dma_addr =ib_dma_map_single (ibdev, req->indirect_desc, + target->indirect_size, +DMA_TO_DEVICE ); +if (ib_dma_mapping_error (ibdev, dma_addr)) + goto out; + + req->indirect_dma_addr = dma_addr; + req->index = i; +list_add_tail (&req->list, &target->free_reqs); + } + ret =0 ; + +out: +return ret; +} +/** * srp_del_scsi_host_attr() - Remove attributes defined in the host template. * @shost: SCSI host whose attributes to remove from sysfs.
@@ -2433,8 +2469,7 @@ static ssize_t srp_create_target(struct device *dev,struct Scsi_Host *target_host;struct srp_target_port *target;struct ib_device *ibdev = host->srp_dev->dev; -dma_addr_t dma_addr; -int i, ret; +int ret; target_host =scsi_host_alloc (&srp_template,sizeof (struct srp_target_port ));
@@ -2490,28 +2525,9 @@ static ssize_t srp_create_target(struct device *dev,INIT_WORK (&target->remove_work, srp_remove_work);spin_lock_init (&target->lock);INIT_LIST_HEAD (&target->free_tx); -INIT_LIST_HEAD (&target->free_reqs); -for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { -struct srp_request *req = &target->req_ring[i]; - - req->fmr_list =kmalloc (target->cmd_sg_cnt *sizeof (void *), -GFP_KERNEL ); - req->map_page =kmalloc (SRP_FMR_SIZE *sizeof (void *), -GFP_KERNEL ); - req->indirect_desc =kmalloc (target->indirect_size,GFP_KERNEL ); -if (!req->fmr_list || !req->map_page || !req->indirect_desc) - goto err_free_mem; - - dma_addr =ib_dma_map_single (ibdev, req->indirect_desc, - target->indirect_size, -DMA_TO_DEVICE ); -if (ib_dma_mapping_error (ibdev, dma_addr)) - goto err_free_mem; - - req->indirect_dma_addr = dma_addr; - req->index = i; -list_add_tail (&req->list, &target->free_reqs); - } + ret =srp_alloc_req_data (target); +if (ret) + goto err_free_mem;ib_query_gid (ibdev, host->port,0 , &target->path.sgid);
Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 10/10 IB/srp: Make queue size configurable
In reply to a message not in the archiveCertain storage configurations, e.g. a sufficiently large array of hard disks in a RAID configuration, need a queue depth above 64 to achieve optimal performance. Hence make the queue depth configurable.
--- drivers/infiniband/ulp/srp/ib_srp.c | 125 +++++++++++++++++++++++++++--------- drivers/infiniband/ulp/srp/ib_srp.h | 17 +++-- 2 files changed, 103 insertions(+), 39 deletions(-)
drivers/infiniband/ulp/srp/ib_srp.c +95 -30
@@ -299,16 +299,16 @@ static int srp_create_target_ib(struct srp_target_port *target)return -ENOMEM ; recv_cq =ib_create_cq (target->srp_host->srp_dev->dev, - srp_recv_completion,NULL , target,SRP_RQ_SIZE , - target->comp_vector); + srp_recv_completion,NULL , target, + target->queue_size, target->comp_vector);if (IS_ERR (recv_cq)) { ret =PTR_ERR (recv_cq); goto err; } send_cq =ib_create_cq (target->srp_host->srp_dev->dev, - srp_send_completion,NULL , target,SRP_SQ_SIZE , - target->comp_vector); + srp_send_completion,NULL , target, + target->queue_size, target->comp_vector);if (IS_ERR (send_cq)) { ret =PTR_ERR (send_cq); goto err_recv_cq;
@@ -317,8 +317,8 @@ static int srp_create_target_ib(struct srp_target_port *target)ib_req_notify_cq (recv_cq,IB_CQ_NEXT_COMP ); init_attr->event_handler = srp_qp_event; - init_attr->cap.max_send_wr =SRP_SQ_SIZE ; - init_attr->cap.max_recv_wr =SRP_RQ_SIZE ; + init_attr->cap.max_send_wr = target->queue_size; + init_attr->cap.max_recv_wr = target->queue_size; init_attr->cap.max_recv_sge =1 ; init_attr->cap.max_send_sge =1 ; init_attr->sq_sig_type =IB_SIGNAL_ALL_WR ;
@@ -364,6 +364,10 @@ err:return ret; } +/* +* Note: this function may be called without srp_alloc_iu_bufs() having been +* invoked. Hence the target->[rt]x_ring checks. +*/ static void srp_free_target_ib (struct srp_target_port *target) {int i;
@@ -375,10 +379,18 @@ static void srp_free_target_ib(struct srp_target_port *target) target->qp =NULL ; target->send_cq = target->recv_cq =NULL ; -for (i =0 ; i <SRP_RQ_SIZE ; ++i) -srp_free_iu (target->srp_host, target->rx_ring[i]); -for (i =0 ; i <SRP_SQ_SIZE ; ++i) -srp_free_iu (target->srp_host, target->tx_ring[i]); +if (target->rx_ring) { +for (i =0 ; i < target->queue_size; ++i) +srp_free_iu (target->srp_host, target->rx_ring[i]); +kfree (target->rx_ring); + target->rx_ring =NULL ; + } +if (target->tx_ring) { +for (i =0 ; i < target->queue_size; ++i) +srp_free_iu (target->srp_host, target->tx_ring[i]); +kfree (target->tx_ring); + target->tx_ring =NULL ; + } } static void srp_path_rec_completion(int status,
@@ -564,7 +576,11 @@ static void srp_free_req_data(struct srp_target_port *target)struct srp_request *req;int i; -for (i =0 , req = target->req_ring; i <SRP_CMD_SQ_SIZE ; ++i, ++req) { +if (!target->req_ring) +return ; + +for (i =0 ; i < target->req_ring_size; ++i) { + req = &target->req_ring[i];kfree (req->fmr_list);kfree (req->map_page);if (req->indirect_dma_addr) {
@@ -574,6 +590,9 @@ static void srp_free_req_data(struct srp_target_port *target) }kfree (req->indirect_desc); } + +kfree (target->req_ring); + target->req_ring =NULL ; }static int srp_alloc_req_data (struct srp_target_port *target)
@@ -586,7 +605,12 @@ static int srp_alloc_req_data(struct srp_target_port *target)INIT_LIST_HEAD (&target->free_reqs); -for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { + target->req_ring =kzalloc (target->req_ring_size * +sizeof (*target->req_ring),GFP_KERNEL ); +if (!target->req_ring) + goto out; + +for (i =0 ; i < target->req_ring_size; ++i) { req = &target->req_ring[i]; req->fmr_list =kmalloc (target->cmd_sg_cnt *sizeof (void *),GFP_KERNEL );
@@ -811,7 +835,7 @@ static void srp_terminate_io(struct srp_rport *rport)struct srp_target_port *target = rport->lld_data;int i; -for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { +for (i =0 ; i < target->req_ring_size; ++i) {struct srp_request *req = &target->req_ring[i];srp_finish_req (target, req,DID_TRANSPORT_FAILFAST <<16 ); }
@@ -848,13 +872,13 @@ static int srp_rport_reconnect(struct srp_rport *rport)else srp_create_target_ib (target); -for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { +for (i =0 ; i < target->req_ring_size; ++i) {struct srp_request *req = &target->req_ring[i];srp_finish_req (target, req,DID_RESET <<16 ); }INIT_LIST_HEAD (&target->free_tx); -for (i =0 ; i <SRP_SQ_SIZE ; ++i) +for (i =0 ; i < target->queue_size; ++i)list_add (&target->tx_ring[i]->list, &target->free_tx);if (ret ==0 )
@@ -1562,11 +1586,24 @@ err_unlock:return SCSI_MLQUEUE_HOST_BUSY ; } +/* +* Note: the resources allocated in this function are freed in +* srp_free_target_ib(). +*/ static int srp_alloc_iu_bufs (struct srp_target_port *target) {int i; -for (i =0 ; i <SRP_RQ_SIZE ; ++i) { + target->rx_ring =kzalloc (target->queue_size *sizeof (*target->rx_ring), +GFP_KERNEL ); +if (!target->rx_ring) + goto err_no_ring; + target->tx_ring =kzalloc (target->queue_size *sizeof (*target->tx_ring), +GFP_KERNEL ); +if (!target->tx_ring) + goto err_no_ring; + +for (i =0 ; i < target->queue_size; ++i) { target->rx_ring[i] =srp_alloc_iu (target->srp_host, target->max_ti_iu_len,GFP_KERNEL ,DMA_FROM_DEVICE );
@@ -1574,7 +1611,7 @@ static int srp_alloc_iu_bufs(struct srp_target_port *target) goto err; } -for (i =0 ; i <SRP_SQ_SIZE ; ++i) { +for (i =0 ; i < target->queue_size; ++i) { target->tx_ring[i] =srp_alloc_iu (target->srp_host, target->max_iu_len,GFP_KERNEL ,DMA_TO_DEVICE );
@@ -1587,16 +1624,18 @@ static int srp_alloc_iu_bufs(struct srp_target_port *target)return 0 ; err: -for (i =0 ; i <SRP_RQ_SIZE ; ++i) { +for (i =0 ; i < target->queue_size; ++i) {srp_free_iu (target->srp_host, target->rx_ring[i]); - target->rx_ring[i] =NULL ; - } - -for (i =0 ; i <SRP_SQ_SIZE ; ++i) {srp_free_iu (target->srp_host, target->tx_ring[i]); - target->tx_ring[i] =NULL ; } + +err_no_ring: +kfree (target->tx_ring); + target->tx_ring =NULL ; +kfree (target->rx_ring); + target->rx_ring =NULL ; +return -ENOMEM ; }
@@ -1647,6 +1686,9 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id, target->scsi_host->can_queue =min (target->req_lim -SRP_TSK_MGMT_SQ_SIZE , target->scsi_host->can_queue); + target->scsi_host->cmd_per_lun + =min_t (int, target->scsi_host->can_queue, + target->scsi_host->cmd_per_lun); }else {shost_printk (KERN_WARNING , target->scsi_host,PFX "Unhandled RSP opcode %#x\n" , lrsp->opcode);
@@ -1654,7 +1696,7 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id, goto error; } -if (!target->rx_ring[0 ]) { +if (!target->rx_ring) { ret =srp_alloc_iu_bufs (target);if (ret) goto error;
@@ -1674,7 +1716,7 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id,if (ret) goto error_free; -for (i =0 ; i <SRP_RQ_SIZE ; i++) { +for (i =0 ; i < target->queue_size; i++) {struct srp_iu *iu = target->rx_ring[i]; ret =srp_post_recv (target, iu);if (ret)
@@ -1933,7 +1975,7 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)if (target->tsk_mgmt_status)return FAILED ; -for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { +for (i =0 ; i < target->req_ring_size; ++i) {struct srp_request *req = &target->req_ring[i];if (req->scmnd && req->scmnd->device == scmnd->device)srp_finish_req (target, req,DID_RESET <<16 );
@@ -2136,9 +2178,9 @@ static struct scsi_host_template srp_template = { .eh_host_reset_handler = srp_reset_host, .skip_settle_delay = true, .sg_tablesize = SRP_DEF_SG_TABLESIZE, - .can_queue = SRP_CMD_SQ_SIZE, + .can_queue = SRP_DEFAULT_CMD_SQ_SIZE, .this_id = -1, - .cmd_per_lun = SRP_CMD_SQ_SIZE, + .cmd_per_lun = SRP_DEFAULT_CMD_SQ_SIZE, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = srp_host_attrs };
@@ -2245,6 +2287,7 @@ enum {SRP_OPT_SG_TABLESIZE =1 <<11 ,SRP_OPT_COMP_VECTOR =1 <<12 ,SRP_OPT_TL_RETRY_COUNT =1 <<13 , +SRP_OPT_CAN_QUEUE =1 <<14 , SRP_OPT_ALL = (SRP_OPT_ID_EXT | SRP_OPT_IOC_GUID | SRP_OPT_DGID |
@@ -2267,6 +2310,7 @@ static const match_table_t srp_opt_tokens = { { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" }, { SRP_OPT_COMP_VECTOR, "comp_vector=%u" }, { SRP_OPT_TL_RETRY_COUNT, "tl_retry_count=%u" }, + { SRP_OPT_CAN_QUEUE, "can_queue=%d" }, { SRP_OPT_ERR, NULL } };
@@ -2361,13 +2405,25 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) target->scsi_host->max_sectors = token;break ; +case SRP_OPT_CAN_QUEUE : +if (match_int (args, &token) || token <1 ) { +pr_warn ("bad can_queue parameter '%s'\n" , p); + goto out; + } + target->scsi_host->can_queue = token; + target->queue_size = token +SRP_RSP_SQ_SIZE + +SRP_TSK_MGMT_SQ_SIZE ; +if (!(opt_mask &SRP_OPT_MAX_CMD_PER_LUN )) + target->scsi_host->cmd_per_lun = token; +break ; +case SRP_OPT_MAX_CMD_PER_LUN : -if (match_int (args, &token)) { +if (match_int (args, &token) || token <1 ) {pr_warn ("bad max cmd_per_lun parameter '%s'\n" , p); goto out; } - target->scsi_host->cmd_per_lun =min (token,SRP_CMD_SQ_SIZE ); + target->scsi_host->cmd_per_lun = token;break ;case SRP_OPT_IO_CLASS :
@@ -2455,6 +2511,12 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)pr_warn ("target creation request is missing parameter '%s'\n" , srp_opt_tokens[i].pattern); +if (target->scsi_host->cmd_per_lun > target->scsi_host->can_queue + && (opt_mask &SRP_OPT_MAX_CMD_PER_LUN )) +pr_warn ("cmd_per_lun = %d > can_queue = %d\n" , + target->scsi_host->cmd_per_lun, + target->scsi_host->can_queue); + out:kfree (options);return ret;
@@ -2493,11 +2555,14 @@ static ssize_t srp_create_target(struct device *dev, target->sg_tablesize = indirect_sg_entries ? : cmd_sg_entries; target->allow_ext_sg = allow_ext_sg; target->tl_retry_count =7 ; + target->queue_size =SRP_DEFAULT_QUEUE_SIZE ; ret =srp_parse_options (buf, target);if (ret) goto err; + target->req_ring_size = target->queue_size -SRP_TSK_MGMT_SQ_SIZE ; +if (!srp_conn_unique (target->srp_host, target)) { shost_printk(KERN_INFO, target->scsi_host, PFX "Already connected to target port with id_ext=%016llx;ioc_guid=%016llx;initiator_ext=%016llx\n",
drivers/infiniband/ulp/srp/ib_srp.h +8 -9
@@ -57,14 +57,11 @@ enum {SRP_MAX_LUN =512 ,SRP_DEF_SG_TABLESIZE =12 , -SRP_RQ_SHIFT =6 , -SRP_RQ_SIZE =1 <<SRP_RQ_SHIFT , - -SRP_SQ_SIZE =SRP_RQ_SIZE , +SRP_DEFAULT_QUEUE_SIZE =1 <<6 ,SRP_RSP_SQ_SIZE =1 , -SRP_REQ_SQ_SIZE =SRP_SQ_SIZE -SRP_RSP_SQ_SIZE ,SRP_TSK_MGMT_SQ_SIZE =1 , -SRP_CMD_SQ_SIZE =SRP_REQ_SQ_SIZE -SRP_TSK_MGMT_SQ_SIZE , +SRP_DEFAULT_CMD_SQ_SIZE =SRP_DEFAULT_QUEUE_SIZE -SRP_RSP_SQ_SIZE - +SRP_TSK_MGMT_SQ_SIZE ,SRP_TAG_NO_REQ = ~0U , SRP_TAG_TSK_MGMT = 1U << 31,
@@ -156,6 +153,8 @@ struct srp_target_port {char target_name[32 ];unsigned int scsi_id;unsigned int sg_tablesize; +int queue_size; +int req_ring_size;int comp_vector;int tl_retry_count;
@@ -173,9 +172,9 @@ struct srp_target_port {int zero_req_lim; -struct srp_iu *tx_ring[SRP_SQ_SIZE ]; -struct srp_iu *rx_ring[SRP_RQ_SIZE ]; -struct srp_request req_ring[SRP_CMD_SQ_SIZE ]; +struct srp_iu **tx_ring; +struct srp_iu **rx_ring; +struct srp_request *req_ring;struct work_struct tl_err_work;struct work_struct remove_work;
Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 10/10] IB/srp: Make queue size configurable
Quoted 4 lines · Bart Van Assche
Certain storage configurations, e.g. a sufficiently large array of hard disks in a RAID configuration, need a queue depth above 64 to achieve optimal performance. Hence make the queue depth configurable.
Hello Bart,
It's better to mention user may need to bump the configuration on target side, as we adjust can_queue to req_lim when receive login response.
Patch looks good to me, if needed you can add my Tested-by.
Thanks,
Jack
Quoted 359 lines
Signed-off-by Bart Van Assche <[email protected]>Cc David Dillow <[email protected]>Cc Roland Dreier <[email protected]>Cc Vu Pham <vu-VPRAkNaXOzVWk0Htik3J/[email protected]>Cc Sebastian Riemer <[email protected]>Cc Konrad Grzybowski <[email protected]>--- drivers/infiniband/ulp/srp/ib_srp.c | 125 +++++++++++++++++++++++++++--------- drivers/infiniband/ulp/srp/ib_srp.h | 17 +++-- 2 files changed, 103 insertions(+), 39 deletions(-)drivers/infiniband/ulp/srp/ib_srp.c +95
-30@@ -299,16 +299,16 @@ static int srp_create_target_ib(struct srp_target_port *target)return -ENOMEM ; recv_cq =ib_create_cq (target->srp_host->srp_dev->dev, - srp_recv_completion,NULL , target,SRP_RQ_SIZE , - target->comp_vector); + srp_recv_completion,NULL , target, + target->queue_size, target->comp_vector);if (IS_ERR (recv_cq)) { ret =PTR_ERR (recv_cq); goto err; } send_cq =ib_create_cq (target->srp_host->srp_dev->dev, - srp_send_completion,NULL , target,SRP_SQ_SIZE , - target->comp_vector); + srp_send_completion,NULL , target, + target->queue_size, target->comp_vector);if (IS_ERR (send_cq)) { ret =PTR_ERR (send_cq); goto err_recv_cq;@@ -317,8 +317,8 @@ static int srp_create_target_ib(struct srp_target_port *target)ib_req_notify_cq (recv_cq,IB_CQ_NEXT_COMP ); init_attr->event_handler = srp_qp_event; - init_attr->cap.max_send_wr =SRP_SQ_SIZE ; - init_attr->cap.max_recv_wr =SRP_RQ_SIZE ; + init_attr->cap.max_send_wr = target->queue_size; + init_attr->cap.max_recv_wr = target->queue_size; init_attr->cap.max_recv_sge =1 ; init_attr->cap.max_send_sge =1 ; init_attr->sq_sig_type =IB_SIGNAL_ALL_WR ;@@ -364,6 +364,10 @@ err:return ret; } +/* +* Note: this function may be called without srp_alloc_iu_bufs() having been +* invoked. Hence the target->[rt]x_ring checks. +*/ static void srp_free_target_ib (struct srp_target_port *target) {int i;@@ -375,10 +379,18 @@ static void srp_free_target_ib(struct srp_target_port *target) target->qp =NULL ; target->send_cq = target->recv_cq =NULL ; -for (i =0 ; i <SRP_RQ_SIZE ; ++i) -srp_free_iu (target->srp_host, target->rx_ring[i]); -for (i =0 ; i <SRP_SQ_SIZE ; ++i) -srp_free_iu (target->srp_host, target->tx_ring[i]); +if (target->rx_ring) { +for (i =0 ; i < target->queue_size; ++i) +srp_free_iu (target->srp_host, target->rx_ring[i]); +kfree (target->rx_ring); + target->rx_ring =NULL ; + } +if (target->tx_ring) { +for (i =0 ; i < target->queue_size; ++i) +srp_free_iu (target->srp_host, target->tx_ring[i]); +kfree (target->tx_ring); + target->tx_ring =NULL ; + } } static void srp_path_rec_completion(int status,@@ -564,7 +576,11 @@ static void srp_free_req_data(struct srp_target_port *target)struct srp_request *req;int i; -for (i =0 , req = target->req_ring; i <SRP_CMD_SQ_SIZE ; ++i, ++req) { +if (!target->req_ring) +return ; + +for (i =0 ; i < target->req_ring_size; ++i) { + req = &target->req_ring[i];kfree (req->fmr_list);kfree (req->map_page);if (req->indirect_dma_addr) {@@ -574,6 +590,9 @@ static void srp_free_req_data(struct srp_target_port *target) }kfree (req->indirect_desc); } + +kfree (target->req_ring); + target->req_ring =NULL ; }static int srp_alloc_req_data (struct srp_target_port *target)@@ -586,7 +605,12 @@ static int srp_alloc_req_data(struct srp_target_port *target)INIT_LIST_HEAD (&target->free_reqs); -for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { + target->req_ring =kzalloc (target->req_ring_size * +sizeof (*target->req_ring),GFP_KERNEL ); +if (!target->req_ring) + goto out; + +for (i =0 ; i < target->req_ring_size; ++i) { req = &target->req_ring[i]; req->fmr_list =kmalloc (target->cmd_sg_cnt *sizeof (void *),GFP_KERNEL );@@ -811,7 +835,7 @@ static void srp_terminate_io(struct srp_rport *rport)struct srp_target_port *target = rport->lld_data;int i; -for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { +for (i =0 ; i < target->req_ring_size; ++i) {struct srp_request *req = &target->req_ring[i];srp_finish_req (target, req,DID_TRANSPORT_FAILFAST <<16 ); }@@ -848,13 +872,13 @@ static int srp_rport_reconnect(struct srp_rport *rport)else srp_create_target_ib (target); -for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { +for (i =0 ; i < target->req_ring_size; ++i) {struct srp_request *req = &target->req_ring[i];srp_finish_req (target, req,DID_RESET <<16 ); }INIT_LIST_HEAD (&target->free_tx); -for (i =0 ; i <SRP_SQ_SIZE ; ++i) +for (i =0 ; i < target->queue_size; ++i)list_add (&target->tx_ring[i]->list, &target->free_tx);if (ret ==0 )@@ -1562,11 +1586,24 @@ err_unlock:return SCSI_MLQUEUE_HOST_BUSY ; } +/* +* Note: the resources allocated in this function are freed in +* srp_free_target_ib(). +*/ static int srp_alloc_iu_bufs (struct srp_target_port *target) {int i; -for (i =0 ; i <SRP_RQ_SIZE ; ++i) { + target->rx_ring =kzalloc (target->queue_size *sizeof (*target->rx_ring), +GFP_KERNEL ); +if (!target->rx_ring) + goto err_no_ring; + target->tx_ring =kzalloc (target->queue_size *sizeof (*target->tx_ring), +GFP_KERNEL ); +if (!target->tx_ring) + goto err_no_ring; + +for (i =0 ; i < target->queue_size; ++i) { target->rx_ring[i] =srp_alloc_iu (target->srp_host, target->max_ti_iu_len,GFP_KERNEL ,DMA_FROM_DEVICE );@@ -1574,7 +1611,7 @@ static int srp_alloc_iu_bufs(struct srp_target_port *target) goto err; } -for (i =0 ; i <SRP_SQ_SIZE ; ++i) { +for (i =0 ; i < target->queue_size; ++i) { target->tx_ring[i] =srp_alloc_iu (target->srp_host, target->max_iu_len,GFP_KERNEL ,DMA_TO_DEVICE );@@ -1587,16 +1624,18 @@ static int srp_alloc_iu_bufs(struct srp_target_port *target)return 0 ; err: -for (i =0 ; i <SRP_RQ_SIZE ; ++i) { +for (i =0 ; i < target->queue_size; ++i) {srp_free_iu (target->srp_host, target->rx_ring[i]); - target->rx_ring[i] =NULL ; - } - -for (i =0 ; i <SRP_SQ_SIZE ; ++i) {srp_free_iu (target->srp_host, target->tx_ring[i]); - target->tx_ring[i] =NULL ; } + +err_no_ring: +kfree (target->tx_ring); + target->tx_ring =NULL ; +kfree (target->rx_ring); + target->rx_ring =NULL ; +return -ENOMEM ; }@@ -1647,6 +1686,9 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id, target->scsi_host->can_queue =min (target->req_lim -SRP_TSK_MGMT_SQ_SIZE , target->scsi_host->can_queue); + target->scsi_host->cmd_per_lun + =min_t (int, target->scsi_host->can_queue, + target->scsi_host->cmd_per_lun); }else {shost_printk (KERN_WARNING , target->scsi_host,PFX "Unhandled RSP opcode %#x\n" , lrsp->opcode);@@ -1654,7 +1696,7 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id, goto error; } -if (!target->rx_ring[0 ]) { +if (!target->rx_ring) { ret =srp_alloc_iu_bufs (target);if (ret) goto error;@@ -1674,7 +1716,7 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id,if (ret) goto error_free; -for (i =0 ; i <SRP_RQ_SIZE ; i++) { +for (i =0 ; i < target->queue_size; i++) {struct srp_iu *iu = target->rx_ring[i]; ret =srp_post_recv (target, iu);if (ret)@@ -1933,7 +1975,7 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)if (target->tsk_mgmt_status)return FAILED ; -for (i =0 ; i <SRP_CMD_SQ_SIZE ; ++i) { +for (i =0 ; i < target->req_ring_size; ++i) {struct srp_request *req = &target->req_ring[i];if (req->scmnd && req->scmnd->device == scmnd->device)srp_finish_req (target, req,DID_RESET <<16 );@@ -2136,9 +2178,9 @@ static struct scsi_host_template srp_template = { .eh_host_reset_handler = srp_reset_host, .skip_settle_delay = true, .sg_tablesize = SRP_DEF_SG_TABLESIZE, - .can_queue = SRP_CMD_SQ_SIZE, + .can_queue = SRP_DEFAULT_CMD_SQ_SIZE, .this_id = -1, - .cmd_per_lun = SRP_CMD_SQ_SIZE, + .cmd_per_lun = SRP_DEFAULT_CMD_SQ_SIZE, .use_clustering = ENABLE_CLUSTERING, .shost_attrs = srp_host_attrs };@@ -2245,6 +2287,7 @@ enum {SRP_OPT_SG_TABLESIZE =1 <<11 ,SRP_OPT_COMP_VECTOR =1 <<12 ,SRP_OPT_TL_RETRY_COUNT =1 <<13 , +SRP_OPT_CAN_QUEUE =1 <<14 , SRP_OPT_ALL = (SRP_OPT_ID_EXT | SRP_OPT_IOC_GUID | SRP_OPT_DGID |@@ -2267,6 +2310,7 @@ static const match_table_t srp_opt_tokens = { { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" }, { SRP_OPT_COMP_VECTOR, "comp_vector=%u" }, { SRP_OPT_TL_RETRY_COUNT, "tl_retry_count=%u" }, + { SRP_OPT_CAN_QUEUE, "can_queue=%d" }, { SRP_OPT_ERR, NULL } };@@ -2361,13 +2405,25 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) target->scsi_host->max_sectors = token;break ; +case SRP_OPT_CAN_QUEUE : +if (match_int (args, &token) || token <1 ) { +pr_warn ("bad can_queue parameter '%s'\n" , p); + goto out; + } + target->scsi_host->can_queue = token; + target->queue_size = token +SRP_RSP_SQ_SIZE + +SRP_TSK_MGMT_SQ_SIZE ; +if (!(opt_mask &SRP_OPT_MAX_CMD_PER_LUN )) + target->scsi_host->cmd_per_lun = token; +break ; +case SRP_OPT_MAX_CMD_PER_LUN : -if (match_int (args, &token)) { +if (match_int (args, &token) || token <1 ) {pr_warn ("bad max cmd_per_lun parameter '%s'\n" , p); goto out; } - target->scsi_host->cmd_per_lun =min (token,SRP_CMD_SQ_SIZE ); + target->scsi_host->cmd_per_lun = token;break ;case SRP_OPT_IO_CLASS :@@ -2455,6 +2511,12 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)pr_warn ("target creation request is missing parameter '%s'\n" , srp_opt_tokens[i].pattern); +if (target->scsi_host->cmd_per_lun > target->scsi_host->can_queue + && (opt_mask &SRP_OPT_MAX_CMD_PER_LUN )) +pr_warn ("cmd_per_lun = %d > can_queue = %d\n" , + target->scsi_host->cmd_per_lun, + target->scsi_host->can_queue); + out:kfree (options);return ret;@@ -2493,11 +2555,14 @@ static ssize_t srp_create_target(struct device *dev, target->sg_tablesize = indirect_sg_entries ? : cmd_sg_entries; target->allow_ext_sg = allow_ext_sg; target->tl_retry_count =7 ; + target->queue_size =SRP_DEFAULT_QUEUE_SIZE ; ret =srp_parse_options (buf, target);if (ret) goto err; + target->req_ring_size = target->queue_size -SRP_TSK_MGMT_SQ_SIZE ; +if (!srp_conn_unique (target->srp_host, target)) { shost_printk(KERN_INFO, target->scsi_host, PFX "Already connected to target port with id_ext=%016llx;ioc_guid=%016llx;initiator_ext=%016llx\n",drivers/infiniband/ulp/srp/ib_srp.h +5
-6@@ -57,14 +57,11 @@ enum {SRP_MAX_LUN =512 ,SRP_DEF_SG_TABLESIZE =12 , -SRP_RQ_SHIFT =6 , -SRP_RQ_SIZE =1 <<SRP_RQ_SHIFT , - -SRP_SQ_SIZE =SRP_RQ_SIZE , +SRP_DEFAULT_QUEUE_SIZE =1 <<6 ,SRP_RSP_SQ_SIZE =1 , -SRP_REQ_SQ_SIZE =SRP_SQ_SIZE -SRP_RSP_SQ_SIZE ,SRP_TSK_MGMT_SQ_SIZE =1 , -SRP_CMD_SQ_SIZE =SRP_REQ_SQ_SIZE -SRP_TSK_MGMT_SQ_SIZE , +SRP_DEFAULT_CMD_SQ_SIZE =SRP_DEFAULT_QUEUE_SIZE -SRP_RSP_SQ_SIZE - +SRP_TSK_MGMT_SQ_SIZE ,SRP_TAG_NO_REQ = ~0U , SRP_TAG_TSK_MGMT = 1U << 31,@@ -156,6 +153,8 @@ struct srp_target_port {char target_name[32 ];unsigned int scsi_id;unsigned int sg_tablesize; +int queue_size; +int req_ring_size;int comp_vector;int tl_retry_count;@@ -173,9 +172,9 @@ struct srp_target_port {int zero_req_lim;
drivers/infiniband/ulp/srp/ib_srp.h struct srp_target_port { · line 180
Quoted 10 lines
drivers/infiniband/ulp/srp/ib_srp.h +3
-3-struct srp_iu *tx_ring[SRP_SQ_SIZE ]; -struct srp_iu *rx_ring[SRP_RQ_SIZE ]; -struct srp_request req_ring[SRP_CMD_SQ_SIZE ]; +struct srp_iu **tx_ring; +struct srp_iu **rx_ring; +struct srp_request *req_ring;struct work_struct tl_err_work;struct work_struct remove_work;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 10/10] IB/srp: Make queue size configurable
In reply to a message not in the archivedrivers/infiniband/ulp/srp/ib_srp.c static const match_table_t srp_opt_tokens = { · line 2314
Quoted 6 lines · Bart Van Assche
drivers/infiniband/ulp/srp/ib_srp.c +1
-0@@ -2267,6 +2310,7 @@ static const match_table_t srp_opt_tokens = { { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" }, { SRP_OPT_COMP_VECTOR, "comp_vector=%u" }, { SRP_OPT_TL_RETRY_COUNT, "tl_retry_count=%u" }, + { SRP_OPT_CAN_QUEUE, "can_queue=%d" }, { SRP_OPT_ERR, NULL }
Minor question -- I thought you had ended up suggesting queue_size instead of can_queue here?
Signature · 9 lines
Dave Dillow National Center for Computational Science Oak Ridge National Laboratory (865) 241-6602 office -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 1382739213.17280.3.camel-zHLflQxYYDO4Hhoo1DtQwJ9G+ZOsUmrO@public.gmane.org
Re: [PATCH 10/10] IB/srp: Make queue size configurable
Quoted 10 lines · David Dillow
drivers/infiniband/ulp/srp/ib_srp.c static const match_table_t srp_opt_tokens = { · line 2314
Quoted 6 lines · Bart Van Assche
drivers/infiniband/ulp/srp/ib_srp.c +1
-0@@ -2267,6 +2310,7 @@ static const match_table_t srp_opt_tokens = { { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" }, { SRP_OPT_COMP_VECTOR, "comp_vector=%u" }, { SRP_OPT_TL_RETRY_COUNT, "tl_retry_count=%u" }, + { SRP_OPT_CAN_QUEUE, "can_queue=%d" }, { SRP_OPT_ERR, NULL }Minor question -- I thought you had ended up suggesting
queue_sizeinstead ofcan_queuehere?
Sorry, forgot to change that. Will post an update.
Bart.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
David Dillow
Acked-byQuoted 10 lines · Bart Van Assche
The purpose of this InfiniBand SRP initiator patch series is as follows:
- Make the SRP initiator driver better suited for use in a H.A. setup. Addfast_io_fail_tmo,dev_loss_tmoandreconnect_delayparameters. With the default values of these parameters failover happens significantly faster. Thedev_lossmechanism can be disabled which makes it possible to avoid device removal which is necessary when e.g. using initiator side mirroring.
- Improve performance by making the queue size configurable.
- Make it possible to figure out which SCSI host corresponds to which SRP initiator port by making the SGID (source GID) available in sysfs.
Many of these already have it, but for patches 1-10:
Signature · 9 lines
Dave Dillow National Center for Computational Science Oak Ridge National Laboratory (865) 241-6602 office -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Bart Van Assche
maintainerPATCH 2/10 IB/srp: Keep rport as long as the IB transport layer
In reply to Bart Van AsscheKeep the rport data structure around after srp_remove_host() has finished until cleanup of the IB transport layer has finished completely. This is necessary because later patches use the rport pointer inside the queuecommand callback. Without this patch accessing the rport from inside a queuecommand callback is racy because srp_remove_host() must be invoked before scsi_remove_host() and because the queuecommand callback could get invoked after srp_remove_host() has finished. In other words, without this patch the queuecommand callback can get invoked after the rport data structure has been freed.
--- drivers/infiniband/ulp/srp/ib_srp.c | 3 +++ drivers/infiniband/ulp/srp/ib_srp.h | 1 + drivers/scsi/scsi_transport_srp.c | 18 ++++++++++++++++++ include/scsi/scsi_transport_srp.h | 2 ++ 4 files changed, 24 insertions(+)
drivers/infiniband/ulp/srp/ib_srp.c +3 -0
@@ -528,11 +528,13 @@ static void srp_remove_target(struct srp_target_port *target)WARN_ON_ONCE (target->state !=SRP_TARGET_REMOVED );srp_del_scsi_host_attr (target->scsi_host); +srp_rport_get (target->rport);srp_remove_host (target->scsi_host);scsi_remove_host (target->scsi_host);srp_disconnect_target (target);ib_destroy_cm_id (target->cm_id);srp_free_target_ib (target); +srp_rport_put (target->rport);srp_free_req_data (target);spin_lock (&target->srp_host->target_lock);
@@ -2004,6 +2006,7 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target) } rport->lld_data = target; + target->rport = rport;spin_lock (&host->target_lock);list_add_tail (&target->list, &host->target_list);
drivers/infiniband/ulp/srp/ib_srp.h +1 -0
@@ -153,6 +153,7 @@ struct srp_target_port {u16 io_class;struct srp_host *srp_host;struct Scsi_Host *scsi_host; +struct srp_rport *rport;char target_name[32 ];unsigned int scsi_id;unsigned int sg_tablesize;
drivers/scsi/scsi_transport_srp.c +18 -0
@@ -185,6 +185,24 @@ static int srp_host_match(struct attribute_container *cont, struct device *dev) }/** +* srp_rport_get() - increment rport reference count +*/ +void srp_rport_get (struct srp_rport *rport) +{ +get_device (&rport->dev); +} +EXPORT_SYMBOL (srp_rport_get); + +/** +* srp_rport_put() - decrement rport reference count +*/ +void srp_rport_put (struct srp_rport *rport) +{ +put_device (&rport->dev); +} +EXPORT_SYMBOL (srp_rport_put); + +/** * srp_rport_add - add a SRP remote port to the device hierarchy * @shost: scsi host the remote port is connected to. * @ids: The port id for the remote port.
include/scsi/scsi_transport_srp.h +2 -0
@@ -38,6 +38,8 @@ extern struct scsi_transport_template *srp_attach_transport (struct srp_function_template *);extern void srp_release_transport (struct scsi_transport_template *); +extern void srp_rport_get (struct srp_rport *rport); +extern void srp_rport_put (struct srp_rport *rport);extern struct srp_rport *srp_rport_add (struct Scsi_Host *,struct srp_rport_identifiers *);extern void srp_rport_del (struct srp_rport *);
Signature · 1 line
1.8.1.4