"xprt" reference count drops to 0

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Due to some race conditions, the reference count can become 0
while "xprt" is still on a "pool":

WARNING: at lib/kref.c:43 kref_get+0x23/0x2d()
 [] kref_get+0x23/0x2d
 [] svc_xprt_get+0x12/0x14 [sunrpc]
 [] svc_recv+0x2db/0x78a [sunrpc]

I think we should increase the reference counter before adding "xprt"
onto any list.

Obviously, we keep increasing the reference count before passing "xprt"
to another thread via "rqstp->rq_xprt".

Thanks,

Zoltan Menyhart
"svc_xprt_get()" should be invoked before adding "xprt" onto "pool" by
"svc_xprt_enqueue()".
Otherwise "xprt->xpt_ref" can drop to 0 due to race conditions.

Signed-off-by: Zoltan Menyhart <Zoltan.Menyhart@xxxxxxxx>

--- old/net/sunrpc/svc_xprt.c	2010-10-05 09:47:51.000000000 +0200
+++ new/net/sunrpc/svc_xprt.c	2010-10-05 09:47:20.000000000 +0200
@@ -369,6 +369,7 @@
 	}
 
  process:
+	svc_xprt_get(xprt);
 	if (!list_empty(&pool->sp_threads)) {
 		rqstp = list_entry(pool->sp_threads.next,
 				   struct svc_rqst,
@@ -381,7 +382,6 @@
 				"svc_xprt_enqueue: server %p, rq_xprt=%p!\n",
 				rqstp, rqstp->rq_xprt);
 		rqstp->rq_xprt = xprt;
-		svc_xprt_get(xprt);
 		rqstp->rq_reserved = serv->sv_max_mesg;
 		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
 		pool->sp_stats.threads_woken++;
@@ -655,7 +655,6 @@
 	xprt = svc_xprt_dequeue(pool);
 	if (xprt) {
 		rqstp->rq_xprt = xprt;
-		svc_xprt_get(xprt);
 		rqstp->rq_reserved = serv->sv_max_mesg;
 		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
 	} else {

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux