diff options
author | Alex Elder <elder@inktank.com> | 2012-10-08 23:37:30 -0400 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2012-10-10 01:00:44 -0400 |
commit | 802c6d967fbdcd2cbc91b917425661bb8bbfaade (patch) | |
tree | a5a64ac537fb69ecb1edd55db8346089fecb9f84 /net | |
parent | 8618e30bc14b06bfafa0f164cca7b0e06451f88a (diff) |
rbd: define common queue_con_delay()
This patch defines a single function, queue_con_delay() to call
queue_delayed_work() for a connection. It basically generalizes
what was previously queue_con() by adding the delay argument.
queue_con() is now a simple helper that passes 0 for its delay.
queue_con_delay() returns 0 if it queued work or an errno if it
did not for some reason.
If con_work() finds the BACKOFF flag set for a connection, it now
calls queue_con_delay() to handle arranging to start again after a
delay.
Note about connection reference counts: con_work() only ever gets
called as a work item function. At the time that work is scheduled,
a reference to the connection is acquired, and the corresponding
con_work() call is then responsible for dropping that reference
before it returns.
Previously, the backoff handling inside con_work() silently handed
off its reference to delayed work it scheduled. Now that
queue_con_delay() is used, a new reference is acquired for the
newly-scheduled work, and the original reference is dropped by the
con->ops->put() call at the end of the function.
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/ceph/messenger.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 973c16c20c42..66f6f56bcb23 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -2244,22 +2244,33 @@ bad_tag: | |||
2244 | 2244 | ||
2245 | 2245 | ||
2246 | /* | 2246 | /* |
2247 | * Atomically queue work on a connection. Bump @con reference to | 2247 | * Atomically queue work on a connection after the specified delay. |
2248 | * avoid races with connection teardown. | 2248 | * Bump @con reference to avoid races with connection teardown. |
2249 | * Returns 0 if work was queued, or an error code otherwise. | ||
2249 | */ | 2250 | */ |
2250 | static void queue_con(struct ceph_connection *con) | 2251 | static int queue_con_delay(struct ceph_connection *con, unsigned long delay) |
2251 | { | 2252 | { |
2252 | if (!con->ops->get(con)) { | 2253 | if (!con->ops->get(con)) { |
2253 | dout("queue_con %p ref count 0\n", con); | 2254 | dout("%s %p ref count 0\n", __func__, con); |
2254 | return; | 2255 | |
2256 | return -ENOENT; | ||
2255 | } | 2257 | } |
2256 | 2258 | ||
2257 | if (!queue_delayed_work(ceph_msgr_wq, &con->work, 0)) { | 2259 | if (!queue_delayed_work(ceph_msgr_wq, &con->work, delay)) { |
2258 | dout("queue_con %p - already queued\n", con); | 2260 | dout("%s %p - already queued\n", __func__, con); |
2259 | con->ops->put(con); | 2261 | con->ops->put(con); |
2260 | } else { | 2262 | |
2261 | dout("queue_con %p\n", con); | 2263 | return -EBUSY; |
2262 | } | 2264 | } |
2265 | |||
2266 | dout("%s %p %lu\n", __func__, con, delay); | ||
2267 | |||
2268 | return 0; | ||
2269 | } | ||
2270 | |||
2271 | static void queue_con(struct ceph_connection *con) | ||
2272 | { | ||
2273 | (void) queue_con_delay(con, 0); | ||
2263 | } | 2274 | } |
2264 | 2275 | ||
2265 | /* | 2276 | /* |
@@ -2294,14 +2305,11 @@ restart: | |||
2294 | 2305 | ||
2295 | if (test_and_clear_bit(CON_FLAG_BACKOFF, &con->flags)) { | 2306 | if (test_and_clear_bit(CON_FLAG_BACKOFF, &con->flags)) { |
2296 | dout("con_work %p backing off\n", con); | 2307 | dout("con_work %p backing off\n", con); |
2297 | if (queue_delayed_work(ceph_msgr_wq, &con->work, | 2308 | ret = queue_con_delay(con, round_jiffies_relative(con->delay)); |
2298 | round_jiffies_relative(con->delay))) { | 2309 | if (ret) { |
2299 | dout("con_work %p backoff %lu\n", con, con->delay); | ||
2300 | mutex_unlock(&con->mutex); | ||
2301 | return; | ||
2302 | } else { | ||
2303 | dout("con_work %p FAILED to back off %lu\n", con, | 2310 | dout("con_work %p FAILED to back off %lu\n", con, |
2304 | con->delay); | 2311 | con->delay); |
2312 | BUG_ON(ret == -ENOENT); | ||
2305 | set_bit(CON_FLAG_BACKOFF, &con->flags); | 2313 | set_bit(CON_FLAG_BACKOFF, &con->flags); |
2306 | } | 2314 | } |
2307 | goto done; | 2315 | goto done; |