mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 10:06:43 +07:00
drbd: Allow to wait for the completion of an epoch entry as well
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
parent
3e05146f0a
commit
53840641bb
@ -9,6 +9,7 @@ struct drbd_interval {
|
|||||||
sector_t sector; /* start sector of the interval */
|
sector_t sector; /* start sector of the interval */
|
||||||
unsigned int size; /* size in bytes */
|
unsigned int size; /* size in bytes */
|
||||||
sector_t end; /* highest interval end in subtree */
|
sector_t end; /* highest interval end in subtree */
|
||||||
|
int waiting:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void drbd_clear_interval(struct drbd_interval *i)
|
static inline void drbd_clear_interval(struct drbd_interval *i)
|
||||||
|
@ -334,13 +334,15 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
drbd_clear_interval(&e->i);
|
drbd_clear_interval(&e->i);
|
||||||
|
e->i.size = data_size;
|
||||||
|
e->i.sector = sector;
|
||||||
|
e->i.waiting = false;
|
||||||
|
|
||||||
e->epoch = NULL;
|
e->epoch = NULL;
|
||||||
e->mdev = mdev;
|
e->mdev = mdev;
|
||||||
e->pages = page;
|
e->pages = page;
|
||||||
atomic_set(&e->pending_bios, 0);
|
atomic_set(&e->pending_bios, 0);
|
||||||
e->i.size = data_size;
|
|
||||||
e->flags = 0;
|
e->flags = 0;
|
||||||
e->i.sector = sector;
|
|
||||||
/*
|
/*
|
||||||
* The block_id is opaque to the receiver. It is not endianness
|
* The block_id is opaque to the receiver. It is not endianness
|
||||||
* converted, and sent back to the sender unchanged.
|
* converted, and sent back to the sender unchanged.
|
||||||
@ -1172,6 +1174,19 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drbd_remove_epoch_entry_interval(struct drbd_conf *mdev,
|
||||||
|
struct drbd_epoch_entry *e)
|
||||||
|
{
|
||||||
|
struct drbd_interval *i = &e->i;
|
||||||
|
|
||||||
|
drbd_remove_interval(&mdev->write_requests, i);
|
||||||
|
drbd_clear_interval(i);
|
||||||
|
|
||||||
|
/* Wake up any processes waiting for this epoch entry to complete. */
|
||||||
|
if (i->waiting)
|
||||||
|
wake_up(&mdev->misc_wait);
|
||||||
|
}
|
||||||
|
|
||||||
static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
|
static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd,
|
||||||
unsigned int data_size)
|
unsigned int data_size)
|
||||||
{
|
{
|
||||||
@ -1591,8 +1606,7 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
|
|||||||
if (mdev->tconn->net_conf->two_primaries) {
|
if (mdev->tconn->net_conf->two_primaries) {
|
||||||
spin_lock_irq(&mdev->tconn->req_lock);
|
spin_lock_irq(&mdev->tconn->req_lock);
|
||||||
D_ASSERT(!drbd_interval_empty(&e->i));
|
D_ASSERT(!drbd_interval_empty(&e->i));
|
||||||
drbd_remove_interval(&mdev->epoch_entries, &e->i);
|
drbd_remove_epoch_entry_interval(mdev, e);
|
||||||
drbd_clear_interval(&e->i);
|
|
||||||
spin_unlock_irq(&mdev->tconn->req_lock);
|
spin_unlock_irq(&mdev->tconn->req_lock);
|
||||||
} else
|
} else
|
||||||
D_ASSERT(drbd_interval_empty(&e->i));
|
D_ASSERT(drbd_interval_empty(&e->i));
|
||||||
@ -1612,8 +1626,7 @@ static int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int u
|
|||||||
|
|
||||||
spin_lock_irq(&mdev->tconn->req_lock);
|
spin_lock_irq(&mdev->tconn->req_lock);
|
||||||
D_ASSERT(!drbd_interval_empty(&e->i));
|
D_ASSERT(!drbd_interval_empty(&e->i));
|
||||||
drbd_remove_interval(&mdev->epoch_entries, &e->i);
|
drbd_remove_epoch_entry_interval(mdev, e);
|
||||||
drbd_clear_interval(&e->i);
|
|
||||||
spin_unlock_irq(&mdev->tconn->req_lock);
|
spin_unlock_irq(&mdev->tconn->req_lock);
|
||||||
|
|
||||||
dec_unacked(mdev);
|
dec_unacked(mdev);
|
||||||
@ -1860,17 +1873,14 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
drbd_remove_interval(&mdev->epoch_entries, &e->i);
|
drbd_remove_epoch_entry_interval(mdev, e);
|
||||||
drbd_clear_interval(&e->i);
|
|
||||||
|
|
||||||
spin_unlock_irq(&mdev->tconn->req_lock);
|
spin_unlock_irq(&mdev->tconn->req_lock);
|
||||||
|
|
||||||
finish_wait(&mdev->misc_wait, &wait);
|
finish_wait(&mdev->misc_wait, &wait);
|
||||||
goto out_interrupted;
|
goto out_interrupted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Indicate to wake up mdev->misc_wait upon completion. */
|
/* Indicate to wake up mdev->misc_wait upon completion. */
|
||||||
req2->rq_state |= RQ_COLLISION;
|
i->waiting = true;
|
||||||
|
|
||||||
spin_unlock_irq(&mdev->tconn->req_lock);
|
spin_unlock_irq(&mdev->tconn->req_lock);
|
||||||
if (first) {
|
if (first) {
|
||||||
@ -1922,8 +1932,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd,
|
|||||||
dev_err(DEV, "submit failed, triggering re-connect\n");
|
dev_err(DEV, "submit failed, triggering re-connect\n");
|
||||||
spin_lock_irq(&mdev->tconn->req_lock);
|
spin_lock_irq(&mdev->tconn->req_lock);
|
||||||
list_del(&e->w.list);
|
list_del(&e->w.list);
|
||||||
drbd_remove_interval(&mdev->epoch_entries, &e->i);
|
drbd_remove_epoch_entry_interval(mdev, e);
|
||||||
drbd_clear_interval(&e->i);
|
|
||||||
spin_unlock_irq(&mdev->tconn->req_lock);
|
spin_unlock_irq(&mdev->tconn->req_lock);
|
||||||
if (e->flags & EE_CALL_AL_COMPLETE_IO)
|
if (e->flags & EE_CALL_AL_COMPLETE_IO)
|
||||||
drbd_al_complete_io(mdev, e->i.sector);
|
drbd_al_complete_io(mdev, e->i.sector);
|
||||||
|
@ -70,9 +70,12 @@ static struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
|
|||||||
req->mdev = mdev;
|
req->mdev = mdev;
|
||||||
req->master_bio = bio_src;
|
req->master_bio = bio_src;
|
||||||
req->epoch = 0;
|
req->epoch = 0;
|
||||||
|
|
||||||
drbd_clear_interval(&req->i);
|
drbd_clear_interval(&req->i);
|
||||||
req->i.sector = bio_src->bi_sector;
|
req->i.sector = bio_src->bi_sector;
|
||||||
req->i.size = bio_src->bi_size;
|
req->i.size = bio_src->bi_size;
|
||||||
|
req->i.waiting = false;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&req->tl_requests);
|
INIT_LIST_HEAD(&req->tl_requests);
|
||||||
INIT_LIST_HEAD(&req->w.list);
|
INIT_LIST_HEAD(&req->w.list);
|
||||||
|
|
||||||
@ -175,10 +178,6 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
|
|||||||
(s & RQ_NET_SENT) != 0 &&
|
(s & RQ_NET_SENT) != 0 &&
|
||||||
req->epoch == mdev->tconn->newest_tle->br_number)
|
req->epoch == mdev->tconn->newest_tle->br_number)
|
||||||
queue_barrier(mdev);
|
queue_barrier(mdev);
|
||||||
|
|
||||||
/* 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,
|
void complete_master_bio(struct drbd_conf *mdev,
|
||||||
@ -188,6 +187,20 @@ void complete_master_bio(struct drbd_conf *mdev,
|
|||||||
dec_ap_bio(mdev);
|
dec_ap_bio(mdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void drbd_remove_request_interval(struct rb_root *root,
|
||||||
|
struct drbd_request *req)
|
||||||
|
{
|
||||||
|
struct drbd_conf *mdev = req->mdev;
|
||||||
|
struct drbd_interval *i = &req->i;
|
||||||
|
|
||||||
|
drbd_remove_interval(root, i);
|
||||||
|
|
||||||
|
/* Wake up any processes waiting for this request to complete. */
|
||||||
|
if (i->waiting)
|
||||||
|
wake_up(&mdev->misc_wait);
|
||||||
|
}
|
||||||
|
|
||||||
/* Helper for __req_mod().
|
/* Helper for __req_mod().
|
||||||
* Set m->bio to the master bio, if it is fit to be completed,
|
* Set m->bio to the master bio, if it is fit to be completed,
|
||||||
* or leave it alone (it is initialized to NULL in __req_mod),
|
* or leave it alone (it is initialized to NULL in __req_mod),
|
||||||
@ -251,7 +264,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
|
|||||||
root = &mdev->write_requests;
|
root = &mdev->write_requests;
|
||||||
else
|
else
|
||||||
root = &mdev->read_requests;
|
root = &mdev->read_requests;
|
||||||
drbd_remove_interval(root, &req->i);
|
drbd_remove_request_interval(root, req);
|
||||||
} else
|
} else
|
||||||
D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
|
D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
|
||||||
|
|
||||||
|
@ -194,12 +194,6 @@ enum drbd_req_state_bits {
|
|||||||
|
|
||||||
/* Should call drbd_al_complete_io() for this request... */
|
/* Should call drbd_al_complete_io() for this request... */
|
||||||
__RQ_IN_ACT_LOG,
|
__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)
|
#define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING)
|
||||||
@ -220,7 +214,6 @@ enum drbd_req_state_bits {
|
|||||||
|
|
||||||
#define RQ_WRITE (1UL << __RQ_WRITE)
|
#define RQ_WRITE (1UL << __RQ_WRITE)
|
||||||
#define RQ_IN_ACT_LOG (1UL << __RQ_IN_ACT_LOG)
|
#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
|
/* For waking up the frozen transfer log mod_req() has to return if the request
|
||||||
should be counted in the epoch object*/
|
should be counted in the epoch object*/
|
||||||
|
Loading…
Reference in New Issue
Block a user