summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/afs/cmservice.c41
-rw-r--r--fs/afs/internal.h9
-rw-r--r--fs/afs/rxrpc.c153
-rw-r--r--include/trace/events/afs.h75
4 files changed, 199 insertions, 79 deletions
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index a2e1e02005f6..e349a3316303 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -24,6 +24,11 @@ static int afs_deliver_cb_callback(struct afs_call *);
24static int afs_deliver_cb_probe_uuid(struct afs_call *); 24static int afs_deliver_cb_probe_uuid(struct afs_call *);
25static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *); 25static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *);
26static void afs_cm_destructor(struct afs_call *); 26static void afs_cm_destructor(struct afs_call *);
27static void SRXAFSCB_CallBack(struct work_struct *);
28static void SRXAFSCB_InitCallBackState(struct work_struct *);
29static void SRXAFSCB_Probe(struct work_struct *);
30static void SRXAFSCB_ProbeUuid(struct work_struct *);
31static void SRXAFSCB_TellMeAboutYourself(struct work_struct *);
27 32
28#define CM_NAME(name) \ 33#define CM_NAME(name) \
29 const char afs_SRXCB##name##_name[] __tracepoint_string = \ 34 const char afs_SRXCB##name##_name[] __tracepoint_string = \
@@ -38,6 +43,7 @@ static const struct afs_call_type afs_SRXCBCallBack = {
38 .deliver = afs_deliver_cb_callback, 43 .deliver = afs_deliver_cb_callback,
39 .abort_to_error = afs_abort_to_error, 44 .abort_to_error = afs_abort_to_error,
40 .destructor = afs_cm_destructor, 45 .destructor = afs_cm_destructor,
46 .work = SRXAFSCB_CallBack,
41}; 47};
42 48
43/* 49/*
@@ -49,6 +55,7 @@ static const struct afs_call_type afs_SRXCBInitCallBackState = {
49 .deliver = afs_deliver_cb_init_call_back_state, 55 .deliver = afs_deliver_cb_init_call_back_state,
50 .abort_to_error = afs_abort_to_error, 56 .abort_to_error = afs_abort_to_error,
51 .destructor = afs_cm_destructor, 57 .destructor = afs_cm_destructor,
58 .work = SRXAFSCB_InitCallBackState,
52}; 59};
53 60
54/* 61/*
@@ -60,6 +67,7 @@ static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
60 .deliver = afs_deliver_cb_init_call_back_state3, 67 .deliver = afs_deliver_cb_init_call_back_state3,
61 .abort_to_error = afs_abort_to_error, 68 .abort_to_error = afs_abort_to_error,
62 .destructor = afs_cm_destructor, 69 .destructor = afs_cm_destructor,
70 .work = SRXAFSCB_InitCallBackState,
63}; 71};
64 72
65/* 73/*
@@ -71,6 +79,7 @@ static const struct afs_call_type afs_SRXCBProbe = {
71 .deliver = afs_deliver_cb_probe, 79 .deliver = afs_deliver_cb_probe,
72 .abort_to_error = afs_abort_to_error, 80 .abort_to_error = afs_abort_to_error,
73 .destructor = afs_cm_destructor, 81 .destructor = afs_cm_destructor,
82 .work = SRXAFSCB_Probe,
74}; 83};
75 84
76/* 85/*
@@ -82,6 +91,7 @@ static const struct afs_call_type afs_SRXCBProbeUuid = {
82 .deliver = afs_deliver_cb_probe_uuid, 91 .deliver = afs_deliver_cb_probe_uuid,
83 .abort_to_error = afs_abort_to_error, 92 .abort_to_error = afs_abort_to_error,
84 .destructor = afs_cm_destructor, 93 .destructor = afs_cm_destructor,
94 .work = SRXAFSCB_ProbeUuid,
85}; 95};
86 96
87/* 97/*
@@ -93,6 +103,7 @@ static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
93 .deliver = afs_deliver_cb_tell_me_about_yourself, 103 .deliver = afs_deliver_cb_tell_me_about_yourself,
94 .abort_to_error = afs_abort_to_error, 104 .abort_to_error = afs_abort_to_error,
95 .destructor = afs_cm_destructor, 105 .destructor = afs_cm_destructor,
106 .work = SRXAFSCB_TellMeAboutYourself,
96}; 107};
97 108
98/* 109/*
@@ -163,6 +174,7 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
163 afs_send_empty_reply(call); 174 afs_send_empty_reply(call);
164 175
165 afs_break_callbacks(call->server, call->count, call->request); 176 afs_break_callbacks(call->server, call->count, call->request);
177 afs_put_call(call);
166 _leave(""); 178 _leave("");
167} 179}
168 180
@@ -284,9 +296,7 @@ static int afs_deliver_cb_callback(struct afs_call *call)
284 return -ENOTCONN; 296 return -ENOTCONN;
285 call->server = server; 297 call->server = server;
286 298
287 INIT_WORK(&call->work, SRXAFSCB_CallBack); 299 return afs_queue_call_work(call);
288 queue_work(afs_wq, &call->work);
289 return 0;
290} 300}
291 301
292/* 302/*
@@ -300,6 +310,7 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
300 310
301 afs_init_callback_state(call->server); 311 afs_init_callback_state(call->server);
302 afs_send_empty_reply(call); 312 afs_send_empty_reply(call);
313 afs_put_call(call);
303 _leave(""); 314 _leave("");
304} 315}
305 316
@@ -330,9 +341,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
330 return -ENOTCONN; 341 return -ENOTCONN;
331 call->server = server; 342 call->server = server;
332 343
333 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); 344 return afs_queue_call_work(call);
334 queue_work(afs_wq, &call->work);
335 return 0;
336} 345}
337 346
338/* 347/*
@@ -404,9 +413,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
404 return -ENOTCONN; 413 return -ENOTCONN;
405 call->server = server; 414 call->server = server;
406 415
407 INIT_WORK(&call->work, SRXAFSCB_InitCallBackState); 416 return afs_queue_call_work(call);
408 queue_work(afs_wq, &call->work);
409 return 0;
410} 417}
411 418
412/* 419/*
@@ -418,6 +425,7 @@ static void SRXAFSCB_Probe(struct work_struct *work)
418 425
419 _enter(""); 426 _enter("");
420 afs_send_empty_reply(call); 427 afs_send_empty_reply(call);
428 afs_put_call(call);
421 _leave(""); 429 _leave("");
422} 430}
423 431
@@ -437,9 +445,7 @@ static int afs_deliver_cb_probe(struct afs_call *call)
437 /* no unmarshalling required */ 445 /* no unmarshalling required */
438 call->state = AFS_CALL_REPLYING; 446 call->state = AFS_CALL_REPLYING;
439 447
440 INIT_WORK(&call->work, SRXAFSCB_Probe); 448 return afs_queue_call_work(call);
441 queue_work(afs_wq, &call->work);
442 return 0;
443} 449}
444 450
445/* 451/*
@@ -462,6 +468,7 @@ static void SRXAFSCB_ProbeUuid(struct work_struct *work)
462 reply.match = htonl(1); 468 reply.match = htonl(1);
463 469
464 afs_send_simple_reply(call, &reply, sizeof(reply)); 470 afs_send_simple_reply(call, &reply, sizeof(reply));
471 afs_put_call(call);
465 _leave(""); 472 _leave("");
466} 473}
467 474
@@ -520,9 +527,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call)
520 527
521 call->state = AFS_CALL_REPLYING; 528 call->state = AFS_CALL_REPLYING;
522 529
523 INIT_WORK(&call->work, SRXAFSCB_ProbeUuid); 530 return afs_queue_call_work(call);
524 queue_work(afs_wq, &call->work);
525 return 0;
526} 531}
527 532
528/* 533/*
@@ -584,7 +589,7 @@ static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
584 reply.cap.capcount = htonl(1); 589 reply.cap.capcount = htonl(1);
585 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION); 590 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
586 afs_send_simple_reply(call, &reply, sizeof(reply)); 591 afs_send_simple_reply(call, &reply, sizeof(reply));
587 592 afs_put_call(call);
588 _leave(""); 593 _leave("");
589} 594}
590 595
@@ -604,7 +609,5 @@ static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
604 /* no unmarshalling required */ 609 /* no unmarshalling required */
605 call->state = AFS_CALL_REPLYING; 610 call->state = AFS_CALL_REPLYING;
606 611
607 INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself); 612 return afs_queue_call_work(call);
608 queue_work(afs_wq, &call->work);
609 return 0;
610} 613}
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index b411670d5f67..65504e218d35 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -66,7 +66,7 @@ enum afs_call_state {
66struct afs_call { 66struct afs_call {
67 const struct afs_call_type *type; /* type of call */ 67 const struct afs_call_type *type; /* type of call */
68 wait_queue_head_t waitq; /* processes awaiting completion */ 68 wait_queue_head_t waitq; /* processes awaiting completion */
69 struct work_struct async_work; /* asynchronous work processor */ 69 struct work_struct async_work; /* async I/O processor */
70 struct work_struct work; /* actual work processor */ 70 struct work_struct work; /* actual work processor */
71 struct rxrpc_call *rxcall; /* RxRPC call handle */ 71 struct rxrpc_call *rxcall; /* RxRPC call handle */
72 struct key *key; /* security for this call */ 72 struct key *key; /* security for this call */
@@ -82,6 +82,7 @@ struct afs_call {
82 pgoff_t first; /* first page in mapping to deal with */ 82 pgoff_t first; /* first page in mapping to deal with */
83 pgoff_t last; /* last page in mapping to deal with */ 83 pgoff_t last; /* last page in mapping to deal with */
84 size_t offset; /* offset into received data store */ 84 size_t offset; /* offset into received data store */
85 atomic_t usage;
85 enum afs_call_state state; 86 enum afs_call_state state;
86 int error; /* error code */ 87 int error; /* error code */
87 u32 abort_code; /* Remote abort ID or 0 */ 88 u32 abort_code; /* Remote abort ID or 0 */
@@ -115,6 +116,9 @@ struct afs_call_type {
115 116
116 /* clean up a call */ 117 /* clean up a call */
117 void (*destructor)(struct afs_call *call); 118 void (*destructor)(struct afs_call *call);
119
120 /* Work function */
121 void (*work)(struct work_struct *work);
118}; 122};
119 123
120/* 124/*
@@ -591,9 +595,12 @@ extern void afs_proc_cell_remove(struct afs_cell *);
591 * rxrpc.c 595 * rxrpc.c
592 */ 596 */
593extern struct socket *afs_socket; 597extern struct socket *afs_socket;
598extern atomic_t afs_outstanding_calls;
594 599
595extern int afs_open_socket(void); 600extern int afs_open_socket(void);
596extern void afs_close_socket(void); 601extern void afs_close_socket(void);
602extern void afs_put_call(struct afs_call *);
603extern int afs_queue_call_work(struct afs_call *);
597extern int afs_make_call(struct in_addr *, struct afs_call *, gfp_t, bool); 604extern int afs_make_call(struct in_addr *, struct afs_call *, gfp_t, bool);
598extern struct afs_call *afs_alloc_flat_call(const struct afs_call_type *, 605extern struct afs_call *afs_alloc_flat_call(const struct afs_call_type *,
599 size_t, size_t); 606 size_t, size_t);
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index ec1e41f929d1..95f42872b787 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -19,9 +19,8 @@
19struct socket *afs_socket; /* my RxRPC socket */ 19struct socket *afs_socket; /* my RxRPC socket */
20static struct workqueue_struct *afs_async_calls; 20static struct workqueue_struct *afs_async_calls;
21static struct afs_call *afs_spare_incoming_call; 21static struct afs_call *afs_spare_incoming_call;
22static atomic_t afs_outstanding_calls; 22atomic_t afs_outstanding_calls;
23 23
24static void afs_free_call(struct afs_call *);
25static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); 24static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long);
26static int afs_wait_for_call_to_complete(struct afs_call *); 25static int afs_wait_for_call_to_complete(struct afs_call *);
27static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); 26static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long);
@@ -112,9 +111,11 @@ void afs_close_socket(void)
112{ 111{
113 _enter(""); 112 _enter("");
114 113
114 kernel_listen(afs_socket, 0);
115 flush_workqueue(afs_async_calls);
116
115 if (afs_spare_incoming_call) { 117 if (afs_spare_incoming_call) {
116 atomic_inc(&afs_outstanding_calls); 118 afs_put_call(afs_spare_incoming_call);
117 afs_free_call(afs_spare_incoming_call);
118 afs_spare_incoming_call = NULL; 119 afs_spare_incoming_call = NULL;
119 } 120 }
120 121
@@ -123,7 +124,6 @@ void afs_close_socket(void)
123 TASK_UNINTERRUPTIBLE); 124 TASK_UNINTERRUPTIBLE);
124 _debug("no outstanding calls"); 125 _debug("no outstanding calls");
125 126
126 flush_workqueue(afs_async_calls);
127 kernel_sock_shutdown(afs_socket, SHUT_RDWR); 127 kernel_sock_shutdown(afs_socket, SHUT_RDWR);
128 flush_workqueue(afs_async_calls); 128 flush_workqueue(afs_async_calls);
129 sock_release(afs_socket); 129 sock_release(afs_socket);
@@ -134,44 +134,79 @@ void afs_close_socket(void)
134} 134}
135 135
136/* 136/*
137 * free a call 137 * Allocate a call.
138 */ 138 */
139static void afs_free_call(struct afs_call *call) 139static struct afs_call *afs_alloc_call(const struct afs_call_type *type,
140 gfp_t gfp)
140{ 141{
141 _debug("DONE %p{%s} [%d]", 142 struct afs_call *call;
142 call, call->type->name, atomic_read(&afs_outstanding_calls)); 143 int o;
143 144
144 ASSERTCMP(call->rxcall, ==, NULL); 145 call = kzalloc(sizeof(*call), gfp);
145 ASSERT(!work_pending(&call->async_work)); 146 if (!call)
146 ASSERT(call->type->name != NULL); 147 return NULL;
147 148
148 kfree(call->request); 149 call->type = type;
149 kfree(call); 150 atomic_set(&call->usage, 1);
151 INIT_WORK(&call->async_work, afs_process_async_call);
152 init_waitqueue_head(&call->waitq);
150 153
151 if (atomic_dec_and_test(&afs_outstanding_calls)) 154 o = atomic_inc_return(&afs_outstanding_calls);
152 wake_up_atomic_t(&afs_outstanding_calls); 155 trace_afs_call(call, afs_call_trace_alloc, 1, o,
156 __builtin_return_address(0));
157 return call;
153} 158}
154 159
155/* 160/*
156 * End a call but do not free it 161 * Dispose of a reference on a call.
157 */ 162 */
158static void afs_end_call_nofree(struct afs_call *call) 163void afs_put_call(struct afs_call *call)
159{ 164{
160 if (call->rxcall) { 165 int n = atomic_dec_return(&call->usage);
161 rxrpc_kernel_end_call(afs_socket, call->rxcall); 166 int o = atomic_read(&afs_outstanding_calls);
162 call->rxcall = NULL; 167
168 trace_afs_call(call, afs_call_trace_put, n + 1, o,
169 __builtin_return_address(0));
170
171 ASSERTCMP(n, >=, 0);
172 if (n == 0) {
173 ASSERT(!work_pending(&call->async_work));
174 ASSERT(call->type->name != NULL);
175
176 if (call->rxcall) {
177 rxrpc_kernel_end_call(afs_socket, call->rxcall);
178 call->rxcall = NULL;
179 }
180 if (call->type->destructor)
181 call->type->destructor(call);
182
183 kfree(call->request);
184 kfree(call);
185
186 o = atomic_dec_return(&afs_outstanding_calls);
187 trace_afs_call(call, afs_call_trace_free, 0, o,
188 __builtin_return_address(0));
189 if (o == 0)
190 wake_up_atomic_t(&afs_outstanding_calls);
163 } 191 }
164 if (call->type->destructor)
165 call->type->destructor(call);
166} 192}
167 193
168/* 194/*
169 * End a call and free it 195 * Queue the call for actual work. Returns 0 unconditionally for convenience.
170 */ 196 */
171static void afs_end_call(struct afs_call *call) 197int afs_queue_call_work(struct afs_call *call)
172{ 198{
173 afs_end_call_nofree(call); 199 int u = atomic_inc_return(&call->usage);
174 afs_free_call(call); 200
201 trace_afs_call(call, afs_call_trace_work, u,
202 atomic_read(&afs_outstanding_calls),
203 __builtin_return_address(0));
204
205 INIT_WORK(&call->work, call->type->work);
206
207 if (!queue_work(afs_wq, &call->work))
208 afs_put_call(call);
209 return 0;
175} 210}
176 211
177/* 212/*
@@ -182,25 +217,19 @@ struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type,
182{ 217{
183 struct afs_call *call; 218 struct afs_call *call;
184 219
185 call = kzalloc(sizeof(*call), GFP_NOFS); 220 call = afs_alloc_call(type, GFP_NOFS);
186 if (!call) 221 if (!call)
187 goto nomem_call; 222 goto nomem_call;
188 223
189 _debug("CALL %p{%s} [%d]",
190 call, type->name, atomic_read(&afs_outstanding_calls));
191 atomic_inc(&afs_outstanding_calls);
192
193 call->type = type;
194 call->request_size = request_size;
195 call->reply_max = reply_max;
196
197 if (request_size) { 224 if (request_size) {
225 call->request_size = request_size;
198 call->request = kmalloc(request_size, GFP_NOFS); 226 call->request = kmalloc(request_size, GFP_NOFS);
199 if (!call->request) 227 if (!call->request)
200 goto nomem_free; 228 goto nomem_free;
201 } 229 }
202 230
203 if (reply_max) { 231 if (reply_max) {
232 call->reply_max = reply_max;
204 call->buffer = kmalloc(reply_max, GFP_NOFS); 233 call->buffer = kmalloc(reply_max, GFP_NOFS);
205 if (!call->buffer) 234 if (!call->buffer)
206 goto nomem_free; 235 goto nomem_free;
@@ -210,7 +239,7 @@ struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type,
210 return call; 239 return call;
211 240
212nomem_free: 241nomem_free:
213 afs_free_call(call); 242 afs_put_call(call);
214nomem_call: 243nomem_call:
215 return NULL; 244 return NULL;
216} 245}
@@ -315,7 +344,6 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
315 atomic_read(&afs_outstanding_calls)); 344 atomic_read(&afs_outstanding_calls));
316 345
317 call->async = async; 346 call->async = async;
318 INIT_WORK(&call->async_work, afs_process_async_call);
319 347
320 memset(&srx, 0, sizeof(srx)); 348 memset(&srx, 0, sizeof(srx));
321 srx.srx_family = AF_RXRPC; 349 srx.srx_family = AF_RXRPC;
@@ -378,7 +406,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
378error_do_abort: 406error_do_abort:
379 rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT, -ret, "KSD"); 407 rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT, -ret, "KSD");
380error_kill_call: 408error_kill_call:
381 afs_end_call(call); 409 afs_put_call(call);
382 _leave(" = %d", ret); 410 _leave(" = %d", ret);
383 return ret; 411 return ret;
384} 412}
@@ -448,7 +476,7 @@ static void afs_deliver_to_call(struct afs_call *call)
448 476
449done: 477done:
450 if (call->state == AFS_CALL_COMPLETE && call->incoming) 478 if (call->state == AFS_CALL_COMPLETE && call->incoming)
451 afs_end_call(call); 479 afs_put_call(call);
452out: 480out:
453 _leave(""); 481 _leave("");
454 return; 482 return;
@@ -505,7 +533,7 @@ static int afs_wait_for_call_to_complete(struct afs_call *call)
505 } 533 }
506 534
507 _debug("call complete"); 535 _debug("call complete");
508 afs_end_call(call); 536 afs_put_call(call);
509 _leave(" = %d", ret); 537 _leave(" = %d", ret);
510 return ret; 538 return ret;
511} 539}
@@ -529,14 +557,25 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
529 unsigned long call_user_ID) 557 unsigned long call_user_ID)
530{ 558{
531 struct afs_call *call = (struct afs_call *)call_user_ID; 559 struct afs_call *call = (struct afs_call *)call_user_ID;
560 int u;
532 561
533 trace_afs_notify_call(rxcall, call); 562 trace_afs_notify_call(rxcall, call);
534 call->need_attention = true; 563 call->need_attention = true;
535 queue_work(afs_async_calls, &call->async_work); 564
565 u = __atomic_add_unless(&call->usage, 1, 0);
566 if (u != 0) {
567 trace_afs_call(call, afs_call_trace_wake, u,
568 atomic_read(&afs_outstanding_calls),
569 __builtin_return_address(0));
570
571 if (!queue_work(afs_async_calls, &call->async_work))
572 afs_put_call(call);
573 }
536} 574}
537 575
538/* 576/*
539 * delete an asynchronous call 577 * Delete an asynchronous call. The work item carries a ref to the call struct
578 * that we need to release.
540 */ 579 */
541static void afs_delete_async_call(struct work_struct *work) 580static void afs_delete_async_call(struct work_struct *work)
542{ 581{
@@ -544,13 +583,14 @@ static void afs_delete_async_call(struct work_struct *work)
544 583
545 _enter(""); 584 _enter("");
546 585
547 afs_free_call(call); 586 afs_put_call(call);
548 587
549 _leave(""); 588 _leave("");
550} 589}
551 590
552/* 591/*
553 * perform processing on an asynchronous call 592 * Perform I/O processing on an asynchronous call. The work item carries a ref
593 * to the call struct that we either need to release or to pass on.
554 */ 594 */
555static void afs_process_async_call(struct work_struct *work) 595static void afs_process_async_call(struct work_struct *work)
556{ 596{
@@ -566,15 +606,16 @@ static void afs_process_async_call(struct work_struct *work)
566 if (call->state == AFS_CALL_COMPLETE) { 606 if (call->state == AFS_CALL_COMPLETE) {
567 call->reply = NULL; 607 call->reply = NULL;
568 608
569 /* kill the call */ 609 /* We have two refs to release - one from the alloc and one
570 afs_end_call_nofree(call); 610 * queued with the work item - and we can't just deallocate the
571 611 * call because the work item may be queued again.
572 /* we can't just delete the call because the work item may be 612 */
573 * queued */
574 call->async_work.func = afs_delete_async_call; 613 call->async_work.func = afs_delete_async_call;
575 queue_work(afs_async_calls, &call->async_work); 614 if (!queue_work(afs_async_calls, &call->async_work))
615 afs_put_call(call);
576 } 616 }
577 617
618 afs_put_call(call);
578 _leave(""); 619 _leave("");
579} 620}
580 621
@@ -594,12 +635,10 @@ static void afs_charge_preallocation(struct work_struct *work)
594 635
595 for (;;) { 636 for (;;) {
596 if (!call) { 637 if (!call) {
597 call = kzalloc(sizeof(struct afs_call), GFP_KERNEL); 638 call = afs_alloc_call(&afs_RXCMxxxx, GFP_KERNEL);
598 if (!call) 639 if (!call)
599 break; 640 break;
600 641
601 INIT_WORK(&call->async_work, afs_process_async_call);
602 call->type = &afs_RXCMxxxx;
603 call->async = true; 642 call->async = true;
604 call->state = AFS_CALL_AWAIT_OP_ID; 643 call->state = AFS_CALL_AWAIT_OP_ID;
605 init_waitqueue_head(&call->waitq); 644 init_waitqueue_head(&call->waitq);
@@ -624,9 +663,8 @@ static void afs_rx_discard_new_call(struct rxrpc_call *rxcall,
624{ 663{
625 struct afs_call *call = (struct afs_call *)user_call_ID; 664 struct afs_call *call = (struct afs_call *)user_call_ID;
626 665
627 atomic_inc(&afs_outstanding_calls);
628 call->rxcall = NULL; 666 call->rxcall = NULL;
629 afs_free_call(call); 667 afs_put_call(call);
630} 668}
631 669
632/* 670/*
@@ -635,7 +673,6 @@ static void afs_rx_discard_new_call(struct rxrpc_call *rxcall,
635static void afs_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall, 673static void afs_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall,
636 unsigned long user_call_ID) 674 unsigned long user_call_ID)
637{ 675{
638 atomic_inc(&afs_outstanding_calls);
639 queue_work(afs_wq, &afs_charge_preallocation_work); 676 queue_work(afs_wq, &afs_charge_preallocation_work);
640} 677}
641 678
@@ -699,7 +736,6 @@ void afs_send_empty_reply(struct afs_call *call)
699 rxrpc_kernel_abort_call(afs_socket, call->rxcall, 736 rxrpc_kernel_abort_call(afs_socket, call->rxcall,
700 RX_USER_ABORT, ENOMEM, "KOO"); 737 RX_USER_ABORT, ENOMEM, "KOO");
701 default: 738 default:
702 afs_end_call(call);
703 _leave(" [error]"); 739 _leave(" [error]");
704 return; 740 return;
705 } 741 }
@@ -738,7 +774,6 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)
738 rxrpc_kernel_abort_call(afs_socket, call->rxcall, 774 rxrpc_kernel_abort_call(afs_socket, call->rxcall,
739 RX_USER_ABORT, ENOMEM, "KOO"); 775 RX_USER_ABORT, ENOMEM, "KOO");
740 } 776 }
741 afs_end_call(call);
742 _leave(" [error]"); 777 _leave(" [error]");
743} 778}
744 779
diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h
index 845907b04ff4..8b95c16b7045 100644
--- a/include/trace/events/afs.h
+++ b/include/trace/events/afs.h
@@ -16,6 +16,51 @@
16 16
17#include <linux/tracepoint.h> 17#include <linux/tracepoint.h>
18 18
19/*
20 * Define enums for tracing information.
21 */
22#ifndef __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY
23#define __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY
24
25enum afs_call_trace {
26 afs_call_trace_alloc,
27 afs_call_trace_free,
28 afs_call_trace_put,
29 afs_call_trace_wake,
30 afs_call_trace_work,
31};
32
33#endif /* end __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY */
34
35/*
36 * Declare tracing information enums and their string mappings for display.
37 */
38#define afs_call_traces \
39 EM(afs_call_trace_alloc, "ALLOC") \
40 EM(afs_call_trace_free, "FREE ") \
41 EM(afs_call_trace_put, "PUT ") \
42 EM(afs_call_trace_wake, "WAKE ") \
43 E_(afs_call_trace_work, "WORK ")
44
45/*
46 * Export enum symbols via userspace.
47 */
48#undef EM
49#undef E_
50#define EM(a, b) TRACE_DEFINE_ENUM(a);
51#define E_(a, b) TRACE_DEFINE_ENUM(a);
52
53afs_call_traces;
54
55/*
56 * Now redefine the EM() and E_() macros to map the enums to the strings that
57 * will be printed in the output.
58 */
59#undef EM
60#undef E_
61#define EM(a, b) { a, b },
62#define E_(a, b) { a, b }
63
19TRACE_EVENT(afs_recv_data, 64TRACE_EVENT(afs_recv_data,
20 TP_PROTO(struct afs_call *call, unsigned count, unsigned offset, 65 TP_PROTO(struct afs_call *call, unsigned count, unsigned offset,
21 bool want_more, int ret), 66 bool want_more, int ret),
@@ -103,6 +148,36 @@ TRACE_EVENT(afs_cb_call,
103 __entry->op) 148 __entry->op)
104 ); 149 );
105 150
151TRACE_EVENT(afs_call,
152 TP_PROTO(struct afs_call *call, enum afs_call_trace op,
153 int usage, int outstanding, const void *where),
154
155 TP_ARGS(call, op, usage, outstanding, where),
156
157 TP_STRUCT__entry(
158 __field(struct afs_call *, call )
159 __field(int, op )
160 __field(int, usage )
161 __field(int, outstanding )
162 __field(const void *, where )
163 ),
164
165 TP_fast_assign(
166 __entry->call = call;
167 __entry->op = op;
168 __entry->usage = usage;
169 __entry->outstanding = outstanding;
170 __entry->where = where;
171 ),
172
173 TP_printk("c=%p %s u=%d o=%d sp=%pSR",
174 __entry->call,
175 __print_symbolic(__entry->op, afs_call_traces),
176 __entry->usage,
177 __entry->outstanding,
178 __entry->where)
179 );
180
106#endif /* _TRACE_AFS_H */ 181#endif /* _TRACE_AFS_H */
107 182
108/* This part must be outside protection */ 183/* This part must be outside protection */