* [PATCH 1/6] libceph: encapsulate out message data setup
2012-06-18 15:29 [PATCH 0/6] ceph: a few more messenger cleanups Alex Elder
@ 2012-06-18 15:33 ` Alex Elder
2012-06-18 15:33 ` [PATCH 2/6] libceph: encapsulate advancing msg page Alex Elder
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alex Elder @ 2012-06-18 15:33 UTC (permalink / raw)
To: ceph-devel
Move the code that prepares to write the data portion of a message
into its own function.
Signed-off-by: Alex Elder <elder@inktank.com>
---
net/ceph/messenger.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
Index: b/net/ceph/messenger.c
===================================================================
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -590,6 +590,23 @@ static void con_out_kvec_add(struct ceph
con->out_kvec_bytes += size;
}
+static void prepare_write_message_data(struct ceph_connection *con)
+{
+ struct ceph_msg *msg = con->out_msg;
+
+ BUG_ON(!msg);
+ BUG_ON(!msg->hdr.data_len);
+
+ /* initialize page iterator */
+ if (msg->pages)
+ con->out_msg_pos.page_pos = msg->page_alignment;
+ else
+ con->out_msg_pos.page_pos = 0;
+ con->out_msg_pos.data_pos = 0;
+ con->out_msg_pos.did_page_crc = false;
+ con->out_more = 1; /* data + footer will follow */
+}
+
/*
* Prepare footer for currently outgoing message, and finish things
* off. Assumes out_kvec* are already valid.. we just add on to the end.
@@ -682,26 +699,17 @@ static void prepare_write_message(struct
con->out_msg->footer.middle_crc = cpu_to_le32(crc);
} else
con->out_msg->footer.middle_crc = 0;
- con->out_msg->footer.data_crc = 0;
- dout("prepare_write_message front_crc %u data_crc %u\n",
+ dout("%s front_crc %u middle_crc %u\n", __func__,
le32_to_cpu(con->out_msg->footer.front_crc),
le32_to_cpu(con->out_msg->footer.middle_crc));
/* is there a data payload? */
- if (le32_to_cpu(m->hdr.data_len) > 0) {
- /* initialize page iterator */
- con->out_msg_pos.page = 0;
- if (m->pages)
- con->out_msg_pos.page_pos = m->page_alignment;
- else
- con->out_msg_pos.page_pos = 0;
- con->out_msg_pos.data_pos = 0;
- con->out_msg_pos.did_page_crc = false;
- con->out_more = 1; /* data + footer will follow */
- } else {
+ con->out_msg->footer.data_crc = 0;
+ if (m->hdr.data_len)
+ prepare_write_message_data(con);
+ else
/* no, queue up footer too and be done */
prepare_write_message_footer(con);
- }
set_bit(WRITE_PENDING, &con->flags);
}
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 2/6] libceph: encapsulate advancing msg page
2012-06-18 15:29 [PATCH 0/6] ceph: a few more messenger cleanups Alex Elder
2012-06-18 15:33 ` [PATCH 1/6] libceph: encapsulate out message data setup Alex Elder
@ 2012-06-18 15:33 ` Alex Elder
2012-06-18 15:33 ` [PATCH 3/6] libceph: don't mark footer complete before it is Alex Elder
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alex Elder @ 2012-06-18 15:33 UTC (permalink / raw)
To: ceph-devel
In write_partial_msg_pages(), once all the data from a page has been
sent we advance to the next one. Put the code that takes care of
this into its own function.
While modifying write_partial_msg_pages(), make its local variable
"in_trail" be Boolean, and use the local variable "msg" (which is
just the connection's current out_msg pointer) consistently.
Signed-off-by: Alex Elder <elder@inktank.com>
---
net/ceph/messenger.c | 58
+++++++++++++++++++++++++++++----------------------
1 file changed, 34 insertions(+), 24 deletions(-)
Index: b/net/ceph/messenger.c
===================================================================
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -915,6 +915,33 @@ static void iter_bio_next(struct bio **b
}
#endif
+static void out_msg_pos_next(struct ceph_connection *con, struct page
*page,
+ size_t len, size_t sent, bool in_trail)
+{
+ struct ceph_msg *msg = con->out_msg;
+
+ BUG_ON(!msg);
+ BUG_ON(!sent);
+
+ con->out_msg_pos.data_pos += sent;
+ con->out_msg_pos.page_pos += sent;
+ if (sent == len) {
+ con->out_msg_pos.page_pos = 0;
+ con->out_msg_pos.page++;
+ con->out_msg_pos.did_page_crc = false;
+ if (in_trail)
+ list_move_tail(&page->lru,
+ &msg->trail->head);
+ else if (msg->pagelist)
+ list_move_tail(&page->lru,
+ &msg->pagelist->head);
+#ifdef CONFIG_BLOCK
+ else if (msg->bio)
+ iter_bio_next(&msg->bio_iter, &msg->bio_seg);
+#endif
+ }
+}
+
/*
* Write as much message data payload as we can. If we finish, queue
* up the footer.
@@ -930,11 +957,11 @@ static int write_partial_msg_pages(struc
bool do_datacrc = !con->msgr->nocrc;
int ret;
int total_max_write;
- int in_trail = 0;
+ bool in_trail = false;
size_t trail_len = (msg->trail ? msg->trail->length : 0);
dout("write_partial_msg_pages %p msg %p page %d/%d offset %d\n",
- con, con->out_msg, con->out_msg_pos.page, con->out_msg->nr_pages,
+ con, msg, con->out_msg_pos.page, msg->nr_pages,
con->out_msg_pos.page_pos);
#ifdef CONFIG_BLOCK
@@ -958,13 +985,12 @@ static int write_partial_msg_pages(struc
/* have we reached the trail part of the data? */
if (con->out_msg_pos.data_pos >= data_len - trail_len) {
- in_trail = 1;
+ in_trail = true;
total_max_write = data_len - con->out_msg_pos.data_pos;
page = list_first_entry(&msg->trail->head,
struct page, lru);
- max_write = PAGE_SIZE;
} else if (msg->pages) {
page = msg->pages[con->out_msg_pos.page];
} else if (msg->pagelist) {
@@ -988,14 +1014,14 @@ static int write_partial_msg_pages(struc
if (do_datacrc && !con->out_msg_pos.did_page_crc) {
void *base;
u32 crc;
- u32 tmpcrc = le32_to_cpu(con->out_msg->footer.data_crc);
+ u32 tmpcrc = le32_to_cpu(msg->footer.data_crc);
char *kaddr;
kaddr = kmap(page);
BUG_ON(kaddr == NULL);
base = kaddr + con->out_msg_pos.page_pos + bio_offset;
crc = crc32c(tmpcrc, base, len);
- con->out_msg->footer.data_crc = cpu_to_le32(crc);
+ msg->footer.data_crc = cpu_to_le32(crc);
con->out_msg_pos.did_page_crc = true;
}
ret = ceph_tcp_sendpage(con->sock, page,
@@ -1008,30 +1034,14 @@ static int write_partial_msg_pages(struc
if (ret <= 0)
goto out;
- con->out_msg_pos.data_pos += ret;
- con->out_msg_pos.page_pos += ret;
- if (ret == len) {
- con->out_msg_pos.page_pos = 0;
- con->out_msg_pos.page++;
- con->out_msg_pos.did_page_crc = false;
- if (in_trail)
- list_move_tail(&page->lru,
- &msg->trail->head);
- else if (msg->pagelist)
- list_move_tail(&page->lru,
- &msg->pagelist->head);
-#ifdef CONFIG_BLOCK
- else if (msg->bio)
- iter_bio_next(&msg->bio_iter, &msg->bio_seg);
-#endif
- }
+ out_msg_pos_next(con, page, len, (size_t) ret, in_trail);
}
dout("write_partial_msg_pages %p msg %p done\n", con, msg);
/* prepare and queue up footer, too */
if (!do_datacrc)
- con->out_msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC;
+ msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC;
con_out_kvec_reset(con);
prepare_write_message_footer(con);
ret = 1;
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 3/6] libceph: don't mark footer complete before it is
2012-06-18 15:29 [PATCH 0/6] ceph: a few more messenger cleanups Alex Elder
2012-06-18 15:33 ` [PATCH 1/6] libceph: encapsulate out message data setup Alex Elder
2012-06-18 15:33 ` [PATCH 2/6] libceph: encapsulate advancing msg page Alex Elder
@ 2012-06-18 15:33 ` Alex Elder
2012-06-18 15:33 ` [PATCH 4/6] libceph: move init_bio_*() functions up Alex Elder
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alex Elder @ 2012-06-18 15:33 UTC (permalink / raw)
To: ceph-devel
This is a nit, but prepare_write_message() sets the FOOTER_COMPLETE
flag before the CRC for the data portion (recorded in the footer)
has been completely computed. Hold off setting the complete flag
until we've decided it's ready to send.
Signed-off-by: Alex Elder <elder@inktank.com>
---
net/ceph/messenger.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Index: b/net/ceph/messenger.c
===================================================================
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -616,6 +616,8 @@ static void prepare_write_message_footer
struct ceph_msg *m = con->out_msg;
int v = con->out_kvec_left;
+ m->footer.flags |= CEPH_MSG_FOOTER_COMPLETE;
+
dout("prepare_write_message_footer %p\n", con);
con->out_kvec_is_msg = true;
con->out_kvec[v].iov_base = &m->footer;
@@ -689,7 +691,7 @@ static void prepare_write_message(struct
/* fill in crc (except data pages), footer */
crc = crc32c(0, &m->hdr, offsetof(struct ceph_msg_header, crc));
con->out_msg->hdr.crc = cpu_to_le32(crc);
- con->out_msg->footer.flags = CEPH_MSG_FOOTER_COMPLETE;
+ con->out_msg->footer.flags = 0;
crc = crc32c(0, m->front.iov_base, m->front.iov_len);
con->out_msg->footer.front_crc = cpu_to_le32(crc);
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 4/6] libceph: move init_bio_*() functions up
2012-06-18 15:29 [PATCH 0/6] ceph: a few more messenger cleanups Alex Elder
` (2 preceding siblings ...)
2012-06-18 15:33 ` [PATCH 3/6] libceph: don't mark footer complete before it is Alex Elder
@ 2012-06-18 15:33 ` Alex Elder
2012-06-18 15:33 ` [PATCH 5/6] libceph: move init of bio_iter Alex Elder
2012-06-18 15:33 ` [PATCH 6/6] libceph: don't use bio_iter as a flag Alex Elder
5 siblings, 0 replies; 7+ messages in thread
From: Alex Elder @ 2012-06-18 15:33 UTC (permalink / raw)
To: ceph-devel
Move init_bio_iter() and iter_bio_next() up in their source file so
the'll be defined before they're needed.
Signed-off-by: Alex Elder <elder@inktank.com>
---
net/ceph/messenger.c | 50
+++++++++++++++++++++++++-------------------------
1 file changed, 25 insertions(+), 25 deletions(-)
Index: b/net/ceph/messenger.c
===================================================================
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -590,6 +590,31 @@ static void con_out_kvec_add(struct ceph
con->out_kvec_bytes += size;
}
+#ifdef CONFIG_BLOCK
+static void init_bio_iter(struct bio *bio, struct bio **iter, int *seg)
+{
+ if (!bio) {
+ *iter = NULL;
+ *seg = 0;
+ return;
+ }
+ *iter = bio;
+ *seg = bio->bi_idx;
+}
+
+static void iter_bio_next(struct bio **bio_iter, int *seg)
+{
+ if (*bio_iter == NULL)
+ return;
+
+ BUG_ON(*seg >= (*bio_iter)->bi_vcnt);
+
+ (*seg)++;
+ if (*seg == (*bio_iter)->bi_vcnt)
+ init_bio_iter((*bio_iter)->bi_next, bio_iter, seg);
+}
+#endif
+
static void prepare_write_message_data(struct ceph_connection *con)
{
struct ceph_msg *msg = con->out_msg;
@@ -892,31 +917,6 @@ out:
return ret; /* done! */
}
-#ifdef CONFIG_BLOCK
-static void init_bio_iter(struct bio *bio, struct bio **iter, int *seg)
-{
- if (!bio) {
- *iter = NULL;
- *seg = 0;
- return;
- }
- *iter = bio;
- *seg = bio->bi_idx;
-}
-
-static void iter_bio_next(struct bio **bio_iter, int *seg)
-{
- if (*bio_iter == NULL)
- return;
-
- BUG_ON(*seg >= (*bio_iter)->bi_vcnt);
-
- (*seg)++;
- if (*seg == (*bio_iter)->bi_vcnt)
- init_bio_iter((*bio_iter)->bi_next, bio_iter, seg);
-}
-#endif
-
static void out_msg_pos_next(struct ceph_connection *con, struct page
*page,
size_t len, size_t sent, bool in_trail)
{
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 5/6] libceph: move init of bio_iter
2012-06-18 15:29 [PATCH 0/6] ceph: a few more messenger cleanups Alex Elder
` (3 preceding siblings ...)
2012-06-18 15:33 ` [PATCH 4/6] libceph: move init_bio_*() functions up Alex Elder
@ 2012-06-18 15:33 ` Alex Elder
2012-06-18 15:33 ` [PATCH 6/6] libceph: don't use bio_iter as a flag Alex Elder
5 siblings, 0 replies; 7+ messages in thread
From: Alex Elder @ 2012-06-18 15:33 UTC (permalink / raw)
To: ceph-devel
If a message has a non-null bio pointer, its bio_iter field is
initialized in write_partial_msg_pages() if this has not been done
already. This is really a one-time setup operation for sending a
message's (bio) data, so move that initialization code into
prepare_write_message_data() which serves that purpose.
Signed-off-by: Alex Elder <elder@inktank.com>
---
net/ceph/messenger.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
Index: b/net/ceph/messenger.c
===================================================================
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -627,6 +627,10 @@ static void prepare_write_message_data(s
con->out_msg_pos.page_pos = msg->page_alignment;
else
con->out_msg_pos.page_pos = 0;
+#ifdef CONFIG_BLOCK
+ if (msg->bio && !msg->bio_iter)
+ init_bio_iter(msg->bio, &msg->bio_iter, &msg->bio_seg);
+#endif
con->out_msg_pos.data_pos = 0;
con->out_msg_pos.did_page_crc = false;
con->out_more = 1; /* data + footer will follow */
@@ -966,11 +970,6 @@ static int write_partial_msg_pages(struc
con, msg, con->out_msg_pos.page, msg->nr_pages,
con->out_msg_pos.page_pos);
-#ifdef CONFIG_BLOCK
- if (msg->bio && !msg->bio_iter)
- init_bio_iter(msg->bio, &msg->bio_iter, &msg->bio_seg);
-#endif
-
while (data_len > con->out_msg_pos.data_pos) {
struct page *page = NULL;
int max_write = PAGE_SIZE;
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 6/6] libceph: don't use bio_iter as a flag
2012-06-18 15:29 [PATCH 0/6] ceph: a few more messenger cleanups Alex Elder
` (4 preceding siblings ...)
2012-06-18 15:33 ` [PATCH 5/6] libceph: move init of bio_iter Alex Elder
@ 2012-06-18 15:33 ` Alex Elder
5 siblings, 0 replies; 7+ messages in thread
From: Alex Elder @ 2012-06-18 15:33 UTC (permalink / raw)
To: ceph-devel
Recently a bug was fixed in which the bio_iter field in a ceph
message was not being properly re-initialized when a message got
re-transmitted:
commit 43643528cce60ca184fe8197efa8e8da7c89a037
Author: Yan, Zheng <zheng.z.yan@intel.com>
rbd: Clear ceph_msg->bio_iter for retransmitted message
We are now only initializing the bio_iter field when we are about to
start to write message data (in prepare_write_message_data()),
rather than every time we are attempting to write any portion of the
message data (in write_partial_msg_pages()). This means we no
longer need to use the msg->bio_iter field as a flag.
So just don't do that any more. Trust prepare_write_message_data()
to ensure msg->bio_iter is properly initialized, every time we are
about to begin writing (or re-writing) a message's bio data.
Signed-off-by: Alex Elder <elder@inktank.com>
---
net/ceph/messenger.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
Index: b/net/ceph/messenger.c
===================================================================
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -628,7 +628,7 @@ static void prepare_write_message_data(s
else
con->out_msg_pos.page_pos = 0;
#ifdef CONFIG_BLOCK
- if (msg->bio && !msg->bio_iter)
+ if (msg->bio)
init_bio_iter(msg->bio, &msg->bio_iter, &msg->bio_seg);
#endif
con->out_msg_pos.data_pos = 0;
@@ -696,10 +696,6 @@ static void prepare_write_message(struct
m->hdr.seq = cpu_to_le64(++con->out_seq);
m->needs_out_seq = false;
}
-#ifdef CONFIG_BLOCK
- else
- m->bio_iter = NULL;
-#endif
dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n",
m, con->out_seq, le16_to_cpu(m->hdr.type),
^ permalink raw reply [flat|nested] 7+ messages in thread