aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-10-08 23:37:30 -0400
committerAlex Elder <elder@inktank.com>2012-10-10 01:00:44 -0400
commit802c6d967fbdcd2cbc91b917425661bb8bbfaade (patch)
treea5a64ac537fb69ecb1edd55db8346089fecb9f84 /net
parent8618e30bc14b06bfafa0f164cca7b0e06451f88a (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.c38
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 */
2250static void queue_con(struct ceph_connection *con) 2251static 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
2271static 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;