[DRBD-cvs] svn commit by phil - r2293 - in trunk: . drbd - * Send
remote read requests from the worker context.
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Mon Jul 24 14:11:42 CEST 2006
*
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Author: phil
Date: 2006-07-24 14:11:40 +0200 (Mon, 24 Jul 2006)
New Revision: 2293
Modified:
trunk/ROADMAP
trunk/drbd/drbd_int.h
trunk/drbd/drbd_main.c
trunk/drbd/drbd_receiver.c
trunk/drbd/drbd_req.c
trunk/drbd/drbd_worker.c
Log:
* Send remote read requests from the worker context.
* Impose the max_buffers setting also on a primary node.
Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP 2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/ROADMAP 2006-07-24 12:11:40 UTC (rev 2293)
@@ -803,9 +803,8 @@
Simon works on this.
39 Send mirrored write requests out of the worker context.
- 30% DONE
- TODO: Honour the max-buffers setting for this.
- Think about read requests.
+ 90% DONE
+ TODO: Get rid of the "send_task" thing.
Maybe:
Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h 2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_int.h 2006-07-24 12:11:40 UTC (rev 2293)
@@ -756,6 +756,7 @@
drbd_state_t state;
wait_queue_head_t cstate_wait; // TODO Rename into "misc_wait".
+ wait_queue_head_t rq_wait;
unsigned int send_cnt;
unsigned int recv_cnt;
unsigned int read_cnt;
@@ -1126,7 +1127,6 @@
extern int drbd_md_sync_page_io(drbd_dev *mdev, struct drbd_backing_dev *bdev,
sector_t sector, int rw);
// worker callbacks
-extern int w_is_app_read (drbd_dev *, struct drbd_work *, int);
extern int w_is_resync_read (drbd_dev *, struct drbd_work *, int);
extern int w_read_retry_remote (drbd_dev *, struct drbd_work *, int);
extern int w_e_end_data_req (drbd_dev *, struct drbd_work *, int);
@@ -1139,6 +1139,8 @@
extern int w_make_resync_request (drbd_dev *, struct drbd_work *, int);
extern int w_send_dblock (drbd_dev *, struct drbd_work *, int);
extern int w_send_barrier (drbd_dev *, struct drbd_work *, int);
+extern int w_send_read_req (drbd_dev *, struct drbd_work *, int);
+
extern void resync_timer_fn(unsigned long data);
// drbd_receiver.c
@@ -1564,16 +1566,25 @@
D_ASSERT(atomic_read(&mdev->local_cnt)>=0);
}
+/*
static inline void inc_ap_bio(drbd_dev* mdev)
{
atomic_inc(&mdev->ap_bio_cnt);
}
+*/
static inline void dec_ap_bio(drbd_dev* mdev)
{
- if(atomic_dec_and_test(&mdev->ap_bio_cnt))
- wake_up(&mdev->cstate_wait);
+ int ap_bio = atomic_dec_return(&mdev->ap_bio_cnt);
+ if(ap_bio == 0) wake_up(&mdev->cstate_wait);
+
+ if(inc_net(mdev)) {
+ if(ap_bio < mdev->net_conf->max_buffers)
+ wake_up(&mdev->rq_wait);
+ dec_net(mdev);
+ }
+
D_ASSERT(atomic_read(&mdev->ap_bio_cnt)>=0);
}
Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c 2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_main.c 2006-07-24 12:11:40 UTC (rev 2293)
@@ -1978,12 +1978,12 @@
if (mdev->state.pdsk >= Inconsistent) /* implies cs >= Connected */ {
D_ASSERT(mdev->state.role == Primary);
if (test_and_clear_bit(UNPLUG_REMOTE,&mdev->flags)) {
- /* add to the front of the data.work queue,
+ /* add to the data.work queue,
* unless already queued.
* XXX this might be a good addition to drbd_queue_work
* anyways, to detect "double queuing" ... */
if (list_empty(&mdev->unplug_work.list))
- _drbd_queue_work_front(&mdev->data.work,&mdev->unplug_work);
+ _drbd_queue_work(&mdev->data.work,&mdev->unplug_work);
}
}
spin_unlock_irq(&mdev->req_lock);
@@ -2064,6 +2064,7 @@
mdev->md_sync_timer.data = (unsigned long) mdev;
init_waitqueue_head(&mdev->cstate_wait);
+ init_waitqueue_head(&mdev->rq_wait);
init_waitqueue_head(&mdev->ee_wait);
init_waitqueue_head(&mdev->al_wait);
Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c 2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_receiver.c 2006-07-24 12:11:40 UTC (rev 2293)
@@ -1045,8 +1045,6 @@
return FALSE;
}
- D_ASSERT(req->w.cb == w_is_app_read);
-
spin_lock(&mdev->pr_lock);
hlist_del(&req->colision);
spin_unlock(&mdev->pr_lock);
@@ -2940,7 +2938,6 @@
ERR("Got a corrupt block_id/sector pair(3).\n");
return FALSE;
}
- D_ASSERT(req->w.cb == w_is_app_read);
spin_lock(&mdev->pr_lock);
list_del(&req->w.list);
Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c 2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_req.c 2006-07-24 12:11:40 UTC (rev 2293)
@@ -124,19 +124,17 @@
int drbd_read_remote(drbd_dev *mdev, drbd_request_t *req)
{
- int rv;
- struct bio *bio = req->master_bio;
-
- req->w.cb = w_is_app_read;
+ req->w.cb = w_send_read_req;
spin_lock(&mdev->pr_lock);
INIT_HLIST_NODE(&req->colision);
hlist_add_head( &req->colision, mdev->app_reads_hash +
ar_hash_fn(mdev, drbd_req_get_sector(req) ));
spin_unlock(&mdev->pr_lock);
set_bit(UNPLUG_REMOTE,&mdev->flags);
- rv=drbd_send_drequest(mdev, DataRequest, bio->bi_sector, bio->bi_size,
- (unsigned long)req);
- return rv;
+
+ drbd_queue_work(mdev, &mdev->data.work, &req->w);
+
+ return 1;
}
int drbd_pr_verify(drbd_dev *mdev, drbd_request_t * req, sector_t sector)
@@ -224,7 +222,14 @@
{
drbd_request_t *req;
int local, remote;
+ int mxb;
+ mxb = 1000000; /* Artificial limit on open requests */
+ if(inc_net(mdev)) {
+ mxb = mdev->net_conf->max_buffers;
+ dec_net(mdev);
+ }
+
/* allocate outside of all locks
*/
req = drbd_req_new(mdev,bio);
@@ -237,10 +242,6 @@
return 0;
}
- /* XXX req->w.cb = something; drbd_queue_work() ....
- * Not yet.
- */
-
// down_read(mdev->device_lock);
wait_event( mdev->cstate_wait,
@@ -321,7 +322,9 @@
/* we need to plug ALWAYS since we possibly need to kick lo_dev */
drbd_plug_device(mdev);
- inc_ap_bio(mdev); // XXX maybe make this the first thing to do in drbd_make_request
+ // inc_ap_bio(mdev); do not allow more open requests than max_buffers!
+ wait_event( mdev->rq_wait,atomic_add_unless(&mdev->ap_bio_cnt,1,mxb) );
+
if (remote) {
/* either WRITE and Connected,
* or READ, and no local disk,
@@ -368,7 +371,6 @@
up(&mdev->data.mutex);
} else {
// this node is diskless ...
- inc_ap_pending(mdev);
drbd_read_remote(mdev,req);
}
}
Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c 2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_worker.c 2006-07-24 12:11:40 UTC (rev 2293)
@@ -242,7 +242,6 @@
ok = drbd_io_error(mdev);
if(unlikely(!ok)) ERR("Sending in w_read_retry_remote() failed\n");
- inc_ap_pending(mdev);
ok = drbd_read_remote(mdev,req);
if(unlikely(!ok)) {
ERR("drbd_read_remote() failed\n");
@@ -270,15 +269,6 @@
return 0;
}
-/* in case we need it. currently unused,
- * since should be assigned to "w_read_retry_remote"
- */
-int w_is_app_read(drbd_dev *mdev, struct drbd_work *w, int unused)
-{
- ERR("%s: Typecheck only, should never be called!\n", __FUNCTION__ );
- return 0;
-}
-
void resync_timer_fn(unsigned long data)
{
unsigned long flags;
@@ -443,6 +433,9 @@
return 1;
}
+/**
+ * w_e_end_data_req: Send the answer (DataReply) to a DataRequest.
+ */
int w_e_end_data_req(drbd_dev *mdev, struct drbd_work *w, int cancel)
{
struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w;
@@ -478,6 +471,9 @@
return ok;
}
+/**
+ * w_e_end_data_req: Send the answer (RSDataReply) to a RSDataRequest.
+ */
int w_e_end_rsdata_req(drbd_dev *mdev, struct drbd_work *w, int cancel)
{
struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w;
@@ -557,6 +553,9 @@
return drbd_send_short_cmd(mdev,UnplugRemote);
}
+/**
+ * w_send_dblock: Send a mirrored write request.
+ */
int w_send_dblock(drbd_dev *mdev, struct drbd_work *w, int cancel)
{
drbd_request_t *req = (drbd_request_t *)w;
@@ -582,6 +581,31 @@
return ok;
}
+/**
+ * w_send_read_req: Send a read requests.
+ */
+int w_send_read_req(drbd_dev *mdev, struct drbd_work *w, int cancel)
+{
+ drbd_request_t *req = (drbd_request_t *)w;
+ struct bio *bio = req->master_bio;
+ int ok;
+
+ inc_ap_pending(mdev);
+
+ if (unlikely(cancel)) return 1;
+
+ ok = drbd_send_drequest(mdev, DataRequest, bio->bi_sector, bio->bi_size,
+ (unsigned long)req);
+
+ if (!ok) {
+ if (mdev->state.conn >= Connected)
+ drbd_force_state(mdev,NS(conn,NetworkFailure));
+ drbd_thread_restart_nowait(&mdev->receiver);
+ }
+
+ return ok;
+}
+
STATIC void drbd_global_lock(void)
{
int i;
More information about the drbd-cvs
mailing list