summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2011-01-27 16:12:23 +0300
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-09-28 12:26:29 +0400
commita500c2efbbb3a57f83e18382e927b18513aca4cd (patch)
treec298951b9228729fb939747e651a928af5469631
parent9e204cddaf76d19ce0e84f025b0946110694dbfb (diff)
downloadlinux-a500c2efbbb3a57f83e18382e927b18513aca4cd.tar.xz
drbd: struct drbd_request: Introduce a new collision flag
This flag is set when a processes puts itself to sleep to wait for a conflicting request to complete. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r--drivers/block/drbd/drbd_receiver.c7
-rw-r--r--drivers/block/drbd/drbd_req.c42
-rw-r--r--drivers/block/drbd/drbd_req.h7
3 files changed, 15 insertions, 41 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index b4e1dab62dc1..d9f3f7fd9bb2 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -1815,6 +1815,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
first = 1;
for (;;) {
struct drbd_interval *i;
+ struct drbd_request *req2;
int have_unacked = 0;
int have_conflict = 0;
prepare_to_wait(&mdev->misc_wait, &wait,
@@ -1822,8 +1823,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
i = drbd_find_overlap(&mdev->write_requests, sector, size);
if (i) {
- struct drbd_request *req2 =
- container_of(i, struct drbd_request, i);
+ req2 = container_of(i, struct drbd_request, i);
/* only ALERT on first iteration,
* we may be woken up early... */
@@ -1869,6 +1869,9 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
goto out_interrupted;
}
+ /* Indicate to wake up mdev->misc_wait upon completion. */
+ req2->rq_state |= RQ_COLLISION;
+
spin_unlock_irq(&mdev->tconn->req_lock);
if (first) {
first = 0;
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 25fa87c95a10..8b4ba94538bd 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -176,45 +176,9 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
req->epoch == mdev->tconn->newest_tle->br_number)
queue_barrier(mdev);
- /* we need to do the conflict detection stuff,
- * if the epoch_entries tree is non-empty and
- * this request has completed on the network */
- if ((s & RQ_NET_DONE) && !RB_EMPTY_ROOT(&mdev->epoch_entries)) {
- const sector_t sector = req->i.sector;
- const int size = req->i.size;
- struct drbd_interval *i;
-
- /* ASSERT:
- * there must be no conflicting requests, since
- * they must have been failed on the spot */
-
- i = drbd_find_overlap(&mdev->write_requests, sector, size);
- if (i) {
- struct drbd_request *req2 =
- container_of(i, struct drbd_request, i);
-
- dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; "
- "other: %p %llus +%u\n",
- req, (unsigned long long)sector, size,
- i, (unsigned long long)req2->i.sector, req2->i.size);
- }
-
- /* maybe "wake" those conflicting epoch entries
- * that wait for this request to finish.
- *
- * currently, there can be only _one_ such ee
- * (well, or some more, which would be pending
- * P_DISCARD_ACK not yet sent by the asender...),
- * since we block the receiver thread upon the
- * first conflict detection, which will wait on
- * misc_wait. maybe we want to assert that?
- *
- * anyways, if we found one,
- * we just have to do a wake_up. */
- i = drbd_find_overlap(&mdev->epoch_entries, sector, size);
- if (i)
- wake_up(&mdev->misc_wait);
- }
+ /* Wake up any processes waiting for this request to complete. */
+ if ((s & RQ_NET_DONE) && (s & RQ_COLLISION))
+ wake_up(&mdev->misc_wait);
}
void complete_master_bio(struct drbd_conf *mdev,
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 431e3f962c3a..7a7464a2b3a6 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -194,6 +194,12 @@ enum drbd_req_state_bits {
/* Should call drbd_al_complete_io() for this request... */
__RQ_IN_ACT_LOG,
+
+ /*
+ * Set when a processes puts itself to sleep to wait for this request
+ * to complete.
+ */
+ __RQ_COLLISION,
};
#define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING)
@@ -214,6 +220,7 @@ enum drbd_req_state_bits {
#define RQ_WRITE (1UL << __RQ_WRITE)
#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
+#define RQ_COLLISION (1UL << __RQ_COLLISION)
/* For waking up the frozen transfer log mod_req() has to return if the request
should be counted in the epoch object*/