summarylogtreecommitdiffstats
path: root/0029-afs-Drop-GLOCK-for-various-Rx-calls.patch
blob: 02b30b80d7b28f4726cb681470744072d1f09054 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
From 35c339ec6b648deb02f7598c02df07b0c2ad0021 Mon Sep 17 00:00:00 2001
From: Andrew Deason <adeason@dson.org>
Date: Sun, 3 May 2020 10:33:28 -0500
Subject: [PATCH 29/29] afs: Drop GLOCK for various Rx calls

Most calls into Rx from libafs do so without the AFS_GLOCK, but a few
pieces of code still hold AFS_GLOCK while making some Rx calls. A few
calls into Rx also currently require AFS_GLOCK, but drop AFS_GLOCK
internally, which is somewhat confusing/inconsistent. Calling Rx
functions with AFS_GLOCK held can potentially cause locking/allocation
problems on various platforms, such as FreeBSD where we get WITNESS
warnings about acquiring sleepable Rx locks while holding the
non-sleepable AFS_GLOCK.

Fix a variety of Rx calls from libafs to drop AFS_GLOCK before calling
into Rx. Specifically, this commit handles calls to rxi_GetIFInfo,
rx_InitHost, rx_StartServer, rx_ServerProc, rx_GetConnection,
rx_DestroyConnection/rx_PutConnection, and
rx_SetConnSecondsUntilNatPing.

For calls made via afs_start_thread, adjust afs_start_thread to accept
a new argument that says whether to acquire AFS_GLOCK for the relevant
function or not.

For a call to rx_InitHost inside afs_InitSetup, dropping GLOCK makes
it possible for another thread to also enter afs_InitSetup while we're
running, before afs_InitSetup_done is set. To prevent two threads from
running afs_InitSetup in parallel, introduce afs_InitSetup_running
(which is set while afs_InitSetup is running), and simply wait for it
to be cleared if it is set when we enter afs_InitSetup.

This commit does not handle strictly all calls into Rx from libafs,
since many Rx calls don't do anything interesting besides set some
internal variables, and so AFS_GLOCK doesn't really matter for them,
and dropping/reacquiring it around those calls may have performance
impact.

Reviewed-on: https://gerrit.openafs.org/14184
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
(cherry picked from commit d5e1428a3bd4a7fbb4401cf17176474f0c1825d3)

 Conflicts:
	src/afs/afs_call.c - context only due to not having commit:
	   'Log binding ip address and port during startup' (02dede5d40)

Change-Id: I0d14105d5dc8bfd4740c7a9adfc61c36f8a2318c
---
 src/afs/LINUX/osi_misc.c       | 22 +++++++++++++++++++---
 src/afs/LINUX/osi_prototypes.h |  2 +-
 src/afs/afs_call.c             | 19 ++++++++++++++++++-
 src/afs/afs_callback.c         |  2 ++
 src/afs/afs_conn.c             |  6 ++++++
 src/afs/afs_daemons.c          | 14 ++++++++------
 src/afs/afs_init.c             |  2 ++
 src/afs/afs_pag_call.c         | 15 ++++++++++-----
 src/rx/rx_kcommon.c            | 10 ----------
 9 files changed, 66 insertions(+), 26 deletions(-)

diff --git a/src/afs/LINUX/osi_misc.c b/src/afs/LINUX/osi_misc.c
index aa5d5fc93..be6984661 100644
--- a/src/afs/LINUX/osi_misc.c
+++ b/src/afs/LINUX/osi_misc.c
@@ -155,7 +155,18 @@ int osi_abspath(char *aname, char *buf, int buflen,
 
 
 /* This could use some work, and support on more platforms. */
-int afs_thread_wrapper(void *rock)
+static int
+afs_thread_wrapper(void *rock)
+{
+    void (*proc)(void) = rock;
+    __module_get(THIS_MODULE);
+    (*proc)();
+    module_put(THIS_MODULE);
+    return 0;
+}
+
+static int
+afs_thread_wrapper_glock(void *rock)
 {
     void (*proc)(void) = rock;
     __module_get(THIS_MODULE);
@@ -166,7 +177,12 @@ int afs_thread_wrapper(void *rock)
     return 0;
 }
 
-void afs_start_thread(void (*proc)(void), char *name)
+void
+afs_start_thread(void (*proc)(void), char *name, int needs_glock)
 {
-    kthread_run(afs_thread_wrapper, proc, "%s", name);
+    if (needs_glock) {
+	kthread_run(afs_thread_wrapper_glock, proc, "%s", name);
+    } else {
+	kthread_run(afs_thread_wrapper, proc, "%s", name);
+    }
 }
diff --git a/src/afs/LINUX/osi_prototypes.h b/src/afs/LINUX/osi_prototypes.h
index 130b5660e..2ed054339 100644
--- a/src/afs/LINUX/osi_prototypes.h
+++ b/src/afs/LINUX/osi_prototypes.h
@@ -50,7 +50,7 @@ extern int osi_lookupname(char *aname, uio_seg_t seg, int followlink,
 			  struct dentry **dpp);
 extern int osi_abspath(char *aname, char *buf, int buflen,
 		       int followlink, char **pathp);
-extern void afs_start_thread(void (*proc)(void), char *name);
+extern void afs_start_thread(void (*proc)(void), char *name, int needs_glock);
 
 /* osi_probe.c */
 extern void *osi_find_syscall_table(int which);
diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c
index 4ac63b187..7fb323c29 100644
--- a/src/afs/afs_call.c
+++ b/src/afs/afs_call.c
@@ -104,11 +104,19 @@ extern afs_int32 afs_md5inum;
 static int
 afs_InitSetup(int preallocs)
 {
+    static int afs_InitSetup_running;
+
     int code;
 
+    while (afs_InitSetup_running) {
+	afs_osi_Sleep(&afs_InitSetup_running);
+    }
+
     if (afs_InitSetup_done)
 	return EAGAIN;
 
+    afs_InitSetup_running = 1;
+
 #ifdef AFS_SUN510_ENV
     /* Initialize a RW lock for the ifinfo global array */
     rw_init(&afsifinfo_lock, NULL, RW_DRIVER, NULL);
@@ -133,10 +141,12 @@ afs_InitSetup(int preallocs)
     /* start RX */
     if(!afscall_set_rxpck_received)
     rx_extraPackets = AFS_NRXPACKETS;	/* smaller # of packets */
+    AFS_GUNLOCK();
     code = rx_InitHost(rx_bindhost, htons(7001));
+    AFS_GLOCK();
     if (code) {
 	afs_warn("AFS: RX failed to initialize %d).\n", code);
-	return code;
+	goto done;
     }
     rx_SetRxDeadTime(afs_rx_deadtime);
     /* resource init creates the services */
@@ -145,6 +155,9 @@ afs_InitSetup(int preallocs)
     afs_InitSetup_done = 1;
     afs_osi_Wakeup(&afs_InitSetup_done);
 
+ done:
+    afs_InitSetup_running = 0;
+    afs_osi_Wakeup(&afs_InitSetup_running);
     return code;
 }
 
@@ -1703,7 +1716,9 @@ afs_shutdown(enum afs_shutdown_type cold_flag)
     afs_warn("CB... ");
 
     afs_termState = AFSOP_STOP_RXCALLBACK;
+    AFS_GUNLOCK();
     rx_WakeupServerProcs();
+    AFS_GLOCK();
 #ifdef AFS_AIX51_ENV
     shutdown_rxkernel();
 #endif
@@ -1756,7 +1771,9 @@ afs_shutdown(enum afs_shutdown_type cold_flag)
     afs_warn("NetIfPoller... ");
     osi_StopNetIfPoller();
 #endif
+    AFS_GUNLOCK();
     rxi_FreeAllPackets();
+    AFS_GLOCK();
 
     afs_termState = AFSOP_STOP_COMPLETE;
 
diff --git a/src/afs/afs_callback.c b/src/afs/afs_callback.c
index 1fe990edf..7cffef6ff 100644
--- a/src/afs/afs_callback.c
+++ b/src/afs/afs_callback.c
@@ -985,7 +985,9 @@ afs_RXCallBackServer(void)
     /*
      * Donate this process to Rx.
      */
+    AFS_GUNLOCK();
     rx_ServerProc(NULL);
+    AFS_GLOCK();
     return (0);
 
 }				/*afs_RXCallBackServer */
diff --git a/src/afs/afs_conn.c b/src/afs/afs_conn.c
index 2a3a513b2..8728ce518 100644
--- a/src/afs/afs_conn.c
+++ b/src/afs/afs_conn.c
@@ -532,7 +532,9 @@ afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell,
 	 */
 	if ((service != 52) && (sap->natping == NULL)) {
 	    sap->natping = tc;
+	    AFS_GUNLOCK();
 	    rx_SetConnSecondsUntilNatPing(tc->id, 20);
+	    AFS_GLOCK();
 	}
 
 	tc->forceConnectFS = 0;	/* apparently we're appropriately connected now */
@@ -542,7 +544,9 @@ afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell,
     } /* end of if (tc->forceConnectFS)*/
 
     *rxconn = tc->id;
+    AFS_GUNLOCK();
     rx_GetConnection(*rxconn);
+    AFS_GLOCK();
 
     ReleaseSharedLock(&afs_xconn);
     return tc;
@@ -672,7 +676,9 @@ afs_PutConn(struct afs_conn *ac, struct rx_connection *rxconn,
 	          (unsigned long)(uintptrsz)ac, (int)ac->refCount);
     }
     ac->parent->refCount--;
+    AFS_GUNLOCK();
     rx_PutConnection(rxconn);
+    AFS_GLOCK();
 }				/*afs_PutConn */
 
 
diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c
index 1879772fb..632aa849b 100644
--- a/src/afs/afs_daemons.c
+++ b/src/afs/afs_daemons.c
@@ -223,19 +223,21 @@ afs_Daemon(void)
 	    }
 	}
 	if (last10MinCheck + 600 < now) {
+	    int addrs_changed;
 #ifdef AFS_USERSPACE_IP_ADDR
 	    extern int rxi_GetcbiInfo(void);
 #endif
 	    afs_Trace1(afs_iclSetp, CM_TRACE_PROBEUP, ICL_TYPE_INT32, 600);
 #ifdef AFS_USERSPACE_IP_ADDR
-	    if (rxi_GetcbiInfo()) {	/* addresses changed from last time */
-		afs_FlushCBs();
-	    }
-#else /* AFS_USERSPACE_IP_ADDR */
-	    if (rxi_GetIFInfo()) {	/* addresses changed from last time */
+	    addrs_changed = rxi_GetcbiInfo();
+#else
+	    AFS_GUNLOCK();
+	    addrs_changed = rxi_GetIFInfo();
+	    AFS_GLOCK();
+#endif
+	    if (addrs_changed) {	/* addresses changed from last time */
 		afs_FlushCBs();
 	    }
-#endif /* else AFS_USERSPACE_IP_ADDR */
 	    if (!afs_CheckServerDaemonStarted)
 		afs_CheckServers(0, NULL);
 	    afs_GCUserData();	/* gc old conns */
diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c
index bdb791c1a..efa513256 100644
--- a/src/afs/afs_init.c
+++ b/src/afs/afs_init.c
@@ -554,7 +554,9 @@ afs_ResourceInit(int preallocs)
     afs_server =
 	rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", &secobj, 1,
 		      RXSTATS_ExecuteRequest);
+    AFS_GUNLOCK();
     rx_StartServer(0);
+    AFS_GLOCK();
     afs_osi_Wakeup(&afs_server);	/* wakeup anyone waiting for it */
     return 0;
 
diff --git a/src/afs/afs_pag_call.c b/src/afs/afs_pag_call.c
index 610cfb3a8..9b7a90631 100644
--- a/src/afs/afs_pag_call.c
+++ b/src/afs/afs_pag_call.c
@@ -91,10 +91,13 @@ afspag_Init(afs_int32 nfs_server_addr)
     afs_uuid_create(&afs_cb_interface.uuid);
 
     AFS_GLOCK();
-
     afs_InitStats();
+    AFS_GUNLOCK();
+
     rx_Init(htons(7001));
 
+    AFS_GLOCK();
+
     AFS_STATCNT(afs_ResourceInit);
     AFS_RWLOCK_INIT(&afs_xuser, "afs_xuser");
     AFS_RWLOCK_INIT(&afs_xpagcell, "afs_xpagcell");
@@ -117,18 +120,20 @@ afspag_Init(afs_int32 nfs_server_addr)
 			      1, RXSTATS_ExecuteRequest);
     pagcb_svc = rx_NewService(0, PAGCB_SERVICEID, "pagcb", &srv_secobj,
 			      1, PAGCB_ExecuteRequest);
+    AFS_GUNLOCK();
     rx_StartServer(0);
+    AFS_GLOCK();
 
     clt_secobj = rxnull_NewClientSecurityObject();
     rmtsys_conn = rx_NewConnection(nfs_server_addr, htons(7009),
 				   RMTSYS_SERVICEID, clt_secobj, 0);
 
 #ifdef RXK_LISTENER_ENV
-    afs_start_thread(rxk_Listener,       "Rx Listener");
+    afs_start_thread(rxk_Listener, "Rx Listener", 1);
 #endif
-    afs_start_thread((void *)(void *)rx_ServerProc,      "Rx Server Thread");
-    afs_start_thread(afs_rxevent_daemon, "Rx Event Daemon");
-    afs_start_thread(afs_Daemon,         "AFS PAG Daemon");
+    afs_start_thread((void *)(void *)rx_ServerProc, "Rx Server Thread", 0);
+    afs_start_thread(afs_rxevent_daemon, "Rx Event Daemon", 1);
+    afs_start_thread(afs_Daemon, "AFS PAG Daemon", 1);
 
     afs_icl_InitLogs();
 
diff --git a/src/rx/rx_kcommon.c b/src/rx/rx_kcommon.c
index c90df3d36..239cf1607 100644
--- a/src/rx/rx_kcommon.c
+++ b/src/rx/rx_kcommon.c
@@ -267,13 +267,7 @@ rx_ServerProc(void *unused)
     threadID = rxi_availProcs++;
     MUTEX_EXIT(&rx_quota_mutex);
 
-# ifdef RX_ENABLE_LOCKS
-    AFS_GUNLOCK();
-# endif /* RX_ENABLE_LOCKS */
     rxi_ServerProc(threadID, NULL, NULL);
-# ifdef RX_ENABLE_LOCKS
-    AFS_GLOCK();
-# endif /* RX_ENABLE_LOCKS */
 
     return NULL;
 }
@@ -856,8 +850,6 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport)
 #  if (defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)) && defined(KERNEL_FUNNEL)
     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
 #  endif
-    AFS_ASSERT_GLOCK();
-    AFS_GUNLOCK();
 #  if	defined(AFS_HPUX102_ENV)
 #   if     defined(AFS_HPUX110_ENV)
     /* we need a file associated with the socket so sosend in NetSend
@@ -997,14 +989,12 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport)
 #   endif /* else defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) */
 #  endif /* else AFS_HPUX110_ENV */
 
-    AFS_GLOCK();
 #  if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
 #  endif
     return (osi_socket *)newSocket;
 
   bad:
-    AFS_GLOCK();
 #  if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
 #  endif
-- 
2.44.0