From: Alex Elder <elder@inktank.com>
To: Josh Durgin <josh.durgin@inktank.com>
Cc: ceph-devel@vger.kernel.org
Subject: Re: [PATCH 5/8] libceph: define and use in_msg_pos_next()
Date: Mon, 11 Mar 2013 14:16:44 -0500 [thread overview]
Message-ID: <513E2D9C.2030104@inktank.com> (raw)
In-Reply-To: <513E28FC.8060608@inktank.com>
On 03/11/2013 01:57 PM, Josh Durgin wrote:
> On 03/09/2013 07:14 AM, Alex Elder wrote:
>> Define a new function in_msg_pos_next() to match out_msg_pos_next(),
>> and use it in place of code at the end of read_partial_message_pages()
>> and read_partial_message_bio().
>>
>> Signed-off-by: Alex Elder <elder@inktank.com>
>> ---
>> net/ceph/messenger.c | 57
>> ++++++++++++++++++++++++++++++++------------------
>> 1 file changed, 37 insertions(+), 20 deletions(-)
>>
>> diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
>> index 2017b88..fb5f6e7 100644
>> --- a/net/ceph/messenger.c
>> +++ b/net/ceph/messenger.c
>> @@ -1052,6 +1052,28 @@ static void out_msg_pos_next(struct
>> ceph_connection *con, struct page *page,
>> #endif
>> }
>>
>> +static void in_msg_pos_next(struct ceph_connection *con, size_t len,
>> + size_t received)
>> +{
>> + struct ceph_msg *msg = con->in_msg;
>> +
>> + BUG_ON(!msg);
>> + BUG_ON(!received);
>> +
>> + con->in_msg_pos.data_pos += received;
>> + con->in_msg_pos.page_pos += received;
>> + if (received < len)
>> + return;
>
> This is different from the condition in read_partial_message_pages()
> case, which only increments in_msg_pos.page and resets page_pos when
> page_pos == PAGE_SIZE. Maybe this is equivalent, but if so it's not
> obvious.
You are correct. And, despite my usual thoroughness and
verbosity, I didn't explain this one.
This message position structure (in_msg_pos) is tracking
how much of the message has been consumed. Each time a
an incoming message is going to arrive, we find out how
much room is left--not surpassing the current page--and
provide that as the "len" (number of bytes) to receive:
left = min((int)(data_len - con->in_msg_pos.data_pos),
(int)(bv->bv_len - con->in_msg_pos.page_pos));
This is saying the amount we'll use is the lesser of:
- all that's left of the entire request
- all that's left in the current page
The number of bytes received is then used, along with
the "len" value, to determine how to advance the position.
If we received exactly how many were requested, we either
reached the end of the request or the end of the page.
In the first case, we're done, in the second, we move
onto the next page in the array.
In all cases but (possibly) on the last page, after adding
the number of bytes received, page_pos == PAGE_SIZE. On the
last page, it doesn't really matter whether we increment
the page number and reset the page position, because we're
done and we won't come back here again. The code previously
skipped over that last case, basically. The new code
handles that case the same as the others, incrementing
and resetting.
So the short answer is, they are still equivalent. And
I agree, it is not obvious.
If you are satisfied, I can add the above (or maybe an
abbreviated form of it) to the commit message.
-Alex
>> +
>> + BUG_ON(received != len);
>> + con->in_msg_pos.page_pos = 0;
>> + con->in_msg_pos.page++;
>> +#ifdef CONFIG_BLOCK
>> + if (msg->bio)
>> + iter_bio_next(&msg->bio_iter, &msg->bio_seg);
>> +#endif /* CONFIG_BLOCK */
>> +}
>> +
>> /*
>> * Write as much message data payload as we can. If we finish, queue
>> * up the footer.
>> @@ -1789,6 +1811,7 @@ static int read_partial_message_pages(struct
>> ceph_connection *con,
>> struct page **pages,
>> unsigned int data_len, bool do_datacrc)
>> {
>> + struct page *page;
>> void *p;
>> int ret;
>> int left;
>> @@ -1797,22 +1820,18 @@ static int read_partial_message_pages(struct
>> ceph_connection *con,
>> (int)(PAGE_SIZE - con->in_msg_pos.page_pos));
>> /* (page) data */
>> BUG_ON(pages == NULL);
>> - p = kmap(pages[con->in_msg_pos.page]);
>> - ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
>> - left);
>> + page = pages[con->in_msg_pos.page];
>> + p = kmap(page);
>> + ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
>> left);
>> if (ret > 0 && do_datacrc)
>> con->in_data_crc =
>> crc32c(con->in_data_crc,
>> p + con->in_msg_pos.page_pos, ret);
>> - kunmap(pages[con->in_msg_pos.page]);
>> + kunmap(page);
>> if (ret <= 0)
>> return ret;
>> - con->in_msg_pos.data_pos += ret;
>> - con->in_msg_pos.page_pos += ret;
>> - if (con->in_msg_pos.page_pos == PAGE_SIZE) {
>> - con->in_msg_pos.page_pos = 0;
>> - con->in_msg_pos.page++;
>> - }
>> +
>> + in_msg_pos_next(con, left, ret);
>>
>> return ret;
>> }
>> @@ -1823,32 +1842,30 @@ static int read_partial_message_bio(struct
>> ceph_connection *con,
>> {
>> struct ceph_msg *msg = con->in_msg;
>> struct bio_vec *bv;
>> + struct page *page;
>> void *p;
>> int ret, left;
>>
>> BUG_ON(!msg);
>> BUG_ON(!msg->bio_iter);
>> bv = bio_iovec_idx(msg->bio_iter, msg->bio_seg);
>> +
>> left = min((int)(data_len - con->in_msg_pos.data_pos),
>> (int)(bv->bv_len - con->in_msg_pos.page_pos));
>>
>> - p = kmap(bv->bv_page) + bv->bv_offset;
>> + page = bv->bv_page;
>> + p = kmap(page) + bv->bv_offset;
>>
>> - ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
>> - left);
>> + ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos,
>> left);
>> if (ret > 0 && do_datacrc)
>> con->in_data_crc =
>> crc32c(con->in_data_crc,
>> p + con->in_msg_pos.page_pos, ret);
>> - kunmap(bv->bv_page);
>> + kunmap(page);
>> if (ret <= 0)
>> return ret;
>> - con->in_msg_pos.data_pos += ret;
>> - con->in_msg_pos.page_pos += ret;
>> - if (con->in_msg_pos.page_pos == bv->bv_len) {
>> - con->in_msg_pos.page_pos = 0;
>> - iter_bio_next(&msg->bio_iter, &msg->bio_seg);
>> - }
>> +
>> + in_msg_pos_next(con, left, ret);
>>
>> return ret;
>> }
>>
>
next prev parent reply other threads:[~2013-03-11 19:16 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-09 15:11 [PATCH 0/8] libceph: miscellaneous cleanups Alex Elder
2013-03-09 15:13 ` [PATCH 1/8] libceph: define CEPH_MSG_MAX_MIDDLE_LEN Alex Elder
2013-03-09 15:13 ` [PATCH 2/8] libceph: minor byte order problems in Alex Elder
2013-03-09 15:14 ` [PATCH 3/8] libceph: change type of ceph_tcp_sendpage() "more" Alex Elder
2013-03-09 15:14 ` [PATCH 4/8] libceph: kill args in read_partial_message_bio() Alex Elder
2013-03-09 15:14 ` [PATCH 5/8] libceph: define and use in_msg_pos_next() Alex Elder
2013-03-11 18:57 ` Josh Durgin
2013-03-11 19:16 ` Alex Elder [this message]
2013-03-11 19:28 ` Josh Durgin
2013-03-09 15:15 ` [PATCH 6/8] libceph: advance pagelist with list_rotate_left() Alex Elder
2013-03-09 15:15 ` [PATCH 7/8] libceph: simplify new message initialization Alex Elder
2013-03-09 15:15 ` [PATCH 8/8] libceph: record byte count not page count Alex Elder
2013-03-09 15:21 ` [PATCH 0/8] libceph: miscellaneous cleanups Alex Elder
2013-03-11 18:57 ` Josh Durgin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=513E2D9C.2030104@inktank.com \
--to=elder@inktank.com \
--cc=ceph-devel@vger.kernel.org \
--cc=josh.durgin@inktank.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.