From patchwork Wed Jun 5 10:34:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eliezer Tamir X-Patchwork-Id: 248996 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 03FCD2C030C for ; Wed, 5 Jun 2013 20:36:55 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754370Ab3FEKe7 (ORCPT ); Wed, 5 Jun 2013 06:34:59 -0400 Received: from mga11.intel.com ([192.55.52.93]:63851 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754327Ab3FEKe5 (ORCPT ); Wed, 5 Jun 2013 06:34:57 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 05 Jun 2013 03:35:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.87,804,1363158000"; d="scan'208";a="348432313" Received: from ladj378.jer.intel.com ([10.12.232.220]) by fmsmga002.fm.intel.com with ESMTP; 05 Jun 2013 03:34:52 -0700 From: Eliezer Tamir Subject: [PATCH v9 net-next 5/7] net: simple poll/select low latency socket poll To: David Miller Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Jesse Brandeburg , Don Skidmore , e1000-devel@lists.sourceforge.net, Willem de Bruijn , Eric Dumazet , Ben Hutchings , Andi Kleen , HPA , Eilon Greenstien , Or Gerlitz , Amir Vadai , Eliezer Tamir Date: Wed, 05 Jun 2013 13:34:52 +0300 Message-ID: <20130605103452.11172.31453.stgit@ladj378.jer.intel.com> In-Reply-To: <20130605103400.11172.49099.stgit@ladj378.jer.intel.com> References: <20130605103400.11172.49099.stgit@ladj378.jer.intel.com> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org A very naive select/poll busy-poll support. Add busy-polling to sock_poll(). When poll/select have nothing to report, call the low-level sock_poll() again until we are out of time or we find something. Right now we poll every socket once, this is suboptimal but improves latency when the number of sockets polled is not large. Signed-off-by: Alexander Duyck Signed-off-by: Jesse Brandeburg Tested-by: Willem de Bruijn Signed-off-by: Eliezer Tamir --- fs/select.c | 7 +++++++ net/socket.c | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/select.c b/fs/select.c index 8c1c96c..f116bf0 100644 --- a/fs/select.c +++ b/fs/select.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -400,6 +401,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) poll_table *wait; int retval, i, timed_out = 0; unsigned long slack = 0; + cycles_t ll_time = ll_end_time(); rcu_read_lock(); retval = max_select_fd(n, fds); @@ -486,6 +488,8 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) break; } + if (can_poll_ll(ll_time)) + continue; /* * If this is the first loop and we have a timeout * given, then we convert to ktime_t and set the to @@ -750,6 +754,7 @@ static int do_poll(unsigned int nfds, struct poll_list *list, ktime_t expire, *to = NULL; int timed_out = 0, count = 0; unsigned long slack = 0; + cycles_t ll_time = ll_end_time(); /* Optimise the no-wait case */ if (end_time && !end_time->tv_sec && !end_time->tv_nsec) { @@ -795,6 +800,8 @@ static int do_poll(unsigned int nfds, struct poll_list *list, if (count || timed_out) break; + if (can_poll_ll(ll_time)) + continue; /* * If this is the first loop and we have a timeout * given, then we convert to ktime_t and set the to diff --git a/net/socket.c b/net/socket.c index 721f4e7..c34dad0 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1148,13 +1148,21 @@ EXPORT_SYMBOL(sock_create_lite); /* No kernel lock held - perfect */ static unsigned int sock_poll(struct file *file, poll_table *wait) { + unsigned int poll_result; struct socket *sock; /* * We can't return errors to poll, so it's either yes or no. */ sock = file->private_data; - return sock->ops->poll(file, sock, wait); + + poll_result = sock->ops->poll(file, sock, wait); + + if (wait && !(poll_result & wait->_key) && + sk_valid_ll(sock->sk) && sk_poll_ll(sock->sk, 1)) + poll_result = sock->ops->poll(file, sock, NULL); + + return poll_result; } static int sock_mmap(struct file *file, struct vm_area_struct *vma)