@@ -446,13 +446,6 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
446446 return - ENOMEM ;
447447
448448 fc_host -> dev_loss_tmo = fc_dev_loss_tmo ;
449- fc_host -> devloss_work_q = alloc_workqueue ("fc_dl_%d" , 0 , 0 ,
450- shost -> host_no );
451- if (!fc_host -> devloss_work_q ) {
452- destroy_workqueue (fc_host -> work_q );
453- fc_host -> work_q = NULL ;
454- return - ENOMEM ;
455- }
456449
457450 fc_bsg_hostadd (shost , fc_host );
458451 /* ignore any bsg add error - we just can't do sgio */
@@ -2821,10 +2814,10 @@ fc_flush_work(struct Scsi_Host *shost)
28212814 * 1 on success / 0 already queued / < 0 for error
28222815 */
28232816static int
2824- fc_queue_devloss_work (struct Scsi_Host * shost , struct delayed_work * work ,
2825- unsigned long delay )
2817+ fc_queue_devloss_work (struct Scsi_Host * shost , struct fc_rport * rport ,
2818+ struct delayed_work * work , unsigned long delay )
28262819{
2827- if (unlikely (!fc_host_devloss_work_q ( shost ) )) {
2820+ if (unlikely (!rport -> devloss_work_q )) {
28282821 printk (KERN_ERR
28292822 "ERROR: FC host '%s' attempted to queue work, "
28302823 "when no workqueue created.\n" , shost -> hostt -> name );
@@ -2833,25 +2826,25 @@ fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work,
28332826 return - EINVAL ;
28342827 }
28352828
2836- return queue_delayed_work (fc_host_devloss_work_q ( shost ) , work , delay );
2829+ return queue_delayed_work (rport -> devloss_work_q , work , delay );
28372830}
28382831
28392832/**
28402833 * fc_flush_devloss - Flush a fc_host's devloss workqueue.
28412834 * @shost: Pointer to Scsi_Host bound to fc_host.
28422835 */
28432836static void
2844- fc_flush_devloss (struct Scsi_Host * shost )
2837+ fc_flush_devloss (struct Scsi_Host * shost , struct fc_rport * rport )
28452838{
2846- if (! fc_host_devloss_work_q ( shost )) {
2839+ if (unlikely (! rport -> devloss_work_q )) {
28472840 printk (KERN_ERR
28482841 "ERROR: FC host '%s' attempted to flush work, "
28492842 "when no workqueue created.\n" , shost -> hostt -> name );
28502843 dump_stack ();
28512844 return ;
28522845 }
28532846
2854- flush_workqueue (fc_host_devloss_work_q ( shost ) );
2847+ flush_workqueue (rport -> devloss_work_q );
28552848}
28562849
28572850
@@ -2913,13 +2906,6 @@ fc_remove_host(struct Scsi_Host *shost)
29132906 fc_host -> work_q = NULL ;
29142907 destroy_workqueue (work_q );
29152908 }
2916-
2917- /* flush all devloss work items, then kill it */
2918- if (fc_host -> devloss_work_q ) {
2919- work_q = fc_host -> devloss_work_q ;
2920- fc_host -> devloss_work_q = NULL ;
2921- destroy_workqueue (work_q );
2922- }
29232909}
29242910EXPORT_SYMBOL (fc_remove_host );
29252911
@@ -2967,6 +2953,7 @@ fc_rport_final_delete(struct work_struct *work)
29672953 struct device * dev = & rport -> dev ;
29682954 struct Scsi_Host * shost = rport_to_shost (rport );
29692955 struct fc_internal * i = to_fc_internal (shost -> transportt );
2956+ struct workqueue_struct * work_q ;
29702957 unsigned long flags ;
29712958 int do_callback = 0 ;
29722959
@@ -2988,9 +2975,9 @@ fc_rport_final_delete(struct work_struct *work)
29882975 if (rport -> flags & FC_RPORT_DEVLOSS_PENDING ) {
29892976 spin_unlock_irqrestore (shost -> host_lock , flags );
29902977 if (!cancel_delayed_work (& rport -> fail_io_work ))
2991- fc_flush_devloss (shost );
2978+ fc_flush_devloss (shost , rport );
29922979 if (!cancel_delayed_work (& rport -> dev_loss_work ))
2993- fc_flush_devloss (shost );
2980+ fc_flush_devloss (shost , rport );
29942981 cancel_work_sync (& rport -> scan_work );
29952982 spin_lock_irqsave (shost -> host_lock , flags );
29962983 rport -> flags &= ~FC_RPORT_DEVLOSS_PENDING ;
@@ -3021,6 +3008,12 @@ fc_rport_final_delete(struct work_struct *work)
30213008
30223009 fc_bsg_remove (rport -> rqst_q );
30233010
3011+ if (rport -> devloss_work_q ) {
3012+ work_q = rport -> devloss_work_q ;
3013+ rport -> devloss_work_q = NULL ;
3014+ destroy_workqueue (work_q );
3015+ }
3016+
30243017 transport_remove_device (dev );
30253018 device_del (dev );
30263019 transport_destroy_device (dev );
@@ -3093,6 +3086,22 @@ fc_remote_port_create(struct Scsi_Host *shost, int channel,
30933086
30943087 spin_unlock_irqrestore (shost -> host_lock , flags );
30953088
3089+ rport -> devloss_work_q = alloc_workqueue ("fc_dl_%d_%d" , 0 , 0 ,
3090+ shost -> host_no , rport -> number );
3091+ if (!rport -> devloss_work_q ) {
3092+ printk (KERN_ERR "FC Remote Port alloc_workqueue failed\n" );
3093+ /*
3094+ * Note that we have not yet called device_initialize() / get_device()
3095+ * Cannot reclaim incremented rport->number because we released host_lock
3096+ */
3097+ spin_lock_irqsave (shost -> host_lock , flags );
3098+ list_del (& rport -> peers );
3099+ scsi_host_put (shost ); /* for fc_host->rport list */
3100+ spin_unlock_irqrestore (shost -> host_lock , flags );
3101+ kfree (rport );
3102+ return NULL ;
3103+ }
3104+
30963105 dev = & rport -> dev ;
30973106 device_initialize (dev ); /* takes self reference */
30983107 dev -> parent = get_device (& shost -> shost_gendev ); /* parent reference */
@@ -3255,9 +3264,9 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
32553264 * be checked and will NOOP the function.
32563265 */
32573266 if (!cancel_delayed_work (& rport -> fail_io_work ))
3258- fc_flush_devloss (shost );
3267+ fc_flush_devloss (shost , rport );
32593268 if (!cancel_delayed_work (& rport -> dev_loss_work ))
3260- fc_flush_devloss (shost );
3269+ fc_flush_devloss (shost , rport );
32613270
32623271 spin_lock_irqsave (shost -> host_lock , flags );
32633272
@@ -3451,11 +3460,12 @@ fc_remote_port_delete(struct fc_rport *rport)
34513460 /* see if we need to kill io faster than waiting for device loss */
34523461 if ((rport -> fast_io_fail_tmo != -1 ) &&
34533462 (rport -> fast_io_fail_tmo < timeout ))
3454- fc_queue_devloss_work (shost , & rport -> fail_io_work ,
3455- rport -> fast_io_fail_tmo * HZ );
3463+ fc_queue_devloss_work (shost , rport , & rport -> fail_io_work ,
3464+ rport -> fast_io_fail_tmo * HZ );
34563465
34573466 /* cap the length the devices can be blocked until they are deleted */
3458- fc_queue_devloss_work (shost , & rport -> dev_loss_work , timeout * HZ );
3467+ fc_queue_devloss_work (shost , rport , & rport -> dev_loss_work ,
3468+ timeout * HZ );
34593469}
34603470EXPORT_SYMBOL (fc_remote_port_delete );
34613471
@@ -3514,9 +3524,9 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
35143524 * transaction.
35153525 */
35163526 if (!cancel_delayed_work (& rport -> fail_io_work ))
3517- fc_flush_devloss (shost );
3527+ fc_flush_devloss (shost , rport );
35183528 if (!cancel_delayed_work (& rport -> dev_loss_work ))
3519- fc_flush_devloss (shost );
3529+ fc_flush_devloss (shost , rport );
35203530
35213531 spin_lock_irqsave (shost -> host_lock , flags );
35223532 rport -> flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
0 commit comments