@@ -2346,13 +2346,13 @@ static int nvme_active_ctrls(struct nvme_subsystem *subsys)
2346
2346
int count = 0 ;
2347
2347
struct nvme_ctrl * ctrl ;
2348
2348
2349
- mutex_lock (& subsys -> lock );
2349
+ lockdep_assert_held (& nvme_subsystems_lock );
2350
+
2350
2351
list_for_each_entry (ctrl , & subsys -> ctrls , subsys_entry ) {
2351
2352
if (ctrl -> state != NVME_CTRL_DELETING &&
2352
2353
ctrl -> state != NVME_CTRL_DEAD )
2353
2354
count ++ ;
2354
2355
}
2355
- mutex_unlock (& subsys -> lock );
2356
2356
2357
2357
return count ;
2358
2358
}
@@ -2394,6 +2394,9 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
2394
2394
mutex_lock (& nvme_subsystems_lock );
2395
2395
found = __nvme_find_get_subsystem (subsys -> subnqn );
2396
2396
if (found ) {
2397
+ __nvme_release_subsystem (subsys );
2398
+ subsys = found ;
2399
+
2397
2400
/*
2398
2401
* Verify that the subsystem actually supports multiple
2399
2402
* controllers, else bail out.
@@ -2402,14 +2405,10 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
2402
2405
nvme_active_ctrls (found ) && !(id -> cmic & (1 << 1 ))) {
2403
2406
dev_err (ctrl -> device ,
2404
2407
"ignoring ctrl due to duplicate subnqn (%s).\n" ,
2405
- found -> subnqn );
2406
- nvme_put_subsystem (found );
2408
+ subsys -> subnqn );
2407
2409
ret = - EINVAL ;
2408
- goto out_unlock ;
2410
+ goto out_put_subsystem ;
2409
2411
}
2410
-
2411
- __nvme_release_subsystem (subsys );
2412
- subsys = found ;
2413
2412
} else {
2414
2413
ret = device_add (& subsys -> dev );
2415
2414
if (ret ) {
@@ -2421,23 +2420,20 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
2421
2420
list_add_tail (& subsys -> entry , & nvme_subsystems );
2422
2421
}
2423
2422
2424
- ctrl -> subsys = subsys ;
2425
- mutex_unlock (& nvme_subsystems_lock );
2426
-
2427
2423
if (sysfs_create_link (& subsys -> dev .kobj , & ctrl -> device -> kobj ,
2428
2424
dev_name (ctrl -> device ))) {
2429
2425
dev_err (ctrl -> device ,
2430
2426
"failed to create sysfs link from subsystem.\n" );
2431
- /* the transport driver will eventually put the subsystem */
2432
- return - EINVAL ;
2427
+ goto out_put_subsystem ;
2433
2428
}
2434
2429
2435
- mutex_lock ( & subsys -> lock ) ;
2430
+ ctrl -> subsys = subsys ;
2436
2431
list_add_tail (& ctrl -> subsys_entry , & subsys -> ctrls );
2437
- mutex_unlock (& subsys -> lock );
2438
-
2432
+ mutex_unlock (& nvme_subsystems_lock );
2439
2433
return 0 ;
2440
2434
2435
+ out_put_subsystem :
2436
+ nvme_put_subsystem (subsys );
2441
2437
out_unlock :
2442
2438
mutex_unlock (& nvme_subsystems_lock );
2443
2439
put_device (& subsys -> dev );
@@ -3694,10 +3690,10 @@ static void nvme_free_ctrl(struct device *dev)
3694
3690
__free_page (ctrl -> discard_page );
3695
3691
3696
3692
if (subsys ) {
3697
- mutex_lock (& subsys -> lock );
3693
+ mutex_lock (& nvme_subsystems_lock );
3698
3694
list_del (& ctrl -> subsys_entry );
3699
- mutex_unlock (& subsys -> lock );
3700
3695
sysfs_remove_link (& subsys -> dev .kobj , dev_name (ctrl -> device ));
3696
+ mutex_unlock (& nvme_subsystems_lock );
3701
3697
}
3702
3698
3703
3699
ctrl -> ops -> free_ctrl (ctrl );
0 commit comments