Patchwork [3.5.yuz,extended,stable] Patch "rbd: reset BACKOFF if unable to re-queue" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Nov. 20, 2012, 5:19 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/200481/
State New
Headers show


Herton Ronaldo Krzesinski - Nov. 20, 2012, 5:19 p.m.
This is a note to let you know that I have just added a patch titled

    rbd: reset BACKOFF if unable to re-queue

to the linux-3.5.y-queue branch of the 3.5.yuz extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.yuz tree, see



From 2f2bf413acd52e5a9bade876b9c7c726bf06b61f Mon Sep 17 00:00:00 2001
From: Alex Elder <>
Date: Mon, 8 Oct 2012 20:37:30 -0700
Subject: [PATCH 73/78] rbd: reset BACKOFF if unable to re-queue

commit 588377d6199034c36d335e7df5818b731fea072c upstream.

If ceph_fault() is unable to queue work after a delay, it sets the
BACKOFF connection flag so con_work() will attempt to do so.

In con_work(), when BACKOFF is set, if queue_delayed_work() doesn't
result in newly-queued work, it simply ignores this condition and
proceeds as if no backoff delay were desired.  There are two
problems with this--one of which is a bug.

The first problem is simply that the intended behavior is to back
off, and if we aren't able queue the work item to run after a delay
we're not doing that.

The only reason queue_delayed_work() won't queue work is if the
provided work item is already queued.  In the messenger, this
means that con_work() is already scheduled to be run again.  So
if we simply set the BACKOFF flag again when this occurs, we know
the next con_work() call will again attempt to hold off activity
on the connection until after the delay.

The second problem--the bug--is a leak of a reference count.  If
queue_delayed_work() returns 0 in con_work(), con->ops->put() drops
the connection reference held on entry to con_work().  However,
processing is (was) allowed to continue, and at the end of the
function a second con->ops->put() is called.

This patch fixes both problems.

Signed-off-by: Alex Elder <>
Reviewed-by: Sage Weil <>
Signed-off-by: Herton Ronaldo Krzesinski <>
 net/ceph/messenger.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)



diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 8ba0eee..0de041f 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -2296,10 +2296,11 @@  restart:
 		} else {
-			con->ops->put(con);
 			dout("con_work %p FAILED to back off %lu\n", con,
+			set_bit(CON_FLAG_BACKOFF, &con->flags);
+		goto done;

 	if (con->state == CON_STATE_STANDBY) {