diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-07-28 09:56:02 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2014-02-17 10:50:40 -0500 |
commit | b5043c5e2ca0de11a22e02cd8835c9489f833722 (patch) | |
tree | 337175f55d4e53b9d11f1b521234934d035ffbb9 | |
parent | 84b8c06b6591e73250e6ab4834a02a86c8994b91 (diff) |
drbd: Turn conn_flush_workqueue() into drbd_flush_workqueue()
The new function can flush any work queue, not just the work queue of the data
socket of a connection.
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 12 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 24 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 10 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 22 |
4 files changed, 33 insertions, 35 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 3c52a4dc423d..d461a7f1eb3f 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -351,11 +351,6 @@ enum epoch_event { | |||
351 | EV_CLEANUP = 32, /* used as flag */ | 351 | EV_CLEANUP = 32, /* used as flag */ |
352 | }; | 352 | }; |
353 | 353 | ||
354 | struct drbd_wq_barrier { | ||
355 | struct drbd_work w; | ||
356 | struct completion done; | ||
357 | }; | ||
358 | |||
359 | struct digest_info { | 354 | struct digest_info { |
360 | int digest_size; | 355 | int digest_size; |
361 | void *digest; | 356 | void *digest; |
@@ -1354,12 +1349,7 @@ extern void __drbd_free_peer_req(struct drbd_device *, struct drbd_peer_request | |||
1354 | extern struct page *drbd_alloc_pages(struct drbd_peer_device *, unsigned int, bool); | 1349 | extern struct page *drbd_alloc_pages(struct drbd_peer_device *, unsigned int, bool); |
1355 | extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled); | 1350 | extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled); |
1356 | extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed); | 1351 | extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed); |
1357 | extern void conn_flush_workqueue(struct drbd_connection *connection); | ||
1358 | extern int drbd_connected(struct drbd_peer_device *); | 1352 | extern int drbd_connected(struct drbd_peer_device *); |
1359 | static inline void drbd_flush_workqueue(struct drbd_device *device) | ||
1360 | { | ||
1361 | conn_flush_workqueue(first_peer_device(device)->connection); | ||
1362 | } | ||
1363 | 1353 | ||
1364 | /* Yes, there is kernel_setsockopt, but only since 2.6.18. | 1354 | /* Yes, there is kernel_setsockopt, but only since 2.6.18. |
1365 | * So we have our own copy of it here. */ | 1355 | * So we have our own copy of it here. */ |
@@ -1714,6 +1704,8 @@ drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w) | |||
1714 | wake_up(&q->q_wait); | 1704 | wake_up(&q->q_wait); |
1715 | } | 1705 | } |
1716 | 1706 | ||
1707 | extern void drbd_flush_workqueue(struct drbd_work_queue *work_queue); | ||
1708 | |||
1717 | static inline void wake_asender(struct drbd_connection *connection) | 1709 | static inline void wake_asender(struct drbd_connection *connection) |
1718 | { | 1710 | { |
1719 | if (test_bit(SIGNAL_ASENDER, &connection->flags)) | 1711 | if (test_bit(SIGNAL_ASENDER, &connection->flags)) |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index ada1b07c564e..232cd570d3ae 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -2397,6 +2397,30 @@ static void drbd_init_workqueue(struct drbd_work_queue* wq) | |||
2397 | init_waitqueue_head(&wq->q_wait); | 2397 | init_waitqueue_head(&wq->q_wait); |
2398 | } | 2398 | } |
2399 | 2399 | ||
2400 | struct completion_work { | ||
2401 | struct drbd_work w; | ||
2402 | struct completion done; | ||
2403 | }; | ||
2404 | |||
2405 | static int w_complete(struct drbd_work *w, int cancel) | ||
2406 | { | ||
2407 | struct completion_work *completion_work = | ||
2408 | container_of(w, struct completion_work, w); | ||
2409 | |||
2410 | complete(&completion_work->done); | ||
2411 | return 0; | ||
2412 | } | ||
2413 | |||
2414 | void drbd_flush_workqueue(struct drbd_work_queue *work_queue) | ||
2415 | { | ||
2416 | struct completion_work completion_work; | ||
2417 | |||
2418 | completion_work.w.cb = w_complete; | ||
2419 | init_completion(&completion_work.done); | ||
2420 | drbd_queue_work(work_queue, &completion_work.w); | ||
2421 | wait_for_completion(&completion_work.done); | ||
2422 | } | ||
2423 | |||
2400 | struct drbd_resource *drbd_find_resource(const char *name) | 2424 | struct drbd_resource *drbd_find_resource(const char *name) |
2401 | { | 2425 | { |
2402 | struct drbd_resource *resource; | 2426 | struct drbd_resource *resource; |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 6b09eb693c96..2086b12d3f75 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -1181,7 +1181,7 @@ void drbd_reconsider_max_bio_size(struct drbd_device *device) | |||
1181 | static void conn_reconfig_start(struct drbd_connection *connection) | 1181 | static void conn_reconfig_start(struct drbd_connection *connection) |
1182 | { | 1182 | { |
1183 | drbd_thread_start(&connection->worker); | 1183 | drbd_thread_start(&connection->worker); |
1184 | conn_flush_workqueue(connection); | 1184 | drbd_flush_workqueue(&connection->sender_work); |
1185 | } | 1185 | } |
1186 | 1186 | ||
1187 | /* if still unconfigured, stops worker again. */ | 1187 | /* if still unconfigured, stops worker again. */ |
@@ -1600,7 +1600,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) | |||
1600 | */ | 1600 | */ |
1601 | wait_event(device->misc_wait, !atomic_read(&device->ap_pending_cnt) || drbd_suspended(device)); | 1601 | wait_event(device->misc_wait, !atomic_read(&device->ap_pending_cnt) || drbd_suspended(device)); |
1602 | /* and for any other previously queued work */ | 1602 | /* and for any other previously queued work */ |
1603 | drbd_flush_workqueue(device); | 1603 | drbd_flush_workqueue(&first_peer_device(device)->connection->sender_work); |
1604 | 1604 | ||
1605 | rv = _drbd_request_state(device, NS(disk, D_ATTACHING), CS_VERBOSE); | 1605 | rv = _drbd_request_state(device, NS(disk, D_ATTACHING), CS_VERBOSE); |
1606 | retcode = rv; /* FIXME: Type mismatch. */ | 1606 | retcode = rv; /* FIXME: Type mismatch. */ |
@@ -2249,7 +2249,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) | |||
2249 | 2249 | ||
2250 | ((char *)new_net_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0; | 2250 | ((char *)new_net_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0; |
2251 | 2251 | ||
2252 | conn_flush_workqueue(connection); | 2252 | drbd_flush_workqueue(&connection->sender_work); |
2253 | 2253 | ||
2254 | mutex_lock(&adm_ctx.resource->conf_update); | 2254 | mutex_lock(&adm_ctx.resource->conf_update); |
2255 | old_net_conf = connection->net_conf; | 2255 | old_net_conf = connection->net_conf; |
@@ -2589,7 +2589,7 @@ int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info) | |||
2589 | * Also wait for it's after_state_ch(). */ | 2589 | * Also wait for it's after_state_ch(). */ |
2590 | drbd_suspend_io(device); | 2590 | drbd_suspend_io(device); |
2591 | wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags)); | 2591 | wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags)); |
2592 | drbd_flush_workqueue(device); | 2592 | drbd_flush_workqueue(&first_peer_device(device)->connection->sender_work); |
2593 | 2593 | ||
2594 | /* If we happen to be C_STANDALONE R_SECONDARY, just change to | 2594 | /* If we happen to be C_STANDALONE R_SECONDARY, just change to |
2595 | * D_INCONSISTENT, and set all bits in the bitmap. Otherwise, | 2595 | * D_INCONSISTENT, and set all bits in the bitmap. Otherwise, |
@@ -2655,7 +2655,7 @@ int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info) | |||
2655 | * Also wait for it's after_state_ch(). */ | 2655 | * Also wait for it's after_state_ch(). */ |
2656 | drbd_suspend_io(device); | 2656 | drbd_suspend_io(device); |
2657 | wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags)); | 2657 | wait_event(device->misc_wait, !test_bit(BITMAP_IO, &device->flags)); |
2658 | drbd_flush_workqueue(device); | 2658 | drbd_flush_workqueue(&first_peer_device(device)->connection->sender_work); |
2659 | 2659 | ||
2660 | /* If we happen to be C_STANDALONE R_PRIMARY, just set all bits | 2660 | /* If we happen to be C_STANDALONE R_PRIMARY, just set all bits |
2661 | * in the bitmap. Otherwise, try to start a resync handshake | 2661 | * in the bitmap. Otherwise, try to start a resync handshake |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 87114361d804..1d9a99c031fa 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -4485,24 +4485,6 @@ static void drbdd(struct drbd_connection *connection) | |||
4485 | conn_request_state(connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD); | 4485 | conn_request_state(connection, NS(conn, C_PROTOCOL_ERROR), CS_HARD); |
4486 | } | 4486 | } |
4487 | 4487 | ||
4488 | static int w_complete(struct drbd_work *w, int cancel) | ||
4489 | { | ||
4490 | struct drbd_wq_barrier *b = container_of(w, struct drbd_wq_barrier, w); | ||
4491 | |||
4492 | complete(&b->done); | ||
4493 | return 0; | ||
4494 | } | ||
4495 | |||
4496 | void conn_flush_workqueue(struct drbd_connection *connection) | ||
4497 | { | ||
4498 | struct drbd_wq_barrier barr; | ||
4499 | |||
4500 | barr.w.cb = w_complete; | ||
4501 | init_completion(&barr.done); | ||
4502 | drbd_queue_work(&connection->sender_work, &barr.w); | ||
4503 | wait_for_completion(&barr.done); | ||
4504 | } | ||
4505 | |||
4506 | static void conn_disconnect(struct drbd_connection *connection) | 4488 | static void conn_disconnect(struct drbd_connection *connection) |
4507 | { | 4489 | { |
4508 | struct drbd_peer_device *peer_device; | 4490 | struct drbd_peer_device *peer_device; |
@@ -4590,14 +4572,14 @@ static int drbd_disconnected(struct drbd_peer_device *peer_device) | |||
4590 | /* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier, | 4572 | /* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier, |
4591 | * w_make_resync_request etc. which may still be on the worker queue | 4573 | * w_make_resync_request etc. which may still be on the worker queue |
4592 | * to be "canceled" */ | 4574 | * to be "canceled" */ |
4593 | drbd_flush_workqueue(device); | 4575 | drbd_flush_workqueue(&peer_device->connection->sender_work); |
4594 | 4576 | ||
4595 | drbd_finish_peer_reqs(device); | 4577 | drbd_finish_peer_reqs(device); |
4596 | 4578 | ||
4597 | /* This second workqueue flush is necessary, since drbd_finish_peer_reqs() | 4579 | /* This second workqueue flush is necessary, since drbd_finish_peer_reqs() |
4598 | might have issued a work again. The one before drbd_finish_peer_reqs() is | 4580 | might have issued a work again. The one before drbd_finish_peer_reqs() is |
4599 | necessary to reclain net_ee in drbd_finish_peer_reqs(). */ | 4581 | necessary to reclain net_ee in drbd_finish_peer_reqs(). */ |
4600 | drbd_flush_workqueue(device); | 4582 | drbd_flush_workqueue(&peer_device->connection->sender_work); |
4601 | 4583 | ||
4602 | /* need to do it again, drbd_finish_peer_reqs() may have populated it | 4584 | /* need to do it again, drbd_finish_peer_reqs() may have populated it |
4603 | * again via drbd_try_clear_on_disk_bm(). */ | 4585 | * again via drbd_try_clear_on_disk_bm(). */ |