From e6ef8a5cb3fcf5e5529a26d2cab5bd891c7964b1 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Thu, 24 Mar 2011 18:07:54 +0100 Subject: [PATCH] drbd: Preallocate one page per drbd_socket as a receive buffer Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 4 ++- drivers/block/drbd/drbd_main.c | 22 +++++++++++++ drivers/block/drbd/drbd_receiver.c | 65 +++++++++++++++++--------------------- 3 files changed, 54 insertions(+), 37 deletions(-) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 74637cc..932ba03 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -554,6 +554,8 @@ struct p_delay_probe93 { #error "PAGE_SIZE too small" #endif +#define DRBD_SOCKET_BUFFER_SIZE 4096 + union p_polymorph { struct p_header header; struct p_handshake handshake; @@ -803,7 +805,7 @@ struct drbd_socket { /* this way we get our * send/receive buffers off the stack */ union p_polymorph sbuf; - union p_polymorph rbuf; + void *rbuf; }; struct drbd_md { diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index dbe5c63..004a8ce 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2272,6 +2272,19 @@ found: return tconn; } +static int drbd_alloc_socket(struct drbd_socket *socket) +{ + socket->rbuf = (void *) __get_free_page(GFP_KERNEL); + if (!socket->rbuf) + return -ENOMEM; + return 0; +} + +static void drbd_free_socket(struct drbd_socket *socket) +{ + free_page((unsigned long) socket->rbuf); +} + struct drbd_tconn *drbd_new_tconn(const char *name) { struct drbd_tconn *tconn; @@ -2284,6 +2297,11 @@ struct drbd_tconn *drbd_new_tconn(const char *name) if (!tconn->name) goto fail; + if (drbd_alloc_socket(&tconn->data)) + goto fail; + if (drbd_alloc_socket(&tconn->meta)) + goto fail; + if (!zalloc_cpumask_var(&tconn->cpu_mask, GFP_KERNEL)) goto fail; @@ -2322,6 +2340,8 @@ struct drbd_tconn *drbd_new_tconn(const char *name) fail: tl_cleanup(tconn); free_cpumask_var(tconn->cpu_mask); + drbd_free_socket(&tconn->meta); + drbd_free_socket(&tconn->data); kfree(tconn->name); kfree(tconn); @@ -2334,6 +2354,8 @@ void drbd_free_tconn(struct drbd_tconn *tconn) idr_destroy(&tconn->volumes); free_cpumask_var(tconn->cpu_mask); + drbd_free_socket(&tconn->meta); + drbd_free_socket(&tconn->data); kfree(tconn->name); kfree(tconn->int_dig_out); kfree(tconn->int_dig_in); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 91aa49f..50e837e 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -743,7 +743,7 @@ static int drbd_send_fp(struct drbd_tconn *tconn, struct socket *sock, enum drbd static enum drbd_packet drbd_recv_fp(struct drbd_tconn *tconn, struct socket *sock) { - struct p_header80 *h = &tconn->data.rbuf.header.h80; + struct p_header80 *h = tconn->data.rbuf; int rr; rr = drbd_recv_short(sock, h, sizeof(*h), 0); @@ -994,7 +994,7 @@ static int decode_header(struct drbd_tconn *tconn, struct p_header *h, struct pa static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi) { - struct p_header *h = &tconn->data.rbuf.header; + struct p_header *h = tconn->data.rbuf; int err; err = drbd_recv_all_warn(tconn, h, sizeof(*h)); @@ -1236,7 +1236,7 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packet cmd, unsigned int data_size) { int rv; - struct p_barrier *p = &mdev->tconn->data.rbuf.barrier; + struct p_barrier *p = mdev->tconn->data.rbuf; struct drbd_epoch *epoch; inc_unacked(mdev); @@ -1546,7 +1546,7 @@ static int receive_DataReply(struct drbd_conf *mdev, enum drbd_packet cmd, struct drbd_request *req; sector_t sector; int err; - struct p_data *p = &mdev->tconn->data.rbuf.data; + struct p_data *p = mdev->tconn->data.rbuf; sector = be64_to_cpu(p->sector); @@ -1574,7 +1574,7 @@ static int receive_RSDataReply(struct drbd_conf *mdev, enum drbd_packet cmd, { sector_t sector; int err; - struct p_data *p = &mdev->tconn->data.rbuf.data; + struct p_data *p = mdev->tconn->data.rbuf; sector = be64_to_cpu(p->sector); D_ASSERT(p->block_id == ID_SYNCER); @@ -1963,7 +1963,7 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packet cmd, { sector_t sector; struct drbd_peer_request *peer_req; - struct p_data *p = &mdev->tconn->data.rbuf.data; + struct p_data *p = mdev->tconn->data.rbuf; u32 peer_seq = be32_to_cpu(p->seq_num); int rw = WRITE; u32 dp_flags; @@ -2147,7 +2147,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, enum drbd_packet cmd, struct digest_info *di = NULL; int size, verb; unsigned int fault_type; - struct p_block_req *p = &mdev->tconn->data.rbuf.block_req; + struct p_block_req *p = mdev->tconn->data.rbuf; sector = be64_to_cpu(p->sector); size = be32_to_cpu(p->blksize); @@ -2867,7 +2867,7 @@ static int cmp_after_sb(enum drbd_after_sb_p peer, enum drbd_after_sb_p self) static int receive_protocol(struct drbd_tconn *tconn, enum drbd_packet cmd, unsigned int data_size) { - struct p_protocol *p = &tconn->data.rbuf.protocol; + struct p_protocol *p = tconn->data.rbuf; int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; int p_want_lose, p_two_primaries, cf; char p_integrity_alg[SHARED_SECRET_MAX] = ""; @@ -2969,7 +2969,7 @@ struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev, static int receive_SyncParam(struct drbd_conf *mdev, enum drbd_packet cmd, unsigned int packet_size) { - struct p_rs_param_95 *p = &mdev->tconn->data.rbuf.rs_param_95; + struct p_rs_param_95 *p = mdev->tconn->data.rbuf; unsigned int header_size, data_size, exp_max_sz; struct crypto_hash *verify_tfm = NULL; struct crypto_hash *csums_tfm = NULL; @@ -3141,7 +3141,7 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev, static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd, unsigned int data_size) { - struct p_sizes *p = &mdev->tconn->data.rbuf.sizes; + struct p_sizes *p = mdev->tconn->data.rbuf; enum determine_dev_size dd = unchanged; sector_t p_size, p_usize, my_usize; int ldsc = 0; /* local disk size changed */ @@ -3239,7 +3239,7 @@ static int receive_sizes(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_uuids(struct drbd_conf *mdev, enum drbd_packet cmd, unsigned int data_size) { - struct p_uuids *p = &mdev->tconn->data.rbuf.uuids; + struct p_uuids *p = mdev->tconn->data.rbuf; u64 *p_uuid; int i, updated_uuids = 0; @@ -3335,7 +3335,7 @@ static union drbd_state convert_state(union drbd_state ps) static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd, unsigned int data_size) { - struct p_req_state *p = &mdev->tconn->data.rbuf.req_state; + struct p_req_state *p = mdev->tconn->data.rbuf; union drbd_state mask, val; enum drbd_state_rv rv; @@ -3362,7 +3362,7 @@ static int receive_req_state(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd, unsigned int data_size) { - struct p_req_state *p = &tconn->data.rbuf.req_state; + struct p_req_state *p = tconn->data.rbuf; union drbd_state mask, val; enum drbd_state_rv rv; @@ -3387,7 +3387,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, enum drbd_packet cmd static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd, unsigned int data_size) { - struct p_state *p = &mdev->tconn->data.rbuf.state; + struct p_state *p = mdev->tconn->data.rbuf; union drbd_state os, ns, peer_state; enum drbd_disk_state real_peer_disk; enum chg_state_flags cs_flags; @@ -3540,7 +3540,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packet cmd, unsigned int data_size) { - struct p_rs_uuid *p = &mdev->tconn->data.rbuf.rs_uuid; + struct p_rs_uuid *p = mdev->tconn->data.rbuf; wait_event(mdev->misc_wait, mdev->state.conn == C_WF_SYNC_UUID || @@ -3752,7 +3752,7 @@ static int receive_bitmap(struct drbd_conf *mdev, enum drbd_packet cmd, struct bm_xfer_ctx c; void *buffer; int err; - struct p_header *h = &mdev->tconn->data.rbuf.header; + struct p_header *h = mdev->tconn->data.rbuf; struct packet_info pi; drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED); @@ -3893,7 +3893,7 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, enum drbd_packet cmd, static int receive_out_of_sync(struct drbd_conf *mdev, enum drbd_packet cmd, unsigned int data_size) { - struct p_block_desc *p = &mdev->tconn->data.rbuf.block_desc; + struct p_block_desc *p = mdev->tconn->data.rbuf; switch (mdev->state.conn) { case C_WF_SYNC_UUID: @@ -3948,16 +3948,9 @@ static struct data_cmd drbd_cmd_handler[] = { [P_CONN_ST_CHG_REQ] = { 0, sizeof(struct p_req_state), CONN, { .conn_fn = receive_req_conn_state } }, }; -/* All handler functions that expect a sub-header get that sub-heder in - mdev->tconn->data.rbuf.header.head.payload. - - Usually in mdev->tconn->data.rbuf.header.head the callback can find the usual - p_header, but they may not rely on that. Since there is also p_header95 ! - */ - static void drbdd(struct drbd_tconn *tconn) { - struct p_header *header = &tconn->data.rbuf.header; + struct p_header *header = tconn->data.rbuf; struct packet_info pi; size_t shs; /* sub header size */ int err; @@ -4188,7 +4181,7 @@ static int drbd_send_handshake(struct drbd_tconn *tconn) static int drbd_do_handshake(struct drbd_tconn *tconn) { /* ASSERT current == tconn->receiver ... */ - struct p_handshake *p = &tconn->data.rbuf.handshake; + struct p_handshake *p = tconn->data.rbuf; const int expect = sizeof(struct p_handshake) - sizeof(struct p_header80); struct packet_info pi; int err; @@ -4435,7 +4428,7 @@ int drbdd_init(struct drbd_thread *thi) static int got_conn_RqSReply(struct drbd_tconn *tconn, enum drbd_packet cmd) { - struct p_req_state_reply *p = &tconn->meta.rbuf.req_state_reply; + struct p_req_state_reply *p = tconn->meta.rbuf; int retcode = be32_to_cpu(p->retcode); if (retcode >= SS_SUCCESS) { @@ -4452,7 +4445,7 @@ static int got_conn_RqSReply(struct drbd_tconn *tconn, enum drbd_packet cmd) static int got_RqSReply(struct drbd_conf *mdev, enum drbd_packet cmd) { - struct p_req_state_reply *p = &mdev->tconn->meta.rbuf.req_state_reply; + struct p_req_state_reply *p = mdev->tconn->meta.rbuf; int retcode = be32_to_cpu(p->retcode); if (retcode >= SS_SUCCESS) { @@ -4485,7 +4478,7 @@ static int got_PingAck(struct drbd_tconn *tconn, enum drbd_packet cmd) static int got_IsInSync(struct drbd_conf *mdev, enum drbd_packet cmd) { - struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack; + struct p_block_ack *p = mdev->tconn->meta.rbuf; sector_t sector = be64_to_cpu(p->sector); int blksize = be32_to_cpu(p->blksize); @@ -4530,7 +4523,7 @@ validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector, static int got_BlockAck(struct drbd_conf *mdev, enum drbd_packet cmd) { - struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack; + struct p_block_ack *p = mdev->tconn->meta.rbuf; sector_t sector = be64_to_cpu(p->sector); int blksize = be32_to_cpu(p->blksize); enum drbd_req_event what; @@ -4575,7 +4568,7 @@ static int got_BlockAck(struct drbd_conf *mdev, enum drbd_packet cmd) static int got_NegAck(struct drbd_conf *mdev, enum drbd_packet cmd) { - struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack; + struct p_block_ack *p = mdev->tconn->meta.rbuf; sector_t sector = be64_to_cpu(p->sector); int size = be32_to_cpu(p->blksize); bool missing_ok = mdev->tconn->net_conf->wire_protocol == DRBD_PROT_A || @@ -4608,7 +4601,7 @@ static int got_NegAck(struct drbd_conf *mdev, enum drbd_packet cmd) static int got_NegDReply(struct drbd_conf *mdev, enum drbd_packet cmd) { - struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack; + struct p_block_ack *p = mdev->tconn->meta.rbuf; sector_t sector = be64_to_cpu(p->sector); update_peer_seq(mdev, be32_to_cpu(p->seq_num)); @@ -4625,7 +4618,7 @@ static int got_NegRSDReply(struct drbd_conf *mdev, enum drbd_packet cmd) { sector_t sector; int size; - struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack; + struct p_block_ack *p = mdev->tconn->meta.rbuf; sector = be64_to_cpu(p->sector); size = be32_to_cpu(p->blksize); @@ -4654,7 +4647,7 @@ static int got_NegRSDReply(struct drbd_conf *mdev, enum drbd_packet cmd) static int got_BarrierAck(struct drbd_conf *mdev, enum drbd_packet cmd) { - struct p_barrier_ack *p = &mdev->tconn->meta.rbuf.barrier_ack; + struct p_barrier_ack *p = mdev->tconn->meta.rbuf; tl_release(mdev->tconn, p->barrier, be32_to_cpu(p->set_size)); @@ -4670,7 +4663,7 @@ static int got_BarrierAck(struct drbd_conf *mdev, enum drbd_packet cmd) static int got_OVResult(struct drbd_conf *mdev, enum drbd_packet cmd) { - struct p_block_ack *p = &mdev->tconn->meta.rbuf.block_ack; + struct p_block_ack *p = mdev->tconn->meta.rbuf; struct drbd_work *w; sector_t sector; int size; @@ -4776,7 +4769,7 @@ static struct asender_cmd asender_tbl[] = { int drbd_asender(struct drbd_thread *thi) { struct drbd_tconn *tconn = thi->tconn; - struct p_header *h = &tconn->meta.rbuf.header; + struct p_header *h = tconn->meta.rbuf; struct asender_cmd *cmd = NULL; struct packet_info pi; int rv; -- 2.7.4