aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_fc.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/scsi/scsi_transport_fc.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/scsi/scsi_transport_fc.c')
-rw-r--r--drivers/scsi/scsi_transport_fc.c199
1 files changed, 143 insertions, 56 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index d7e470a06180..1b214910b714 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -53,6 +53,25 @@ static void fc_bsg_remove(struct request_queue *);
53static void fc_bsg_goose_queue(struct fc_rport *); 53static void fc_bsg_goose_queue(struct fc_rport *);
54 54
55/* 55/*
56 * Module Parameters
57 */
58
59/*
60 * dev_loss_tmo: the default number of seconds that the FC transport
61 * should insulate the loss of a remote port.
62 * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT.
63 */
64static unsigned int fc_dev_loss_tmo = 60; /* seconds */
65
66module_param_named(dev_loss_tmo, fc_dev_loss_tmo, uint, S_IRUGO|S_IWUSR);
67MODULE_PARM_DESC(dev_loss_tmo,
68 "Maximum number of seconds that the FC transport should"
69 " insulate the loss of a remote port. Once this value is"
70 " exceeded, the scsi target is removed. Value should be"
71 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT if"
72 " fast_io_fail_tmo is not set.");
73
74/*
56 * Redefine so that we can have same named attributes in the 75 * Redefine so that we can have same named attributes in the
57 * sdev/starget/host objects. 76 * sdev/starget/host objects.
58 */ 77 */
@@ -403,16 +422,16 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
403 422
404 snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name), 423 snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name),
405 "fc_wq_%d", shost->host_no); 424 "fc_wq_%d", shost->host_no);
406 fc_host->work_q = create_singlethread_workqueue( 425 fc_host->work_q = alloc_workqueue(fc_host->work_q_name, 0, 0);
407 fc_host->work_q_name);
408 if (!fc_host->work_q) 426 if (!fc_host->work_q)
409 return -ENOMEM; 427 return -ENOMEM;
410 428
429 fc_host->dev_loss_tmo = fc_dev_loss_tmo;
411 snprintf(fc_host->devloss_work_q_name, 430 snprintf(fc_host->devloss_work_q_name,
412 sizeof(fc_host->devloss_work_q_name), 431 sizeof(fc_host->devloss_work_q_name),
413 "fc_dl_%d", shost->host_no); 432 "fc_dl_%d", shost->host_no);
414 fc_host->devloss_work_q = create_singlethread_workqueue( 433 fc_host->devloss_work_q =
415 fc_host->devloss_work_q_name); 434 alloc_workqueue(fc_host->devloss_work_q_name, 0, 0);
416 if (!fc_host->devloss_work_q) { 435 if (!fc_host->devloss_work_q) {
417 destroy_workqueue(fc_host->work_q); 436 destroy_workqueue(fc_host->work_q);
418 fc_host->work_q = NULL; 437 fc_host->work_q = NULL;
@@ -462,25 +481,6 @@ static DECLARE_TRANSPORT_CLASS(fc_vport_class,
462 NULL); 481 NULL);
463 482
464/* 483/*
465 * Module Parameters
466 */
467
468/*
469 * dev_loss_tmo: the default number of seconds that the FC transport
470 * should insulate the loss of a remote port.
471 * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT.
472 */
473static unsigned int fc_dev_loss_tmo = 60; /* seconds */
474
475module_param_named(dev_loss_tmo, fc_dev_loss_tmo, uint, S_IRUGO|S_IWUSR);
476MODULE_PARM_DESC(dev_loss_tmo,
477 "Maximum number of seconds that the FC transport should"
478 " insulate the loss of a remote port. Once this value is"
479 " exceeded, the scsi target is removed. Value should be"
480 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT if"
481 " fast_io_fail_tmo is not set.");
482
483/*
484 * Netlink Infrastructure 484 * Netlink Infrastructure
485 */ 485 */
486 486
@@ -830,24 +830,32 @@ static FC_DEVICE_ATTR(rport, supported_classes, S_IRUGO,
830/* 830/*
831 * dev_loss_tmo attribute 831 * dev_loss_tmo attribute
832 */ 832 */
833fc_rport_show_function(dev_loss_tmo, "%d\n", 20, ) 833static int fc_str_to_dev_loss(const char *buf, unsigned long *val)
834static ssize_t 834{
835store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr, 835 char *cp;
836 const char *buf, size_t count) 836
837 *val = simple_strtoul(buf, &cp, 0);
838 if ((*cp && (*cp != '\n')) || (*val < 0))
839 return -EINVAL;
840 /*
841 * Check for overflow; dev_loss_tmo is u32
842 */
843 if (*val > UINT_MAX)
844 return -EINVAL;
845
846 return 0;
847}
848
849static int fc_rport_set_dev_loss_tmo(struct fc_rport *rport,
850 unsigned long val)
837{ 851{
838 unsigned long val;
839 struct fc_rport *rport = transport_class_to_rport(dev);
840 struct Scsi_Host *shost = rport_to_shost(rport); 852 struct Scsi_Host *shost = rport_to_shost(rport);
841 struct fc_internal *i = to_fc_internal(shost->transportt); 853 struct fc_internal *i = to_fc_internal(shost->transportt);
842 char *cp; 854
843 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || 855 if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
844 (rport->port_state == FC_PORTSTATE_DELETED) || 856 (rport->port_state == FC_PORTSTATE_DELETED) ||
845 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) 857 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
846 return -EBUSY; 858 return -EBUSY;
847 val = simple_strtoul(buf, &cp, 0);
848 if ((*cp && (*cp != '\n')) || (val < 0))
849 return -EINVAL;
850
851 /* 859 /*
852 * Check for overflow; dev_loss_tmo is u32 860 * Check for overflow; dev_loss_tmo is u32
853 */ 861 */
@@ -863,6 +871,25 @@ store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr,
863 return -EINVAL; 871 return -EINVAL;
864 872
865 i->f->set_rport_dev_loss_tmo(rport, val); 873 i->f->set_rport_dev_loss_tmo(rport, val);
874 return 0;
875}
876
877fc_rport_show_function(dev_loss_tmo, "%d\n", 20, )
878static ssize_t
879store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr,
880 const char *buf, size_t count)
881{
882 struct fc_rport *rport = transport_class_to_rport(dev);
883 unsigned long val;
884 int rc;
885
886 rc = fc_str_to_dev_loss(buf, &val);
887 if (rc)
888 return rc;
889
890 rc = fc_rport_set_dev_loss_tmo(rport, val);
891 if (rc)
892 return rc;
866 return count; 893 return count;
867} 894}
868static FC_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR, 895static FC_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR,
@@ -1608,8 +1635,35 @@ store_fc_private_host_issue_lip(struct device *dev,
1608static FC_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL, 1635static FC_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
1609 store_fc_private_host_issue_lip); 1636 store_fc_private_host_issue_lip);
1610 1637
1611fc_private_host_rd_attr(npiv_vports_inuse, "%u\n", 20); 1638static ssize_t
1639store_fc_private_host_dev_loss_tmo(struct device *dev,
1640 struct device_attribute *attr,
1641 const char *buf, size_t count)
1642{
1643 struct Scsi_Host *shost = transport_class_to_shost(dev);
1644 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1645 struct fc_rport *rport;
1646 unsigned long val, flags;
1647 int rc;
1648
1649 rc = fc_str_to_dev_loss(buf, &val);
1650 if (rc)
1651 return rc;
1652
1653 fc_host_dev_loss_tmo(shost) = val;
1654 spin_lock_irqsave(shost->host_lock, flags);
1655 list_for_each_entry(rport, &fc_host->rports, peers)
1656 fc_rport_set_dev_loss_tmo(rport, val);
1657 spin_unlock_irqrestore(shost->host_lock, flags);
1658 return count;
1659}
1612 1660
1661fc_private_host_show_function(dev_loss_tmo, "%d\n", 20, );
1662static FC_DEVICE_ATTR(host, dev_loss_tmo, S_IRUGO | S_IWUSR,
1663 show_fc_host_dev_loss_tmo,
1664 store_fc_private_host_dev_loss_tmo);
1665
1666fc_private_host_rd_attr(npiv_vports_inuse, "%u\n", 20);
1613 1667
1614/* 1668/*
1615 * Host Statistics Management 1669 * Host Statistics Management
@@ -2165,6 +2219,7 @@ fc_attach_transport(struct fc_function_template *ft)
2165 SETUP_HOST_ATTRIBUTE_RW(system_hostname); 2219 SETUP_HOST_ATTRIBUTE_RW(system_hostname);
2166 2220
2167 /* Transport-managed attributes */ 2221 /* Transport-managed attributes */
2222 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(dev_loss_tmo);
2168 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); 2223 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
2169 if (ft->issue_fc_host_lip) 2224 if (ft->issue_fc_host_lip)
2170 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip); 2225 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
@@ -2322,7 +2377,7 @@ fc_flush_devloss(struct Scsi_Host *shost)
2322 * fc_remove_host - called to terminate any fc_transport-related elements for a scsi host. 2377 * fc_remove_host - called to terminate any fc_transport-related elements for a scsi host.
2323 * @shost: Which &Scsi_Host 2378 * @shost: Which &Scsi_Host
2324 * 2379 *
2325 * This routine is expected to be called immediately preceeding the 2380 * This routine is expected to be called immediately preceding the
2326 * a driver's call to scsi_remove_host(). 2381 * a driver's call to scsi_remove_host().
2327 * 2382 *
2328 * WARNING: A driver utilizing the fc_transport, which fails to call 2383 * WARNING: A driver utilizing the fc_transport, which fails to call
@@ -2402,7 +2457,7 @@ static void fc_terminate_rport_io(struct fc_rport *rport)
2402} 2457}
2403 2458
2404/** 2459/**
2405 * fc_starget_delete - called to delete the scsi decendents of an rport 2460 * fc_starget_delete - called to delete the scsi descendants of an rport
2406 * @work: remote port to be operated on. 2461 * @work: remote port to be operated on.
2407 * 2462 *
2408 * Deletes target and all sdevs. 2463 * Deletes target and all sdevs.
@@ -2433,6 +2488,8 @@ fc_rport_final_delete(struct work_struct *work)
2433 unsigned long flags; 2488 unsigned long flags;
2434 int do_callback = 0; 2489 int do_callback = 0;
2435 2490
2491 fc_terminate_rport_io(rport);
2492
2436 /* 2493 /*
2437 * if a scan is pending, flush the SCSI Host work_q so that 2494 * if a scan is pending, flush the SCSI Host work_q so that
2438 * that we can reclaim the rport scan work element. 2495 * that we can reclaim the rport scan work element.
@@ -2440,8 +2497,6 @@ fc_rport_final_delete(struct work_struct *work)
2440 if (rport->flags & FC_RPORT_SCAN_PENDING) 2497 if (rport->flags & FC_RPORT_SCAN_PENDING)
2441 scsi_flush_work(shost); 2498 scsi_flush_work(shost);
2442 2499
2443 fc_terminate_rport_io(rport);
2444
2445 /* 2500 /*
2446 * Cancel any outstanding timers. These should really exist 2501 * Cancel any outstanding timers. These should really exist
2447 * only when rmmod'ing the LLDD and we're asking for 2502 * only when rmmod'ing the LLDD and we're asking for
@@ -2525,7 +2580,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
2525 2580
2526 rport->maxframe_size = -1; 2581 rport->maxframe_size = -1;
2527 rport->supported_classes = FC_COS_UNSPECIFIED; 2582 rport->supported_classes = FC_COS_UNSPECIFIED;
2528 rport->dev_loss_tmo = fc_dev_loss_tmo; 2583 rport->dev_loss_tmo = fc_host->dev_loss_tmo;
2529 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name)); 2584 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name));
2530 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name)); 2585 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name));
2531 rport->port_id = ids->port_id; 2586 rport->port_id = ids->port_id;
@@ -3760,28 +3815,17 @@ fail_host_msg:
3760static void 3815static void
3761fc_bsg_goose_queue(struct fc_rport *rport) 3816fc_bsg_goose_queue(struct fc_rport *rport)
3762{ 3817{
3763 int flagset;
3764 unsigned long flags;
3765
3766 if (!rport->rqst_q) 3818 if (!rport->rqst_q)
3767 return; 3819 return;
3768 3820
3821 /*
3822 * This get/put dance makes no sense
3823 */
3769 get_device(&rport->dev); 3824 get_device(&rport->dev);
3770 3825 blk_run_queue_async(rport->rqst_q);
3771 spin_lock_irqsave(rport->rqst_q->queue_lock, flags);
3772 flagset = test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags) &&
3773 !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags);
3774 if (flagset)
3775 queue_flag_set(QUEUE_FLAG_REENTER, rport->rqst_q);
3776 __blk_run_queue(rport->rqst_q);
3777 if (flagset)
3778 queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q);
3779 spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags);
3780
3781 put_device(&rport->dev); 3826 put_device(&rport->dev);
3782} 3827}
3783 3828
3784
3785/** 3829/**
3786 * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD 3830 * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD
3787 * @q: rport request queue 3831 * @q: rport request queue
@@ -3857,7 +3901,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
3857 if (!get_device(dev)) 3901 if (!get_device(dev))
3858 return; 3902 return;
3859 3903
3860 while (!blk_queue_plugged(q)) { 3904 while (1) {
3861 if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) && 3905 if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) &&
3862 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)) 3906 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
3863 break; 3907 break;
@@ -4044,11 +4088,54 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
4044/** 4088/**
4045 * fc_bsg_remove - Deletes the bsg hooks on fchosts/rports 4089 * fc_bsg_remove - Deletes the bsg hooks on fchosts/rports
4046 * @q: the request_queue that is to be torn down. 4090 * @q: the request_queue that is to be torn down.
4091 *
4092 * Notes:
4093 * Before unregistering the queue empty any requests that are blocked
4094 *
4095 *
4047 */ 4096 */
4048static void 4097static void
4049fc_bsg_remove(struct request_queue *q) 4098fc_bsg_remove(struct request_queue *q)
4050{ 4099{
4100 struct request *req; /* block request */
4101 int counts; /* totals for request_list count and starved */
4102
4051 if (q) { 4103 if (q) {
4104 /* Stop taking in new requests */
4105 spin_lock_irq(q->queue_lock);
4106 blk_stop_queue(q);
4107
4108 /* drain all requests in the queue */
4109 while (1) {
4110 /* need the lock to fetch a request
4111 * this may fetch the same reqeust as the previous pass
4112 */
4113 req = blk_fetch_request(q);
4114 /* save requests in use and starved */
4115 counts = q->rq.count[0] + q->rq.count[1] +
4116 q->rq.starved[0] + q->rq.starved[1];
4117 spin_unlock_irq(q->queue_lock);
4118 /* any requests still outstanding? */
4119 if (counts == 0)
4120 break;
4121
4122 /* This may be the same req as the previous iteration,
4123 * always send the blk_end_request_all after a prefetch.
4124 * It is not okay to not end the request because the
4125 * prefetch started the request.
4126 */
4127 if (req) {
4128 /* return -ENXIO to indicate that this queue is
4129 * going away
4130 */
4131 req->errors = -ENXIO;
4132 blk_end_request_all(req, -ENXIO);
4133 }
4134
4135 msleep(200); /* allow bsg to possibly finish */
4136 spin_lock_irq(q->queue_lock);
4137 }
4138
4052 bsg_unregister_queue(q); 4139 bsg_unregister_queue(q);
4053 blk_cleanup_queue(q); 4140 blk_cleanup_queue(q);
4054 } 4141 }