@@ -1849,16 +1849,20 @@ static int srpt_disconnect_ch(struct srpt_rdma_ch *ch)
1849
1849
1850
1850
static bool srpt_ch_closed (struct srpt_port * sport , struct srpt_rdma_ch * ch )
1851
1851
{
1852
+ struct srpt_nexus * nexus ;
1852
1853
struct srpt_rdma_ch * ch2 ;
1853
1854
bool res = true;
1854
1855
1855
1856
rcu_read_lock ();
1856
- list_for_each_entry (ch2 , & sport -> rch_list , list ) {
1857
- if (ch2 == ch ) {
1858
- res = false;
1859
- break ;
1857
+ list_for_each_entry (nexus , & sport -> nexus_list , entry ) {
1858
+ list_for_each_entry (ch2 , & nexus -> ch_list , list ) {
1859
+ if (ch2 == ch ) {
1860
+ res = false;
1861
+ goto done ;
1862
+ }
1860
1863
}
1861
1864
}
1865
+ done :
1862
1866
rcu_read_unlock ();
1863
1867
1864
1868
return res ;
@@ -1891,30 +1895,78 @@ static bool srpt_disconnect_ch_sync(struct srpt_rdma_ch *ch)
1891
1895
return ret == 0 ;
1892
1896
}
1893
1897
1894
- static void srpt_set_enabled (struct srpt_port * sport , bool enabled )
1895
- __must_hold (& sport - > mutex )
1898
+ static void __srpt_close_all_ch (struct srpt_port * sport )
1896
1899
{
1900
+ struct srpt_nexus * nexus ;
1897
1901
struct srpt_rdma_ch * ch ;
1898
1902
1899
1903
lockdep_assert_held (& sport -> mutex );
1900
1904
1901
- if (sport -> enabled == enabled )
1902
- return ;
1903
- sport -> enabled = enabled ;
1904
- if (sport -> enabled )
1905
- return ;
1905
+ list_for_each_entry (nexus , & sport -> nexus_list , entry ) {
1906
+ list_for_each_entry (ch , & nexus -> ch_list , list ) {
1907
+ if (srpt_disconnect_ch (ch ) >= 0 )
1908
+ pr_info ("Closing channel %s-%d because target %s_%d has been disabled\n" ,
1909
+ ch -> sess_name , ch -> qp -> qp_num ,
1910
+ sport -> sdev -> device -> name , sport -> port );
1911
+ srpt_close_ch (ch );
1912
+ }
1913
+ }
1914
+ }
1915
+
1916
+ /*
1917
+ * Look up (i_port_id, t_port_id) in sport->nexus_list. Create an entry if
1918
+ * it does not yet exist.
1919
+ */
1920
+ static struct srpt_nexus * srpt_get_nexus (struct srpt_port * sport ,
1921
+ const u8 i_port_id [16 ],
1922
+ const u8 t_port_id [16 ])
1923
+ {
1924
+ struct srpt_nexus * nexus = NULL , * tmp_nexus = NULL , * n ;
1906
1925
1907
- again :
1908
- list_for_each_entry (ch , & sport -> rch_list , list ) {
1909
- if (ch -> sport == sport ) {
1910
- pr_info ("%s: closing channel %s-%d\n" ,
1911
- sport -> sdev -> device -> name , ch -> sess_name ,
1912
- ch -> qp -> qp_num );
1913
- if (srpt_disconnect_ch_sync (ch ))
1914
- goto again ;
1926
+ for (;;) {
1927
+ mutex_lock (& sport -> mutex );
1928
+ list_for_each_entry (n , & sport -> nexus_list , entry ) {
1929
+ if (memcmp (n -> i_port_id , i_port_id , 16 ) == 0 &&
1930
+ memcmp (n -> t_port_id , t_port_id , 16 ) == 0 ) {
1931
+ nexus = n ;
1932
+ break ;
1933
+ }
1934
+ }
1935
+ if (!nexus && tmp_nexus ) {
1936
+ list_add_tail_rcu (& tmp_nexus -> entry ,
1937
+ & sport -> nexus_list );
1938
+ swap (nexus , tmp_nexus );
1915
1939
}
1940
+ mutex_unlock (& sport -> mutex );
1941
+
1942
+ if (nexus )
1943
+ break ;
1944
+ tmp_nexus = kzalloc (sizeof (* nexus ), GFP_KERNEL );
1945
+ if (!tmp_nexus ) {
1946
+ nexus = ERR_PTR (- ENOMEM );
1947
+ break ;
1948
+ }
1949
+ init_rcu_head (& tmp_nexus -> rcu );
1950
+ INIT_LIST_HEAD (& tmp_nexus -> ch_list );
1951
+ memcpy (tmp_nexus -> i_port_id , i_port_id , 16 );
1952
+ memcpy (tmp_nexus -> t_port_id , t_port_id , 16 );
1916
1953
}
1917
1954
1955
+ kfree (tmp_nexus );
1956
+
1957
+ return nexus ;
1958
+ }
1959
+
1960
+ static void srpt_set_enabled (struct srpt_port * sport , bool enabled )
1961
+ __must_hold (& sport - > mutex )
1962
+ {
1963
+ lockdep_assert_held (& sport -> mutex );
1964
+
1965
+ if (sport -> enabled == enabled )
1966
+ return ;
1967
+ sport -> enabled = enabled ;
1968
+ if (!enabled )
1969
+ __srpt_close_all_ch (sport );
1918
1970
}
1919
1971
1920
1972
static void srpt_free_ch (struct kref * kref )
@@ -1984,11 +2036,12 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
1984
2036
{
1985
2037
struct srpt_device * sdev = cm_id -> context ;
1986
2038
struct srpt_port * sport = & sdev -> port [param -> port - 1 ];
2039
+ struct srpt_nexus * nexus ;
1987
2040
struct srp_login_req * req ;
1988
- struct srp_login_rsp * rsp ;
1989
- struct srp_login_rej * rej ;
1990
- struct ib_cm_rep_param * rep_param ;
1991
- struct srpt_rdma_ch * ch , * tmp_ch ;
2041
+ struct srp_login_rsp * rsp = NULL ;
2042
+ struct srp_login_rej * rej = NULL ;
2043
+ struct ib_cm_rep_param * rep_param = NULL ;
2044
+ struct srpt_rdma_ch * ch ;
1992
2045
char i_port_id [36 ];
1993
2046
u32 it_iu_len ;
1994
2047
int i , ret = 0 ;
@@ -2007,6 +2060,13 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
2007
2060
param -> port , & sport -> gid ,
2008
2061
be16_to_cpu (param -> primary_path -> pkey ));
2009
2062
2063
+ nexus = srpt_get_nexus (sport , req -> initiator_port_id ,
2064
+ req -> target_port_id );
2065
+ if (IS_ERR (nexus )) {
2066
+ ret = PTR_ERR (nexus );
2067
+ goto out ;
2068
+ }
2069
+
2010
2070
rsp = kzalloc (sizeof (* rsp ), GFP_KERNEL );
2011
2071
rej = kzalloc (sizeof (* rej ), GFP_KERNEL );
2012
2072
rep_param = kzalloc (sizeof (* rep_param ), GFP_KERNEL );
@@ -2036,29 +2096,22 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
2036
2096
}
2037
2097
2038
2098
if ((req -> req_flags & SRP_MTCH_ACTION ) == SRP_MULTICHAN_SINGLE ) {
2099
+ struct srpt_rdma_ch * ch2 ;
2100
+
2039
2101
rsp -> rsp_flags = SRP_LOGIN_RSP_MULTICHAN_NO_CHAN ;
2040
2102
2041
2103
mutex_lock (& sport -> mutex );
2042
-
2043
- list_for_each_entry_safe (ch , tmp_ch , & sport -> rch_list , list ) {
2044
- if (!memcmp (ch -> i_port_id , req -> initiator_port_id , 16 )
2045
- && !memcmp (ch -> t_port_id , req -> target_port_id , 16 )
2046
- && param -> port == ch -> sport -> port
2047
- && param -> listen_id == ch -> sport -> sdev -> cm_id
2048
- && ch -> cm_id ) {
2049
- if (srpt_disconnect_ch (ch ) < 0 )
2050
- continue ;
2051
- pr_info ("Relogin - closed existing channel %s\n" ,
2052
- ch -> sess_name );
2053
- rsp -> rsp_flags =
2054
- SRP_LOGIN_RSP_MULTICHAN_TERMINATED ;
2055
- }
2104
+ list_for_each_entry (ch2 , & nexus -> ch_list , list ) {
2105
+ if (srpt_disconnect_ch (ch2 ) < 0 )
2106
+ continue ;
2107
+ pr_info ("Relogin - closed existing channel %s\n" ,
2108
+ ch2 -> sess_name );
2109
+ rsp -> rsp_flags = SRP_LOGIN_RSP_MULTICHAN_TERMINATED ;
2056
2110
}
2057
-
2058
2111
mutex_unlock (& sport -> mutex );
2059
-
2060
- } else
2112
+ } else {
2061
2113
rsp -> rsp_flags = SRP_LOGIN_RSP_MULTICHAN_MAINTAINED ;
2114
+ }
2062
2115
2063
2116
if (* (__be64 * )req -> target_port_id != cpu_to_be64 (srpt_service_guid )
2064
2117
|| * (__be64 * )(req -> target_port_id + 8 ) !=
@@ -2083,10 +2136,9 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
2083
2136
init_rcu_head (& ch -> rcu );
2084
2137
kref_init (& ch -> kref );
2085
2138
ch -> pkey = be16_to_cpu (param -> primary_path -> pkey );
2139
+ ch -> nexus = nexus ;
2086
2140
ch -> zw_cqe .done = srpt_zerolength_write_done ;
2087
2141
INIT_WORK (& ch -> release_work , srpt_release_channel_work );
2088
- memcpy (ch -> i_port_id , req -> initiator_port_id , 16 );
2089
- memcpy (ch -> t_port_id , req -> target_port_id , 16 );
2090
2142
ch -> sport = & sdev -> port [param -> port - 1 ];
2091
2143
ch -> cm_id = cm_id ;
2092
2144
cm_id -> context = ch ;
@@ -2147,8 +2199,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
2147
2199
srpt_format_guid (ch -> sess_name , sizeof (ch -> sess_name ),
2148
2200
& param -> primary_path -> dgid .global .interface_id );
2149
2201
snprintf (i_port_id , sizeof (i_port_id ), "0x%016llx%016llx" ,
2150
- be64_to_cpu (* (__be64 * )ch -> i_port_id ),
2151
- be64_to_cpu (* (__be64 * )(ch -> i_port_id + 8 )));
2202
+ be64_to_cpu (* (__be64 * )nexus -> i_port_id ),
2203
+ be64_to_cpu (* (__be64 * )(nexus -> i_port_id + 8 )));
2152
2204
2153
2205
pr_debug ("registering session %s\n" , ch -> sess_name );
2154
2206
@@ -2208,7 +2260,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
2208
2260
}
2209
2261
2210
2262
mutex_lock (& sport -> mutex );
2211
- list_add_tail_rcu (& ch -> list , & sport -> rch_list );
2263
+ list_add_tail_rcu (& ch -> list , & nexus -> ch_list );
2212
2264
mutex_unlock (& sport -> mutex );
2213
2265
2214
2266
goto out ;
@@ -2560,24 +2612,56 @@ static void srpt_refresh_port_work(struct work_struct *work)
2560
2612
srpt_refresh_port (sport );
2561
2613
}
2562
2614
2615
+ static bool srpt_ch_list_empty (struct srpt_port * sport )
2616
+ {
2617
+ struct srpt_nexus * nexus ;
2618
+ bool res = true;
2619
+
2620
+ rcu_read_lock ();
2621
+ list_for_each_entry (nexus , & sport -> nexus_list , entry )
2622
+ if (!list_empty (& nexus -> ch_list ))
2623
+ res = false;
2624
+ rcu_read_unlock ();
2625
+
2626
+ return res ;
2627
+ }
2628
+
2563
2629
/**
2564
2630
* srpt_release_sport - disable login and wait for associated channels
2565
2631
* @sport: SRPT HCA port.
2566
2632
*/
2567
2633
static int srpt_release_sport (struct srpt_port * sport )
2568
2634
{
2569
- int res ;
2635
+ struct srpt_nexus * nexus , * next_n ;
2636
+ struct srpt_rdma_ch * ch ;
2570
2637
2571
2638
WARN_ON_ONCE (irqs_disabled ());
2572
2639
2573
2640
mutex_lock (& sport -> mutex );
2574
2641
srpt_set_enabled (sport , false);
2575
2642
mutex_unlock (& sport -> mutex );
2576
2643
2577
- res = wait_event_interruptible (sport -> ch_releaseQ ,
2578
- list_empty_careful (& sport -> rch_list ));
2579
- if (res )
2580
- pr_err ("%s: interrupted.\n" , __func__ );
2644
+ while (wait_event_timeout (sport -> ch_releaseQ ,
2645
+ srpt_ch_list_empty (sport ), 5 * HZ ) <= 0 ) {
2646
+ pr_info ("%s_%d: waiting for session unregistration ...\n" ,
2647
+ sport -> sdev -> device -> name , sport -> port );
2648
+ rcu_read_lock ();
2649
+ list_for_each_entry (nexus , & sport -> nexus_list , entry ) {
2650
+ list_for_each_entry (ch , & nexus -> ch_list , list ) {
2651
+ pr_info ("%s-%d: state %s\n" ,
2652
+ ch -> sess_name , ch -> qp -> qp_num ,
2653
+ get_ch_state_name (ch -> state ));
2654
+ }
2655
+ }
2656
+ rcu_read_unlock ();
2657
+ }
2658
+
2659
+ mutex_lock (& sport -> mutex );
2660
+ list_for_each_entry_safe (nexus , next_n , & sport -> nexus_list , entry ) {
2661
+ list_del (& nexus -> entry );
2662
+ kfree_rcu (nexus , rcu );
2663
+ }
2664
+ mutex_unlock (& sport -> mutex );
2581
2665
2582
2666
return 0 ;
2583
2667
}
@@ -2744,7 +2828,7 @@ static void srpt_add_one(struct ib_device *device)
2744
2828
2745
2829
for (i = 1 ; i <= sdev -> device -> phys_port_cnt ; i ++ ) {
2746
2830
sport = & sdev -> port [i - 1 ];
2747
- INIT_LIST_HEAD (& sport -> rch_list );
2831
+ INIT_LIST_HEAD (& sport -> nexus_list );
2748
2832
init_waitqueue_head (& sport -> ch_releaseQ );
2749
2833
mutex_init (& sport -> mutex );
2750
2834
sport -> sdev = sdev ;
0 commit comments