Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 346220
b: refs/heads/master
c: 6f3465e
h: refs/heads/master
v: v3
  • Loading branch information
Lars Ellenberg authored and Philipp Reisner committed Nov 8, 2012
1 parent c0bba9a commit cf98d6d
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0c849666016cbf541c1030eec55f5f8dd1fba513
refs/heads/master: 6f3465ed82b10922effe364676103cbd4f2bcd81
6 changes: 6 additions & 0 deletions trunk/drivers/block/drbd/drbd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,12 @@ enum {
CONN_DRY_RUN, /* Expect disconnect after resync handshake. */
CREATE_BARRIER, /* next P_DATA is preceded by a P_BARRIER */
STATE_SENT, /* Do not change state/UUIDs while this is set */
CALLBACK_PENDING, /* Whether we have a call_usermodehelper(, UMH_WAIT_PROC)
* pending, from drbd worker context.
* If set, bdi_write_congested() returns true,
* so shrink_page_list() would not recurse into,
* and potentially deadlock on, this drbd worker.
*/
};

struct drbd_tconn { /* is a resource from the config file */
Expand Down
16 changes: 16 additions & 0 deletions trunk/drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2338,6 +2338,22 @@ static int drbd_congested(void *congested_data, int bdi_bits)
goto out;
}

if (test_bit(CALLBACK_PENDING, &mdev->tconn->flags)) {
r |= (1 << BDI_async_congested);
/* Without good local data, we would need to read from remote,
* and that would need the worker thread as well, which is
* currently blocked waiting for that usermode helper to
* finish.
*/
if (!get_ldev_if_state(mdev, D_UP_TO_DATE))
r |= (1 << BDI_sync_congested);
else
put_ldev(mdev);
r &= bdi_bits;
reason = 'c';
goto out;
}

if (get_ldev(mdev)) {
q = bdev_get_queue(mdev->ldev->backing_bdev);
r = bdi_congested(&q->backing_dev_info, bdi_bits);
Expand Down
9 changes: 8 additions & 1 deletion trunk/drivers/block/drbd/drbd_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,11 +323,15 @@ int drbd_khelper(struct drbd_conf *mdev, char *cmd)
NULL };
char mb[12];
char *argv[] = {usermode_helper, cmd, mb, NULL };
struct drbd_tconn *tconn = mdev->tconn;
struct sib_info sib;
int ret;

if (current == tconn->worker.task)
set_bit(CALLBACK_PENDING, &tconn->flags);

snprintf(mb, 12, "minor-%d", mdev_to_minor(mdev));
setup_khelper_env(mdev->tconn, envp);
setup_khelper_env(tconn, envp);

/* The helper may take some time.
* write out any unsynced meta data changes now */
Expand All @@ -350,6 +354,9 @@ int drbd_khelper(struct drbd_conf *mdev, char *cmd)
sib.helper_exit_code = ret;
drbd_bcast_event(mdev, &sib);

if (current == tconn->worker.task)
clear_bit(CALLBACK_PENDING, &tconn->flags);

if (ret < 0) /* Ignore any ERRNOs we got. */
ret = 0;

Expand Down

0 comments on commit cf98d6d

Please sign in to comment.