aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/rxrpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/rxrpc.c')
-rw-r--r--fs/afs/rxrpc.c137
1 files changed, 107 insertions, 30 deletions
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index b92774231b3c..e86c527d87a1 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -17,6 +17,8 @@
17 17
18static struct socket *afs_socket; /* my RxRPC socket */ 18static struct socket *afs_socket; /* my RxRPC socket */
19static struct workqueue_struct *afs_async_calls; 19static struct workqueue_struct *afs_async_calls;
20static atomic_t afs_outstanding_calls;
21static atomic_t afs_outstanding_skbs;
20 22
21static void afs_wake_up_call_waiter(struct afs_call *); 23static void afs_wake_up_call_waiter(struct afs_call *);
22static int afs_wait_for_call_to_complete(struct afs_call *); 24static int afs_wait_for_call_to_complete(struct afs_call *);
@@ -45,6 +47,7 @@ static const struct afs_wait_mode afs_async_incoming_call = {
45 47
46/* asynchronous incoming call initial processing */ 48/* asynchronous incoming call initial processing */
47static const struct afs_call_type afs_RXCMxxxx = { 49static const struct afs_call_type afs_RXCMxxxx = {
50 .name = "CB.xxxx",
48 .deliver = afs_deliver_cm_op_id, 51 .deliver = afs_deliver_cm_op_id,
49 .abort_to_error = afs_abort_to_error, 52 .abort_to_error = afs_abort_to_error,
50}; 53};
@@ -118,10 +121,67 @@ void afs_close_socket(void)
118 121
119 _debug("dework"); 122 _debug("dework");
120 destroy_workqueue(afs_async_calls); 123 destroy_workqueue(afs_async_calls);
124
125 ASSERTCMP(atomic_read(&afs_outstanding_skbs), ==, 0);
126 ASSERTCMP(atomic_read(&afs_outstanding_calls), ==, 0);
121 _leave(""); 127 _leave("");
122} 128}
123 129
124/* 130/*
131 * note that the data in a socket buffer is now delivered and that the buffer
132 * should be freed
133 */
134static void afs_data_delivered(struct sk_buff *skb)
135{
136 if (!skb) {
137 _debug("DLVR NULL [%d]", atomic_read(&afs_outstanding_skbs));
138 dump_stack();
139 } else {
140 _debug("DLVR %p{%u} [%d]",
141 skb, skb->mark, atomic_read(&afs_outstanding_skbs));
142 if (atomic_dec_return(&afs_outstanding_skbs) == -1)
143 BUG();
144 rxrpc_kernel_data_delivered(skb);
145 }
146}
147
148/*
149 * free a socket buffer
150 */
151static void afs_free_skb(struct sk_buff *skb)
152{
153 if (!skb) {
154 _debug("FREE NULL [%d]", atomic_read(&afs_outstanding_skbs));
155 dump_stack();
156 } else {
157 _debug("FREE %p{%u} [%d]",
158 skb, skb->mark, atomic_read(&afs_outstanding_skbs));
159 if (atomic_dec_return(&afs_outstanding_skbs) == -1)
160 BUG();
161 rxrpc_kernel_free_skb(skb);
162 }
163}
164
165/*
166 * free a call
167 */
168static void afs_free_call(struct afs_call *call)
169{
170 _debug("DONE %p{%s} [%d]",
171 call, call->type->name, atomic_read(&afs_outstanding_calls));
172 if (atomic_dec_return(&afs_outstanding_calls) == -1)
173 BUG();
174
175 ASSERTCMP(call->rxcall, ==, NULL);
176 ASSERT(!work_pending(&call->async_work));
177 ASSERT(skb_queue_empty(&call->rx_queue));
178 ASSERT(call->type->name != NULL);
179
180 kfree(call->request);
181 kfree(call);
182}
183
184/*
125 * allocate a call with flat request and reply buffers 185 * allocate a call with flat request and reply buffers
126 */ 186 */
127struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type, 187struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type,
@@ -133,30 +193,32 @@ struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type,
133 if (!call) 193 if (!call)
134 goto nomem_call; 194 goto nomem_call;
135 195
196 _debug("CALL %p{%s} [%d]",
197 call, type->name, atomic_read(&afs_outstanding_calls));
198 atomic_inc(&afs_outstanding_calls);
199
200 call->type = type;
201 call->request_size = request_size;
202 call->reply_max = reply_size;
203
136 if (request_size) { 204 if (request_size) {
137 call->request = kmalloc(request_size, GFP_NOFS); 205 call->request = kmalloc(request_size, GFP_NOFS);
138 if (!call->request) 206 if (!call->request)
139 goto nomem_request; 207 goto nomem_free;
140 } 208 }
141 209
142 if (reply_size) { 210 if (reply_size) {
143 call->buffer = kmalloc(reply_size, GFP_NOFS); 211 call->buffer = kmalloc(reply_size, GFP_NOFS);
144 if (!call->buffer) 212 if (!call->buffer)
145 goto nomem_buffer; 213 goto nomem_free;
146 } 214 }
147 215
148 call->type = type;
149 call->request_size = request_size;
150 call->reply_max = reply_size;
151
152 init_waitqueue_head(&call->waitq); 216 init_waitqueue_head(&call->waitq);
153 skb_queue_head_init(&call->rx_queue); 217 skb_queue_head_init(&call->rx_queue);
154 return call; 218 return call;
155 219
156nomem_buffer: 220nomem_free:
157 kfree(call->request); 221 afs_free_call(call);
158nomem_request:
159 kfree(call);
160nomem_call: 222nomem_call:
161 return NULL; 223 return NULL;
162} 224}
@@ -188,6 +250,12 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
188 250
189 _enter("%x,{%d},", addr->s_addr, ntohs(call->port)); 251 _enter("%x,{%d},", addr->s_addr, ntohs(call->port));
190 252
253 ASSERT(call->type != NULL);
254 ASSERT(call->type->name != NULL);
255
256 _debug("MAKE %p{%s} [%d]",
257 call, call->type->name, atomic_read(&afs_outstanding_calls));
258
191 call->wait_mode = wait_mode; 259 call->wait_mode = wait_mode;
192 INIT_WORK(&call->async_work, afs_process_async_call); 260 INIT_WORK(&call->async_work, afs_process_async_call);
193 261
@@ -203,6 +271,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
203 /* create a call */ 271 /* create a call */
204 rxcall = rxrpc_kernel_begin_call(afs_socket, &srx, call->key, 272 rxcall = rxrpc_kernel_begin_call(afs_socket, &srx, call->key,
205 (unsigned long) call, gfp); 273 (unsigned long) call, gfp);
274 call->key = NULL;
206 if (IS_ERR(rxcall)) { 275 if (IS_ERR(rxcall)) {
207 ret = PTR_ERR(rxcall); 276 ret = PTR_ERR(rxcall);
208 goto error_kill_call; 277 goto error_kill_call;
@@ -237,10 +306,10 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
237error_do_abort: 306error_do_abort:
238 rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT); 307 rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT);
239 rxrpc_kernel_end_call(rxcall); 308 rxrpc_kernel_end_call(rxcall);
309 call->rxcall = NULL;
240error_kill_call: 310error_kill_call:
241 call->type->destructor(call); 311 call->type->destructor(call);
242 ASSERT(skb_queue_empty(&call->rx_queue)); 312 afs_free_call(call);
243 kfree(call);
244 _leave(" = %d", ret); 313 _leave(" = %d", ret);
245 return ret; 314 return ret;
246} 315}
@@ -257,15 +326,19 @@ static void afs_rx_interceptor(struct sock *sk, unsigned long user_call_ID,
257 326
258 _enter("%p,,%u", call, skb->mark); 327 _enter("%p,,%u", call, skb->mark);
259 328
329 _debug("ICPT %p{%u} [%d]",
330 skb, skb->mark, atomic_read(&afs_outstanding_skbs));
331
260 ASSERTCMP(sk, ==, afs_socket->sk); 332 ASSERTCMP(sk, ==, afs_socket->sk);
333 atomic_inc(&afs_outstanding_skbs);
261 334
262 if (!call) { 335 if (!call) {
263 /* its an incoming call for our callback service */ 336 /* its an incoming call for our callback service */
264 __skb_queue_tail(&afs_incoming_calls, skb); 337 skb_queue_tail(&afs_incoming_calls, skb);
265 schedule_work(&afs_collect_incoming_call_work); 338 schedule_work(&afs_collect_incoming_call_work);
266 } else { 339 } else {
267 /* route the messages directly to the appropriate call */ 340 /* route the messages directly to the appropriate call */
268 __skb_queue_tail(&call->rx_queue, skb); 341 skb_queue_tail(&call->rx_queue, skb);
269 call->wait_mode->rx_wakeup(call); 342 call->wait_mode->rx_wakeup(call);
270 } 343 }
271 344
@@ -317,9 +390,9 @@ static void afs_deliver_to_call(struct afs_call *call)
317 call->state = AFS_CALL_ERROR; 390 call->state = AFS_CALL_ERROR;
318 break; 391 break;
319 } 392 }
320 rxrpc_kernel_data_delivered(skb); 393 afs_data_delivered(skb);
321 skb = NULL; 394 skb = NULL;
322 break; 395 continue;
323 case RXRPC_SKB_MARK_FINAL_ACK: 396 case RXRPC_SKB_MARK_FINAL_ACK:
324 _debug("Rcv ACK"); 397 _debug("Rcv ACK");
325 call->state = AFS_CALL_COMPLETE; 398 call->state = AFS_CALL_COMPLETE;
@@ -350,19 +423,19 @@ static void afs_deliver_to_call(struct afs_call *call)
350 break; 423 break;
351 } 424 }
352 425
353 rxrpc_kernel_free_skb(skb); 426 afs_free_skb(skb);
354 } 427 }
355 428
356 /* make sure the queue is empty if the call is done with (we might have 429 /* make sure the queue is empty if the call is done with (we might have
357 * aborted the call early because of an unmarshalling error) */ 430 * aborted the call early because of an unmarshalling error) */
358 if (call->state >= AFS_CALL_COMPLETE) { 431 if (call->state >= AFS_CALL_COMPLETE) {
359 while ((skb = skb_dequeue(&call->rx_queue))) 432 while ((skb = skb_dequeue(&call->rx_queue)))
360 rxrpc_kernel_free_skb(skb); 433 afs_free_skb(skb);
361 if (call->incoming) { 434 if (call->incoming) {
362 rxrpc_kernel_end_call(call->rxcall); 435 rxrpc_kernel_end_call(call->rxcall);
436 call->rxcall = NULL;
363 call->type->destructor(call); 437 call->type->destructor(call);
364 ASSERT(skb_queue_empty(&call->rx_queue)); 438 afs_free_call(call);
365 kfree(call);
366 } 439 }
367 } 440 }
368 441
@@ -409,14 +482,14 @@ static int afs_wait_for_call_to_complete(struct afs_call *call)
409 _debug("call incomplete"); 482 _debug("call incomplete");
410 rxrpc_kernel_abort_call(call->rxcall, RX_CALL_DEAD); 483 rxrpc_kernel_abort_call(call->rxcall, RX_CALL_DEAD);
411 while ((skb = skb_dequeue(&call->rx_queue))) 484 while ((skb = skb_dequeue(&call->rx_queue)))
412 rxrpc_kernel_free_skb(skb); 485 afs_free_skb(skb);
413 } 486 }
414 487
415 _debug("call complete"); 488 _debug("call complete");
416 rxrpc_kernel_end_call(call->rxcall); 489 rxrpc_kernel_end_call(call->rxcall);
490 call->rxcall = NULL;
417 call->type->destructor(call); 491 call->type->destructor(call);
418 ASSERT(skb_queue_empty(&call->rx_queue)); 492 afs_free_call(call);
419 kfree(call);
420 _leave(" = %d", ret); 493 _leave(" = %d", ret);
421 return ret; 494 return ret;
422} 495}
@@ -459,9 +532,7 @@ static void afs_delete_async_call(struct work_struct *work)
459 532
460 _enter(""); 533 _enter("");
461 534
462 ASSERT(skb_queue_empty(&call->rx_queue)); 535 afs_free_call(call);
463 ASSERT(!work_pending(&call->async_work));
464 kfree(call);
465 536
466 _leave(""); 537 _leave("");
467} 538}
@@ -489,6 +560,7 @@ static void afs_process_async_call(struct work_struct *work)
489 560
490 /* kill the call */ 561 /* kill the call */
491 rxrpc_kernel_end_call(call->rxcall); 562 rxrpc_kernel_end_call(call->rxcall);
563 call->rxcall = NULL;
492 if (call->type->destructor) 564 if (call->type->destructor)
493 call->type->destructor(call); 565 call->type->destructor(call);
494 566
@@ -526,7 +598,7 @@ static void afs_collect_incoming_call(struct work_struct *work)
526 _debug("new call"); 598 _debug("new call");
527 599
528 /* don't need the notification */ 600 /* don't need the notification */
529 rxrpc_kernel_free_skb(skb); 601 afs_free_skb(skb);
530 602
531 if (!call) { 603 if (!call) {
532 call = kzalloc(sizeof(struct afs_call), GFP_KERNEL); 604 call = kzalloc(sizeof(struct afs_call), GFP_KERNEL);
@@ -541,6 +613,11 @@ static void afs_collect_incoming_call(struct work_struct *work)
541 init_waitqueue_head(&call->waitq); 613 init_waitqueue_head(&call->waitq);
542 skb_queue_head_init(&call->rx_queue); 614 skb_queue_head_init(&call->rx_queue);
543 call->state = AFS_CALL_AWAIT_OP_ID; 615 call->state = AFS_CALL_AWAIT_OP_ID;
616
617 _debug("CALL %p{%s} [%d]",
618 call, call->type->name,
619 atomic_read(&afs_outstanding_calls));
620 atomic_inc(&afs_outstanding_calls);
544 } 621 }
545 622
546 rxcall = rxrpc_kernel_accept_call(afs_socket, 623 rxcall = rxrpc_kernel_accept_call(afs_socket,
@@ -551,7 +628,8 @@ static void afs_collect_incoming_call(struct work_struct *work)
551 } 628 }
552 } 629 }
553 630
554 kfree(call); 631 if (call)
632 afs_free_call(call);
555} 633}
556 634
557/* 635/*
@@ -629,8 +707,7 @@ void afs_send_empty_reply(struct afs_call *call)
629 rxrpc_kernel_end_call(call->rxcall); 707 rxrpc_kernel_end_call(call->rxcall);
630 call->rxcall = NULL; 708 call->rxcall = NULL;
631 call->type->destructor(call); 709 call->type->destructor(call);
632 ASSERT(skb_queue_empty(&call->rx_queue)); 710 afs_free_call(call);
633 kfree(call);
634 _leave(" [error]"); 711 _leave(" [error]");
635 return; 712 return;
636 } 713 }