[SCM] Samba Shared Repository - branch v3-6-test updated

Karolin Seeger kseeger at samba.org
Tue Nov 6 03:18:35 MST 2012


The branch, v3-6-test has been updated
       via  0e607ea s3-aio_pthread: Optimize aio_pthread_handle_completion
       via  7f83d75 lib/tsocket: optimize syscalls in tstream_readv_pdu_send()
       via  53aa972 lib/tsocket: disable the syscall optimization for recvfrom/readv by default
      from  a6dea8e docs-xml: fix use of <smbconfoption> tag (fix bug #9345)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test


- Log -----------------------------------------------------------------
commit 0e607ead8e605f0ee7f2153f98b6c171e6acc437
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Nov 5 15:53:31 2012 +0100

    s3-aio_pthread: Optimize aio_pthread_handle_completion
    
    Read as much as we can
    
    The last 3 patches address bug #9359 - Optimization needed for SMB2 performance
    sensitive workloads.

commit 7f83d75a3a666ca1bc6213433344b8017eb4932a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 2 13:56:53 2012 +0100

    lib/tsocket: optimize syscalls in tstream_readv_pdu_send()
    
    Once we've got the first part of a pdu we try to optimize
    readv calls for the rest of the pdu.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 53aa9727b8157ca1ad6c59ef9ebbb9f519b33f1e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 2 13:45:49 2012 +0100

    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 <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/tsocket/tsocket.h             |   42 +++++++++++++++++++++
 lib/tsocket/tsocket_bsd.c         |   73 ++++++++++++++++++++++++++++++++++---
 lib/tsocket/tsocket_helpers.c     |   29 +++++++++++++++
 source3/modules/vfs_aio_pthread.c |   58 +++++++++++++++++++++---------
 4 files changed, 179 insertions(+), 23 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h
index 3aca536..98f864e 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.
@@ -689,6 +710,27 @@ int _tdgram_unix_socket(const struct tsocket_address *local,
 #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 9e80065..58598d1 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,
@@ -837,14 +857,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,
@@ -1400,6 +1431,7 @@ struct tstream_bsd {
 
 	void *event_ptr;
 	struct tevent_fd *fde;
+	bool optimize_readv;
 
 	void *readable_private;
 	void (*readable_handler)(void *private_data);
@@ -1407,6 +1439,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,
@@ -1619,9 +1670,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,
diff --git a/lib/tsocket/tsocket_helpers.c b/lib/tsocket/tsocket_helpers.c
index 3a41a3e..809830d 100644
--- a/lib/tsocket/tsocket_helpers.c
+++ b/lib/tsocket/tsocket_helpers.c
@@ -212,6 +212,20 @@ static void tstream_readv_pdu_ask_for_next_vector(struct tevent_req *req)
 	size_t to_read = 0;
 	size_t i;
 	struct tevent_req *subreq;
+	bool optimize = false;
+	bool save_optimize = false;
+
+	if (state->count > 0) {
+		/*
+		 * This is not the first time we asked for a vector,
+		 * which means parts of the pdu already arrived.
+		 *
+		 * In this case it make sense to enable
+		 * a syscall/performance optimization if the
+		 * low level tstream implementation supports it.
+		 */
+		optimize = true;
+	}
 
 	TALLOC_FREE(state->vector);
 	state->count = 0;
@@ -255,11 +269,26 @@ static void tstream_readv_pdu_ask_for_next_vector(struct tevent_req *req)
 		return;
 	}
 
+	if (optimize) {
+		/*
+		 * If the low level stream is a bsd socket
+		 * we will get syscall optimization.
+		 *
+		 * If it is not a bsd socket
+		 * tstream_bsd_optimize_readv() just returns.
+		 */
+		save_optimize = tstream_bsd_optimize_readv(state->caller.stream,
+							   true);
+	}
 	subreq = tstream_readv_send(state,
 				    state->caller.ev,
 				    state->caller.stream,
 				    state->vector,
 				    state->count);
+	if (optimize) {
+		tstream_bsd_optimize_readv(state->caller.stream,
+					   save_optimize);
+	}
 	if (tevent_req_nomem(subreq, req)) {
 		return;
 	}
diff --git a/source3/modules/vfs_aio_pthread.c b/source3/modules/vfs_aio_pthread.c
index ceef822..6627811 100644
--- a/source3/modules/vfs_aio_pthread.c
+++ b/source3/modules/vfs_aio_pthread.c
@@ -74,6 +74,7 @@ static bool init_aio_threadpool(struct vfs_handle_struct *handle)
 	struct fd_event *sock_event = NULL;
 	int ret = 0;
 	int num_threads;
+	int fd;
 
 	if (pool) {
 		return true;
@@ -85,9 +86,14 @@ static bool init_aio_threadpool(struct vfs_handle_struct *handle)
 		errno = ret;
 		return false;
 	}
+
+	fd = pthreadpool_signal_fd(pool);
+
+	set_blocking(fd, false);
+
 	sock_event = tevent_add_fd(server_event_context(),
 				NULL,
-				pthreadpool_signal_fd(pool),
+				fd,
 				TEVENT_FD_READ,
 				aio_pthread_handle_completion,
 				NULL);
@@ -290,25 +296,43 @@ static void aio_pthread_handle_completion(struct event_context *event_ctx,
 		return;
 	}
 
-	ret = pthreadpool_finished_job(pool, &jobid);
-	if (ret) {
-		smb_panic("aio_pthread_handle_completion");
-		return;
-	}
+	while (true) {
+		ret = pthreadpool_finished_job(pool, &jobid);
 
-	pd = find_private_data_by_jobid(jobid);
-	if (pd == NULL) {
-		DEBUG(1, ("aio_pthread_handle_completion cannot find jobid %d\n",
-			  jobid));
-		return;
-	}
+		if (ret == EINTR || ret == EAGAIN) {
+			return;
+		}
+#ifdef EWOULDBLOCK
+		if (ret == EWOULDBLOCK) {
+			return;
+		}
+#endif
 
-	aio_ex = (struct aio_extra *)pd->aiocb->aio_sigevent.sigev_value.sival_ptr;
-	smbd_aio_complete_aio_ex(aio_ex);
+		if (ret == ECANCELED) {
+			return;
+		}
 
-	DEBUG(10,("aio_pthread_handle_completion: jobid %d completed\n",
-		jobid ));
-	TALLOC_FREE(aio_ex);
+		if (ret) {
+			smb_panic("aio_pthread_handle_completion");
+			return;
+		}
+
+		pd = find_private_data_by_jobid(jobid);
+		if (pd == NULL) {
+			DEBUG(1, ("aio_pthread_handle_completion cannot find "
+				  "jobid %d\n", jobid));
+			return;
+		}
+
+		aio_ex = (struct aio_extra *)
+			pd->aiocb->aio_sigevent.sigev_value.sival_ptr;
+
+		smbd_aio_complete_aio_ex(aio_ex);
+
+		DEBUG(10,("aio_pthread_handle_completion: jobid %d "
+			  "completed\n", jobid ));
+		TALLOC_FREE(aio_ex);
+	}
 }
 
 /************************************************************************


-- 
Samba Shared Repository


More information about the samba-cvs mailing list