From: Philipp Reisner <philipp.reisner@linbit.com>
To: linux-kernel@vger.kernel.org, Jens Axboe <axboe@kernel.dk>
Cc: drbd-dev@lists.linbit.com
Subject: [PATCH 01/16] drbd: Concurrent write detection fix
Date: Wed, 31 Aug 2011 17:10:53 +0200 [thread overview]
Message-ID: <1314803468-1201-2-git-send-email-philipp.reisner@linbit.com> (raw)
In-Reply-To: <1314803468-1201-1-git-send-email-philipp.reisner@linbit.com>
From: Andreas Gruenbacher <agruen@linbit.com>
Commit 9b1e63e changed the concurrent write detection algorithm to only insert
peer requests into write_requests tree after determining that there is no
conflict. With this change, new conflicting local requests could be added
while the algorithm runs, but this case was not handled correctly. Instead of
making the algorithm deal with this case, switch back to adding peer requests
to the write_requests tree immediately: this improves fairness.
When a peer request is discarded, remove that request from the write_requests
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
drivers/block/drbd/drbd_receiver.c | 41 ++++++++++++++++++-----------------
1 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 1b67426..987af1a 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1639,16 +1639,10 @@ static int e_send_discard_ack(struct drbd_work *w, int unused)
struct drbd_peer_request *peer_req =
container_of(w, struct drbd_peer_request, w);
struct drbd_conf *mdev = w->mdev;
- int ok = 1;
+ int ok;
D_ASSERT(mdev->tconn->net_conf->wire_protocol == DRBD_PROT_C);
ok = drbd_send_ack(mdev, P_DISCARD_ACK, peer_req);
-
- spin_lock_irq(&mdev->tconn->req_lock);
- D_ASSERT(!drbd_interval_empty(&peer_req->i));
- drbd_remove_epoch_entry_interval(mdev, peer_req);
- spin_unlock_irq(&mdev->tconn->req_lock);
-
dec_unacked(mdev);
return ok;
@@ -1839,6 +1833,12 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
spin_lock_irq(&mdev->tconn->req_lock);
+ /*
+ * Inserting the peer request into the write_requests tree will
+ * prevent new conflicting local requests from being added.
+ */
+ drbd_insert_interval(&mdev->write_requests, &peer_req->i);
+
first = 1;
for (;;) {
struct drbd_interval *i;
@@ -1847,26 +1847,26 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
prepare_to_wait(&mdev->misc_wait, &wait,
TASK_INTERRUPTIBLE);
- i = drbd_find_overlap(&mdev->write_requests, sector, size);
- if (i) {
+ drbd_for_each_overlap(i, &mdev->write_requests, sector, size) {
+ struct drbd_request *req2;
+
+ if (i == &peer_req->i || !i->local)
+ continue;
+
/* only ALERT on first iteration,
* we may be woken up early... */
if (first)
- dev_alert(DEV, "%s[%u] Concurrent %s write detected!"
+ dev_alert(DEV, "%s[%u] Concurrent local write detected!"
" new: %llus +%u; pending: %llus +%u\n",
current->comm, current->pid,
- i->local ? "local" : "remote",
(unsigned long long)sector, size,
(unsigned long long)i->sector, i->size);
- if (i->local) {
- struct drbd_request *req2;
-
- req2 = container_of(i, struct drbd_request, i);
- if (req2->rq_state & RQ_NET_PENDING)
- ++have_unacked;
- }
+ req2 = container_of(i, struct drbd_request, i);
+ if (req2->rq_state & RQ_NET_PENDING)
+ ++have_unacked;
++have_conflict;
+ break;
}
if (!have_conflict)
break;
@@ -1875,6 +1875,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
if (first && discard && have_unacked) {
dev_alert(DEV, "Concurrent write! [DISCARD BY FLAG] sec=%llus\n",
(unsigned long long)sector);
+ drbd_remove_epoch_entry_interval(mdev, peer_req);
inc_unacked(mdev);
peer_req->w.cb = e_send_discard_ack;
list_add_tail(&peer_req->w.list, &mdev->done_ee);
@@ -1891,6 +1892,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
}
if (signal_pending(current)) {
+ drbd_remove_epoch_entry_interval(mdev, peer_req);
spin_unlock_irq(&mdev->tconn->req_lock);
finish_wait(&mdev->misc_wait, &wait);
goto out_interrupted;
@@ -1909,12 +1911,11 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
* there must be none now. */
D_ASSERT(have_unacked == 0);
}
+ /* FIXME: Introduce a timeout here after which we disconnect. */
schedule();
spin_lock_irq(&mdev->tconn->req_lock);
}
finish_wait(&mdev->misc_wait, &wait);
-
- drbd_insert_interval(&mdev->write_requests, &peer_req->i);
}
list_add(&peer_req->w.list, &mdev->active_ee);
--
1.7.4.1
next prev parent reply other threads:[~2011-08-31 15:14 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-31 15:10 [RFC 00/16] drbd: part 3 of adding multiple volume support to drbd Philipp Reisner
2011-08-31 15:10 ` Philipp Reisner [this message]
2011-08-31 15:10 ` [PATCH 02/16] drbd: Replace atomic_add_return with atomic_inc_return Philipp Reisner
2011-08-31 15:10 ` [PATCH 03/16] drbd: Use ping-timeout when waiting for missing ack packets Philipp Reisner
2011-08-31 15:10 ` [PATCH 04/16] drbd: Improve how conflicting writes are handled Philipp Reisner
2011-08-31 15:10 ` [PATCH 05/16] drbd: Remove redundant check Philipp Reisner
2011-08-31 15:10 ` [PATCH 06/16] drbd: Get rid of P_MAX_CMD Philipp Reisner
2011-08-31 15:10 ` [PATCH 07/16] drbd: Replace get_asender_cmd() with its implementation Philipp Reisner
2011-08-31 15:11 ` [PATCH 08/16] drbd: Remove left-over function prototypes Philipp Reisner
2011-08-31 15:11 ` [PATCH 09/16] drbd: Reworked the unconfiguring and thread stopping code Philipp Reisner
2011-08-31 15:11 ` [PATCH 10/16] drbd: Removed the mdev parameter from the ..to_tags() and ...from_tags() functions Philipp Reisner
2011-08-31 15:11 ` [PATCH 11/16] drbd: Improved the dec_*() macros Philipp Reisner
2011-08-31 15:11 ` [PATCH 12/16] drbd: Converted the transfer log from mdev to tconn Philipp Reisner
2011-08-31 15:11 ` [PATCH 13/16] drbd: Preparing the connector interface to operator on connections Philipp Reisner
2011-08-31 15:11 ` [PATCH 14/16] drbd: Converted drbd_nl_(net_conf|disconnect)() from mdev to tconn Philipp Reisner
2011-08-31 15:11 ` [PATCH 15/16] drbd: Implemented new commands to create/delete connections/minors Philipp Reisner
2011-08-31 15:11 ` [PATCH 16/16] drbd: Replaced the minor_table array by an idr Philipp Reisner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1314803468-1201-2-git-send-email-philipp.reisner@linbit.com \
--to=philipp.reisner@linbit.com \
--cc=axboe@kernel.dk \
--cc=drbd-dev@lists.linbit.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®