@@ -187,7 +187,6 @@ static int __init zfcp_module_init(void)
187
187
goto out_gid_cache ;
188
188
189
189
mutex_init (& zfcp_data .config_mutex );
190
- rwlock_init (& zfcp_data .config_lock );
191
190
192
191
zfcp_data .scsi_transport_template =
193
192
fc_attach_transport (& zfcp_transport_functions );
@@ -238,12 +237,18 @@ module_init(zfcp_module_init);
238
237
*/
239
238
struct zfcp_unit * zfcp_get_unit_by_lun (struct zfcp_port * port , u64 fcp_lun )
240
239
{
240
+ unsigned long flags ;
241
241
struct zfcp_unit * unit ;
242
242
243
- list_for_each_entry (unit , & port -> unit_list_head , list )
243
+ read_lock_irqsave (& port -> unit_list_lock , flags );
244
+ list_for_each_entry (unit , & port -> unit_list , list )
244
245
if ((unit -> fcp_lun == fcp_lun ) &&
245
- !(atomic_read (& unit -> status ) & ZFCP_STATUS_COMMON_REMOVE ))
246
- return unit ;
246
+ !(atomic_read (& unit -> status ) & ZFCP_STATUS_COMMON_REMOVE )) {
247
+ zfcp_unit_get (unit );
248
+ read_unlock_irqrestore (& port -> unit_list_lock , flags );
249
+ return unit ;
250
+ }
251
+ read_unlock_irqrestore (& port -> unit_list_lock , flags );
247
252
return NULL ;
248
253
}
249
254
@@ -257,12 +262,18 @@ struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
257
262
struct zfcp_port * zfcp_get_port_by_wwpn (struct zfcp_adapter * adapter ,
258
263
u64 wwpn )
259
264
{
265
+ unsigned long flags ;
260
266
struct zfcp_port * port ;
261
267
262
- list_for_each_entry (port , & adapter -> port_list_head , list )
268
+ read_lock_irqsave (& adapter -> port_list_lock , flags );
269
+ list_for_each_entry (port , & adapter -> port_list , list )
263
270
if ((port -> wwpn == wwpn ) &&
264
- !(atomic_read (& port -> status ) & ZFCP_STATUS_COMMON_REMOVE ))
271
+ !(atomic_read (& port -> status ) & ZFCP_STATUS_COMMON_REMOVE )) {
272
+ zfcp_port_get (port );
273
+ read_unlock_irqrestore (& adapter -> port_list_lock , flags );
265
274
return port ;
275
+ }
276
+ read_unlock_irqrestore (& adapter -> port_list_lock , flags );
266
277
return NULL ;
267
278
}
268
279
@@ -284,12 +295,11 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
284
295
{
285
296
struct zfcp_unit * unit ;
286
297
287
- read_lock_irq ( & zfcp_data . config_lock );
288
- if (zfcp_get_unit_by_lun ( port , fcp_lun ) ) {
289
- read_unlock_irq ( & zfcp_data . config_lock );
298
+ unit = zfcp_get_unit_by_lun ( port , fcp_lun );
299
+ if (unit ) {
300
+ zfcp_unit_put ( unit );
290
301
return ERR_PTR (- EINVAL );
291
302
}
292
- read_unlock_irq (& zfcp_data .config_lock );
293
303
294
304
unit = kzalloc (sizeof (struct zfcp_unit ), GFP_KERNEL );
295
305
if (!unit )
@@ -335,13 +345,13 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
335
345
336
346
zfcp_unit_get (unit );
337
347
338
- write_lock_irq (& zfcp_data .config_lock );
339
- list_add_tail (& unit -> list , & port -> unit_list_head );
348
+ write_lock_irq (& port -> unit_list_lock );
349
+ list_add_tail (& unit -> list , & port -> unit_list );
350
+ write_unlock_irq (& port -> unit_list_lock );
351
+
340
352
atomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , & unit -> status );
341
353
atomic_set_mask (ZFCP_STATUS_COMMON_RUNNING , & unit -> status );
342
354
343
- write_unlock_irq (& zfcp_data .config_lock );
344
-
345
355
zfcp_port_get (port );
346
356
347
357
return unit ;
@@ -356,11 +366,11 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
356
366
*/
357
367
void zfcp_unit_dequeue (struct zfcp_unit * unit )
358
368
{
369
+ struct zfcp_port * port = unit -> port ;
370
+
359
371
wait_event (unit -> remove_wq , atomic_read (& unit -> refcount ) == 0 );
360
- write_lock_irq (& zfcp_data .config_lock );
361
- list_del (& unit -> list );
362
- write_unlock_irq (& zfcp_data .config_lock );
363
- zfcp_port_put (unit -> port );
372
+ list_del (& unit -> list ); /* no list locking required */
373
+ zfcp_port_put (port );
364
374
sysfs_remove_group (& unit -> sysfs_device .kobj , & zfcp_sysfs_unit_attrs );
365
375
device_unregister (& unit -> sysfs_device );
366
376
}
@@ -539,11 +549,13 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
539
549
if (zfcp_fc_gs_setup (adapter ))
540
550
goto generic_services_failed ;
541
551
552
+ rwlock_init (& adapter -> port_list_lock );
553
+ INIT_LIST_HEAD (& adapter -> port_list );
554
+
542
555
init_waitqueue_head (& adapter -> remove_wq );
543
556
init_waitqueue_head (& adapter -> erp_ready_wq );
544
557
init_waitqueue_head (& adapter -> erp_done_wqh );
545
558
546
- INIT_LIST_HEAD (& adapter -> port_list_head );
547
559
INIT_LIST_HEAD (& adapter -> erp_ready_head );
548
560
INIT_LIST_HEAD (& adapter -> erp_running_head );
549
561
@@ -650,19 +662,20 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
650
662
{
651
663
struct zfcp_port * port ;
652
664
653
- read_lock_irq ( & zfcp_data . config_lock );
654
- if (zfcp_get_port_by_wwpn ( adapter , wwpn ) ) {
655
- read_unlock_irq ( & zfcp_data . config_lock );
656
- return ERR_PTR (- EINVAL );
665
+ port = zfcp_get_port_by_wwpn ( adapter , wwpn );
666
+ if (port ) {
667
+ zfcp_port_put ( port );
668
+ return ERR_PTR (- EEXIST );
657
669
}
658
- read_unlock_irq (& zfcp_data .config_lock );
659
670
660
671
port = kzalloc (sizeof (struct zfcp_port ), GFP_KERNEL );
661
672
if (!port )
662
673
return ERR_PTR (- ENOMEM );
663
674
675
+ rwlock_init (& port -> unit_list_lock );
676
+ INIT_LIST_HEAD (& port -> unit_list );
677
+
664
678
init_waitqueue_head (& port -> remove_wq );
665
- INIT_LIST_HEAD (& port -> unit_list_head );
666
679
INIT_WORK (& port -> gid_pn_work , zfcp_fc_port_did_lookup );
667
680
INIT_WORK (& port -> test_link_work , zfcp_fc_link_test_work );
668
681
INIT_WORK (& port -> rport_work , zfcp_scsi_rport_work );
@@ -698,13 +711,13 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
698
711
699
712
zfcp_port_get (port );
700
713
701
- write_lock_irq (& zfcp_data .config_lock );
702
- list_add_tail (& port -> list , & adapter -> port_list_head );
714
+ write_lock_irq (& adapter -> port_list_lock );
715
+ list_add_tail (& port -> list , & adapter -> port_list );
716
+ write_unlock_irq (& adapter -> port_list_lock );
717
+
703
718
atomic_clear_mask (ZFCP_STATUS_COMMON_REMOVE , & port -> status );
704
719
atomic_set_mask (ZFCP_STATUS_COMMON_RUNNING , & port -> status );
705
720
706
- write_unlock_irq (& zfcp_data .config_lock );
707
-
708
721
zfcp_adapter_get (adapter );
709
722
return port ;
710
723
}
@@ -715,12 +728,11 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
715
728
*/
716
729
void zfcp_port_dequeue (struct zfcp_port * port )
717
730
{
718
- write_lock_irq ( & zfcp_data . config_lock ) ;
719
- list_del ( & port -> list );
720
- write_unlock_irq ( & zfcp_data . config_lock );
731
+ struct zfcp_adapter * adapter = port -> adapter ;
732
+
733
+ list_del ( & port -> list ); /* no list locking required here */
721
734
wait_event (port -> remove_wq , atomic_read (& port -> refcount ) == 0 );
722
- cancel_work_sync (& port -> rport_work ); /* usually not necessary */
723
- zfcp_adapter_put (port -> adapter );
735
+ zfcp_adapter_put (adapter );
724
736
sysfs_remove_group (& port -> sysfs_device .kobj , & zfcp_sysfs_port_attrs );
725
737
device_unregister (& port -> sysfs_device );
726
738
}
0 commit comments