afs: Avoid NatPing event on all connection 12/14312/3
authorYadavendra Yadav <yadayada@in.ibm.com>
Thu, 20 Aug 2020 20:24:00 +0000 (01:24 +0530)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 28 Aug 2020 16:10:40 +0000 (12:10 -0400)
Inside release_conns_user_server, connection vector is traversed and after
destroying a connection new eligible connection is found on which NatPing
event will be set. Ideally there should be only one connection on which
NatPing should be set but in current code while traversing all connection
of server a NatPing event is set on all connections to that server. In
cases where we have large number of connection to a server this can lead
to huge number of “RX_PACKET_TYPE_VERSION” packets sent to a server.
Since this happen during Garbage collection of user structs, to simulate
this issue below steps were tried

  - had one script which “cd” to a volume mount and then script sleeps for
    large time.
  - Ran one infinite while loop where above script was called using PAG
    based tokens (As new connection will be created for each PAG)
  - Instrumented the code, so that we hit above code segment where NatPing
    event is set. Mainly reduced NOTOKTIMEOUT to 60 sec.

To fix this issue set NatPing on one connection and once it is set break
from “for” loop traversing the server connection.

Change-Id: Ia38cec0403fde76cdd59aa664bd261481e2edee6
Reviewed-on: https://gerrit.openafs.org/14312
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>

src/afs/afs_conn.c

index fa6ed4d..92d36af 100644 (file)
@@ -152,7 +152,10 @@ release_conns_user_server(struct unixuser *xu, struct server *xs)
                        if (sa->natping == tc) {
                            int cin;
                            struct afs_conn *tcn;
+                           sa->natping = NULL;
                            for (tcvn = sa->conns; tcvn; tcvn = tcvn->next) {
+                               if (sa->natping != NULL)
+                                   break;
                                if (tcvn == tcv)
                                    continue;
                                for(cin = 0; cin < CVEC_LEN; ++cin) {