@@ -42,6 +42,19 @@ static struct smc_lgr_list smc_lgr_list = { /* established link groups */
42
42
static void smc_buf_free (struct smc_link_group * lgr , bool is_rmb ,
43
43
struct smc_buf_desc * buf_desc );
44
44
45
+ /* return head of link group list and its lock for a given link group */
46
+ static inline struct list_head * smc_lgr_list_head (struct smc_link_group * lgr ,
47
+ spinlock_t * * lgr_lock )
48
+ {
49
+ if (lgr -> is_smcd ) {
50
+ * lgr_lock = & lgr -> smcd -> lgr_lock ;
51
+ return & lgr -> smcd -> lgr_list ;
52
+ }
53
+
54
+ * lgr_lock = & smc_lgr_list .lock ;
55
+ return & smc_lgr_list .list ;
56
+ }
57
+
45
58
static void smc_lgr_schedule_free_work (struct smc_link_group * lgr )
46
59
{
47
60
/* client link group creation always follows the server link group
@@ -157,19 +170,21 @@ static void smc_lgr_free_work(struct work_struct *work)
157
170
struct smc_link_group * lgr = container_of (to_delayed_work (work ),
158
171
struct smc_link_group ,
159
172
free_work );
173
+ spinlock_t * lgr_lock ;
160
174
bool conns ;
161
175
162
- spin_lock_bh (& smc_lgr_list .lock );
176
+ smc_lgr_list_head (lgr , & lgr_lock );
177
+ spin_lock_bh (lgr_lock );
163
178
read_lock_bh (& lgr -> conns_lock );
164
179
conns = RB_EMPTY_ROOT (& lgr -> conns_all );
165
180
read_unlock_bh (& lgr -> conns_lock );
166
181
if (!conns ) { /* number of lgr connections is no longer zero */
167
- spin_unlock_bh (& smc_lgr_list . lock );
182
+ spin_unlock_bh (lgr_lock );
168
183
return ;
169
184
}
170
185
if (!list_empty (& lgr -> list ))
171
186
list_del_init (& lgr -> list ); /* remove from smc_lgr_list */
172
- spin_unlock_bh (& smc_lgr_list . lock );
187
+ spin_unlock_bh (lgr_lock );
173
188
174
189
if (!lgr -> is_smcd && !lgr -> terminating ) {
175
190
struct smc_link * lnk = & lgr -> lnk [SMC_SINGLE_LINK ];
@@ -200,6 +215,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
200
215
struct smc_link_group * lgr ;
201
216
struct list_head * lgr_list ;
202
217
struct smc_link * lnk ;
218
+ spinlock_t * lgr_lock ;
203
219
u8 rndvec [3 ];
204
220
int rc = 0 ;
205
221
int i ;
@@ -235,6 +251,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
235
251
lgr -> peer_gid = ini -> ism_gid ;
236
252
lgr -> smcd = ini -> ism_dev ;
237
253
lgr_list = & ini -> ism_dev -> lgr_list ;
254
+ lgr_lock = & lgr -> smcd -> lgr_lock ;
238
255
} else {
239
256
/* SMC-R specific settings */
240
257
lgr -> role = smc -> listen_smc ? SMC_SERV : SMC_CLNT ;
@@ -248,6 +265,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
248
265
lnk -> smcibdev = ini -> ib_dev ;
249
266
lnk -> ibport = ini -> ib_port ;
250
267
lgr_list = & smc_lgr_list .list ;
268
+ lgr_lock = & smc_lgr_list .lock ;
251
269
lnk -> path_mtu =
252
270
ini -> ib_dev -> pattr [ini -> ib_port - 1 ].active_mtu ;
253
271
if (!ini -> ib_dev -> initialized )
@@ -277,9 +295,9 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
277
295
goto destroy_qp ;
278
296
}
279
297
smc -> conn .lgr = lgr ;
280
- spin_lock_bh (& smc_lgr_list . lock );
298
+ spin_lock_bh (lgr_lock );
281
299
list_add (& lgr -> list , lgr_list );
282
- spin_unlock_bh (& smc_lgr_list . lock );
300
+ spin_unlock_bh (lgr_lock );
283
301
return 0 ;
284
302
285
303
destroy_qp :
@@ -442,11 +460,15 @@ static void smc_lgr_free(struct smc_link_group *lgr)
442
460
443
461
void smc_lgr_forget (struct smc_link_group * lgr )
444
462
{
445
- spin_lock_bh (& smc_lgr_list .lock );
463
+ struct list_head * lgr_list ;
464
+ spinlock_t * lgr_lock ;
465
+
466
+ lgr_list = smc_lgr_list_head (lgr , & lgr_lock );
467
+ spin_lock_bh (lgr_lock );
446
468
/* do not use this link group for new connections */
447
- if (!list_empty (& lgr -> list ))
448
- list_del_init (& lgr -> list );
449
- spin_unlock_bh (& smc_lgr_list . lock );
469
+ if (!list_empty (lgr_list ))
470
+ list_del_init (lgr_list );
471
+ spin_unlock_bh (lgr_lock );
450
472
}
451
473
452
474
/* terminate linkgroup abnormally */
@@ -487,9 +509,12 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr)
487
509
488
510
void smc_lgr_terminate (struct smc_link_group * lgr )
489
511
{
490
- spin_lock_bh (& smc_lgr_list .lock );
512
+ spinlock_t * lgr_lock ;
513
+
514
+ smc_lgr_list_head (lgr , & lgr_lock );
515
+ spin_lock_bh (lgr_lock );
491
516
__smc_lgr_terminate (lgr );
492
- spin_unlock_bh (& smc_lgr_list . lock );
517
+ spin_unlock_bh (lgr_lock );
493
518
}
494
519
495
520
/* Called when IB port is terminated */
@@ -514,15 +539,15 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, unsigned short vlan)
514
539
LIST_HEAD (lgr_free_list );
515
540
516
541
/* run common cleanup function and build free list */
517
- spin_lock_bh (& smc_lgr_list . lock );
542
+ spin_lock_bh (& dev -> lgr_lock );
518
543
list_for_each_entry_safe (lgr , l , & dev -> lgr_list , list ) {
519
544
if ((!peer_gid || lgr -> peer_gid == peer_gid ) &&
520
545
(vlan == VLAN_VID_MASK || lgr -> vlan_id == vlan )) {
521
546
__smc_lgr_terminate (lgr );
522
547
list_move (& lgr -> list , & lgr_free_list );
523
548
}
524
549
}
525
- spin_unlock_bh (& smc_lgr_list . lock );
550
+ spin_unlock_bh (& dev -> lgr_lock );
526
551
527
552
/* cancel the regular free workers and actually free lgrs */
528
553
list_for_each_entry_safe (lgr , l , & lgr_free_list , list ) {
@@ -609,17 +634,19 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
609
634
struct list_head * lgr_list ;
610
635
struct smc_link_group * lgr ;
611
636
enum smc_lgr_role role ;
637
+ spinlock_t * lgr_lock ;
612
638
int rc = 0 ;
613
639
614
640
lgr_list = ini -> is_smcd ? & ini -> ism_dev -> lgr_list : & smc_lgr_list .list ;
641
+ lgr_lock = ini -> is_smcd ? & ini -> ism_dev -> lgr_lock : & smc_lgr_list .lock ;
615
642
ini -> cln_first_contact = SMC_FIRST_CONTACT ;
616
643
role = smc -> listen_smc ? SMC_SERV : SMC_CLNT ;
617
644
if (role == SMC_CLNT && ini -> srv_first_contact )
618
645
/* create new link group as well */
619
646
goto create ;
620
647
621
648
/* determine if an existing link group can be reused */
622
- spin_lock_bh (& smc_lgr_list . lock );
649
+ spin_lock_bh (lgr_lock );
623
650
list_for_each_entry (lgr , lgr_list , list ) {
624
651
write_lock_bh (& lgr -> conns_lock );
625
652
if ((ini -> is_smcd ?
@@ -640,7 +667,7 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
640
667
}
641
668
write_unlock_bh (& lgr -> conns_lock );
642
669
}
643
- spin_unlock_bh (& smc_lgr_list . lock );
670
+ spin_unlock_bh (lgr_lock );
644
671
645
672
if (role == SMC_CLNT && !ini -> srv_first_contact &&
646
673
ini -> cln_first_contact == SMC_FIRST_CONTACT ) {
0 commit comments