net/smc: longer delay for client link group removal
authorUrsula Braun <ubraun@linux.vnet.ibm.com>
Thu, 21 Sep 2017 07:16:31 +0000 (09:16 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 21 Sep 2017 22:31:03 +0000 (15:31 -0700)
Client link group creation always follows the server linkgroup creation.
If peer creates a new server link group, client has to create a new
client link group. If peer reuses a server link group for a new
connection, client has to reuse its client link group as well. This
patch introduces a longer delay for client link group removal to make
sure this link group still exists, once the peer decides to reuse a
server link group. This avoids out-of-sync conditions for link groups.
If already scheduled, modify the delay.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/smc_core.c

index 1a16d51e2330bb43de8bdd67c18f8b03c1e3ee92..20b66e79c5d6305dddf120f09249654732842c00 100644 (file)
@@ -25,8 +25,9 @@
 #include "smc_cdc.h"
 #include "smc_close.h"
 
-#define SMC_LGR_NUM_INCR       256
-#define SMC_LGR_FREE_DELAY     (600 * HZ)
+#define SMC_LGR_NUM_INCR               256
+#define SMC_LGR_FREE_DELAY_SERV                (600 * HZ)
+#define SMC_LGR_FREE_DELAY_CLNT                (SMC_LGR_FREE_DELAY_SERV + 10)
 
 static u32 smc_lgr_num;                        /* unique link group number */
 
@@ -107,8 +108,15 @@ static void smc_lgr_unregister_conn(struct smc_connection *conn)
                __smc_lgr_unregister_conn(conn);
        }
        write_unlock_bh(&lgr->conns_lock);
-       if (reduced && !lgr->conns_num)
-               schedule_delayed_work(&lgr->free_work, SMC_LGR_FREE_DELAY);
+       if (!reduced || lgr->conns_num)
+               return;
+       /* client link group creation always follows the server link group
+        * creation. For client use a somewhat higher removal delay time,
+        * otherwise there is a risk of out-of-sync link groups.
+        */
+       mod_delayed_work(system_wq, &lgr->free_work,
+                        lgr->role == SMC_CLNT ? SMC_LGR_FREE_DELAY_CLNT :
+                                                SMC_LGR_FREE_DELAY_SERV);
 }
 
 static void smc_lgr_free_work(struct work_struct *work)