From e42889f83f261e2ac34014649476fae638a6e1f2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Nov 2012 13:45:49 +0100 Subject: lib/tsocket: disable the syscall optimization for recvfrom/readv by default We only do the optimization on recvfrom/readv if the caller asked for it. This is needed because in most cases we preferr to flush send buffers before receiving incoming requests. Signed-off-by: Stefan Metzmacher --- lib/tsocket/tsocket.h | 42 +++++++++++++++++++++++++++ lib/tsocket/tsocket_bsd.c | 73 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 109 insertions(+), 6 deletions(-) diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h index 3aca536124..98f864e6a5 100644 --- a/lib/tsocket/tsocket.h +++ b/lib/tsocket/tsocket.h @@ -627,6 +627,27 @@ int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx, char *tsocket_address_unix_path(const struct tsocket_address *addr, TALLOC_CTX *mem_ctx); +/** + * @brief Request a syscall optimization for tdgram_recvfrom_send() + * + * This function is only used to reduce the amount of syscalls and + * optimize performance. You should only use this if you know + * what you're doing. + * + * The optimization is off by default. + * + * @param[in] dgram The tdgram_context of a bsd socket, if this + * not a bsd socket the function does nothing. + * + * @param[in] on The boolean value to turn the optimization on and off. + * + * @return The old boolean value. + * + * @see tdgram_recvfrom_send() + */ +bool tdgram_bsd_optimize_recvfrom(struct tdgram_context *dgram, + bool on); + #ifdef DOXYGEN /** * @brief Create a tdgram_context for a ipv4 or ipv6 UDP communication. @@ -688,6 +709,27 @@ int _tdgram_unix_socket(const struct tsocket_address *local, _tdgram_unix_socket(local, remote, mem_ctx, dgram, __location__) #endif +/** + * @brief Request a syscall optimization for tstream_readv_send() + * + * This function is only used to reduce the amount of syscalls and + * optimize performance. You should only use this if you know + * what you're doing. + * + * The optimization is off by default. + * + * @param[in] stream The tstream_context of a bsd socket, if this + * not a bsd socket the function does nothing. + * + * @param[in] on The boolean value to turn the optimization on and off. + * + * @return The old boolean value. + * + * @see tstream_readv_send() + */ +bool tstream_bsd_optimize_readv(struct tstream_context *stream, + bool on); + /** * @brief Connect async to a TCP endpoint and create a tstream_context for the * stream based communication. diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c index 135fd027aa..56dff68dd2 100644 --- a/lib/tsocket/tsocket_bsd.c +++ b/lib/tsocket/tsocket_bsd.c @@ -654,6 +654,7 @@ struct tdgram_bsd { void *event_ptr; struct tevent_fd *fde; + bool optimize_recvfrom; void *readable_private; void (*readable_handler)(void *private_data); @@ -661,6 +662,25 @@ struct tdgram_bsd { void (*writeable_handler)(void *private_data); }; +bool tdgram_bsd_optimize_recvfrom(struct tdgram_context *dgram, + bool on) +{ + struct tdgram_bsd *bsds = + talloc_get_type(_tdgram_context_data(dgram), + struct tdgram_bsd); + bool old; + + if (bsds == NULL) { + /* not a bsd socket */ + return false; + } + + old = bsds->optimize_recvfrom; + bsds->optimize_recvfrom = on; + + return old; +} + static void tdgram_bsd_fde_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, @@ -838,14 +858,25 @@ static struct tevent_req *tdgram_bsd_recvfrom_send(TALLOC_CTX *mem_ctx, goto post; } + /* * this is a fast path, not waiting for the * socket to become explicit readable gains * about 10%-20% performance in benchmark tests. */ - tdgram_bsd_recvfrom_handler(req); - if (!tevent_req_is_in_progress(req)) { - goto post; + if (bsds->optimize_recvfrom) { + /* + * We only do the optimization on + * recvfrom if the caller asked for it. + * + * This is needed because in most cases + * we preferr to flush send buffers before + * receiving incoming requests. + */ + tdgram_bsd_recvfrom_handler(req); + if (!tevent_req_is_in_progress(req)) { + goto post; + } } ret = tdgram_bsd_set_readable_handler(bsds, ev, @@ -1405,6 +1436,7 @@ struct tstream_bsd { void *event_ptr; struct tevent_fd *fde; + bool optimize_readv; void *readable_private; void (*readable_handler)(void *private_data); @@ -1412,6 +1444,25 @@ struct tstream_bsd { void (*writeable_handler)(void *private_data); }; +bool tstream_bsd_optimize_readv(struct tstream_context *stream, + bool on) +{ + struct tstream_bsd *bsds = + talloc_get_type(_tstream_context_data(stream), + struct tstream_bsd); + bool old; + + if (bsds == NULL) { + /* not a bsd socket */ + return false; + } + + old = bsds->optimize_readv; + bsds->optimize_readv = on; + + return old; +} + static void tstream_bsd_fde_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, @@ -1624,9 +1675,19 @@ static struct tevent_req *tstream_bsd_readv_send(TALLOC_CTX *mem_ctx, * socket to become explicit readable gains * about 10%-20% performance in benchmark tests. */ - tstream_bsd_readv_handler(req); - if (!tevent_req_is_in_progress(req)) { - goto post; + if (bsds->optimize_readv) { + /* + * We only do the optimization on + * readv if the caller asked for it. + * + * This is needed because in most cases + * we preferr to flush send buffers before + * receiving incoming requests. + */ + tstream_bsd_readv_handler(req); + if (!tevent_req_is_in_progress(req)) { + goto post; + } } ret = tstream_bsd_set_readable_handler(bsds, ev, -- cgit