aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-11-21 14:19:31 -0500
committerJ. Bruce Fields <bfields@redhat.com>2014-12-09 11:29:14 -0500
commit83a712e0afefaf68555f816ea78ecd2862c6cf30 (patch)
tree05e25469b98a7f437209ea0a50580d7f291c3d90 /net/sunrpc
parentb1691bc03d4eddb959234409167bef9be9e62d74 (diff)
sunrpc: add some tracepoints around enqueue and dequeue of svc_xprt
These were useful when I was tracking down a race condition between svc_xprt_do_enqueue and svc_get_next_xprt. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/svc_xprt.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index ed90d955f733..73d40bd1839a 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -322,12 +322,12 @@ static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt)
322static void svc_xprt_do_enqueue(struct svc_xprt *xprt) 322static void svc_xprt_do_enqueue(struct svc_xprt *xprt)
323{ 323{
324 struct svc_pool *pool; 324 struct svc_pool *pool;
325 struct svc_rqst *rqstp; 325 struct svc_rqst *rqstp = NULL;
326 int cpu; 326 int cpu;
327 bool queued = false; 327 bool queued = false;
328 328
329 if (!svc_xprt_has_something_to_do(xprt)) 329 if (!svc_xprt_has_something_to_do(xprt))
330 return; 330 goto out;
331 331
332 /* Mark transport as busy. It will remain in this state until 332 /* Mark transport as busy. It will remain in this state until
333 * the provider calls svc_xprt_received. We update XPT_BUSY 333 * the provider calls svc_xprt_received. We update XPT_BUSY
@@ -337,7 +337,7 @@ static void svc_xprt_do_enqueue(struct svc_xprt *xprt)
337 if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) { 337 if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) {
338 /* Don't enqueue transport while already enqueued */ 338 /* Don't enqueue transport while already enqueued */
339 dprintk("svc: transport %p busy, not enqueued\n", xprt); 339 dprintk("svc: transport %p busy, not enqueued\n", xprt);
340 return; 340 goto out;
341 } 341 }
342 342
343 cpu = get_cpu(); 343 cpu = get_cpu();
@@ -377,7 +377,7 @@ redo_search:
377 atomic_long_inc(&pool->sp_stats.threads_woken); 377 atomic_long_inc(&pool->sp_stats.threads_woken);
378 wake_up_process(rqstp->rq_task); 378 wake_up_process(rqstp->rq_task);
379 put_cpu(); 379 put_cpu();
380 return; 380 goto out;
381 } 381 }
382 rcu_read_unlock(); 382 rcu_read_unlock();
383 383
@@ -396,7 +396,10 @@ redo_search:
396 spin_unlock_bh(&pool->sp_lock); 396 spin_unlock_bh(&pool->sp_lock);
397 goto redo_search; 397 goto redo_search;
398 } 398 }
399 rqstp = NULL;
399 put_cpu(); 400 put_cpu();
401out:
402 trace_svc_xprt_do_enqueue(xprt, rqstp);
400} 403}
401 404
402/* 405/*
@@ -420,7 +423,7 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool)
420 struct svc_xprt *xprt = NULL; 423 struct svc_xprt *xprt = NULL;
421 424
422 if (list_empty(&pool->sp_sockets)) 425 if (list_empty(&pool->sp_sockets))
423 return NULL; 426 goto out;
424 427
425 spin_lock_bh(&pool->sp_lock); 428 spin_lock_bh(&pool->sp_lock);
426 if (likely(!list_empty(&pool->sp_sockets))) { 429 if (likely(!list_empty(&pool->sp_sockets))) {
@@ -433,7 +436,8 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool)
433 xprt, atomic_read(&xprt->xpt_ref.refcount)); 436 xprt, atomic_read(&xprt->xpt_ref.refcount));
434 } 437 }
435 spin_unlock_bh(&pool->sp_lock); 438 spin_unlock_bh(&pool->sp_lock);
436 439out:
440 trace_svc_xprt_dequeue(xprt);
437 return xprt; 441 return xprt;
438} 442}
439 443
@@ -515,6 +519,7 @@ void svc_wake_up(struct svc_serv *serv)
515 rcu_read_unlock(); 519 rcu_read_unlock();
516 dprintk("svc: daemon %p woken up.\n", rqstp); 520 dprintk("svc: daemon %p woken up.\n", rqstp);
517 wake_up_process(rqstp->rq_task); 521 wake_up_process(rqstp->rq_task);
522 trace_svc_wake_up(rqstp->rq_task->pid);
518 return; 523 return;
519 } 524 }
520 rcu_read_unlock(); 525 rcu_read_unlock();
@@ -522,6 +527,7 @@ void svc_wake_up(struct svc_serv *serv)
522 /* No free entries available */ 527 /* No free entries available */
523 set_bit(SP_TASK_PENDING, &pool->sp_flags); 528 set_bit(SP_TASK_PENDING, &pool->sp_flags);
524 smp_wmb(); 529 smp_wmb();
530 trace_svc_wake_up(0);
525} 531}
526EXPORT_SYMBOL_GPL(svc_wake_up); 532EXPORT_SYMBOL_GPL(svc_wake_up);
527 533
@@ -740,7 +746,7 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
740 dprintk("svc_recv: found XPT_CLOSE\n"); 746 dprintk("svc_recv: found XPT_CLOSE\n");
741 svc_delete_xprt(xprt); 747 svc_delete_xprt(xprt);
742 /* Leave XPT_BUSY set on the dead xprt: */ 748 /* Leave XPT_BUSY set on the dead xprt: */
743 return 0; 749 goto out;
744 } 750 }
745 if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { 751 if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
746 struct svc_xprt *newxpt; 752 struct svc_xprt *newxpt;
@@ -771,6 +777,8 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
771 } 777 }
772 /* clear XPT_BUSY: */ 778 /* clear XPT_BUSY: */
773 svc_xprt_received(xprt); 779 svc_xprt_received(xprt);
780out:
781 trace_svc_handle_xprt(xprt, len);
774 return len; 782 return len;
775} 783}
776 784