Skip to content

Commit 62ed448

Browse files
committed
SUNRPC: Optimize xdr_reserve_space()
Transitioning between encode buffers is quite infrequent. It happens about 1 time in 400 calls to xdr_reserve_space(), measured on NFSD with a typical build/test workload. Force the compiler to remove that code from xdr_reserve_space(), which is a hot path on both the server and the client. This change reduces the size of xdr_reserve_space() from 10 cache lines to 2 when compiled with -Os. Signed-off-by: Chuck Lever <[email protected]> Reviewed-by: J. Bruce Fields <[email protected]>
1 parent 6c254bf commit 62ed448

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

include/linux/sunrpc/xdr.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf,
243243
extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
244244
extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec,
245245
size_t nbytes);
246-
extern void xdr_commit_encode(struct xdr_stream *xdr);
246+
extern void __xdr_commit_encode(struct xdr_stream *xdr);
247247
extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len);
248248
extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen);
249249
extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
@@ -306,6 +306,20 @@ xdr_reset_scratch_buffer(struct xdr_stream *xdr)
306306
xdr_set_scratch_buffer(xdr, NULL, 0);
307307
}
308308

309+
/**
310+
* xdr_commit_encode - Ensure all data is written to xdr->buf
311+
* @xdr: pointer to xdr_stream
312+
*
313+
* Handle encoding across page boundaries by giving the caller a
314+
* temporary location to write to, then later copying the data into
315+
* place. __xdr_commit_encode() does that copying.
316+
*/
317+
static inline void xdr_commit_encode(struct xdr_stream *xdr)
318+
{
319+
if (unlikely(xdr->scratch.iov_len))
320+
__xdr_commit_encode(xdr);
321+
}
322+
309323
/**
310324
* xdr_stream_remaining - Return the number of bytes remaining in the stream
311325
* @xdr: pointer to struct xdr_stream

net/sunrpc/xdr.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
919919
EXPORT_SYMBOL_GPL(xdr_init_encode);
920920

921921
/**
922-
* xdr_commit_encode - Ensure all data is written to buffer
922+
* __xdr_commit_encode - Ensure all data is written to buffer
923923
* @xdr: pointer to xdr_stream
924924
*
925925
* We handle encoding across page boundaries by giving the caller a
@@ -931,22 +931,25 @@ EXPORT_SYMBOL_GPL(xdr_init_encode);
931931
* required at the end of encoding, or any other time when the xdr_buf
932932
* data might be read.
933933
*/
934-
inline void xdr_commit_encode(struct xdr_stream *xdr)
934+
void __xdr_commit_encode(struct xdr_stream *xdr)
935935
{
936936
int shift = xdr->scratch.iov_len;
937937
void *page;
938938

939-
if (shift == 0)
940-
return;
941939
page = page_address(*xdr->page_ptr);
942940
memcpy(xdr->scratch.iov_base, page, shift);
943941
memmove(page, page + shift, (void *)xdr->p - page);
944942
xdr_reset_scratch_buffer(xdr);
945943
}
946-
EXPORT_SYMBOL_GPL(xdr_commit_encode);
944+
EXPORT_SYMBOL_GPL(__xdr_commit_encode);
947945

948-
static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
949-
size_t nbytes)
946+
/*
947+
* The buffer space to be reserved crosses the boundary between
948+
* xdr->buf->head and xdr->buf->pages, or between two pages
949+
* in xdr->buf->pages.
950+
*/
951+
static noinline __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
952+
size_t nbytes)
950953
{
951954
__be32 *p;
952955
int space_left;

0 commit comments

Comments
 (0)