Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1655318

[PATCH 3.16 178/212] net: net_enable_timestamp() can be called from irq contexts

Path csiph.com!eternal-september.org!feeder.eternal-september.org!aioe.org!news.servidellagleba.it!bofh.it!news.nic.it!robomod
From Ben Hutchings <ben@decadent.org.uk>
Newsgroups linux.kernel
Subject [PATCH 3.16 178/212] net: net_enable_timestamp() can be called from irq contexts
Date Thu, 01 Jun 2017 18:00:05 +0200
Message-ID <tNAG1-4sr-87@gated-at.bofh.it> (permalink)
References <tNAwh-4oP-3@gated-at.bofh.it>
Content-Type text/plain; charset="UTF-8"
Content-Disposition inline
Content-Transfer-Encoding 8bit
MIME-Version 1.0
X-Mailer LinuxStableQueue (scripts by bwh)
X-Sa-Exim-Connect-IP 82.70.136.246
X-Sa-Exim-Mail-From ben@decadent.org.uk
X-Sa-Exim-Scanned No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false
Sender robomod@news.nic.it
List-ID <linux-kernel.vger.kernel.org>
X-Mailing-List linux-kernel@vger.kernel.org
Approved robomod@news.nic.it
Lines 94
Organization linux.* mail to news gateway
X-Original-Cc akpm@linux-foundation.org, "Eric Dumazet" <edumazet@google.com>, "David S. Miller" <davem@davemloft.net>, "Dmitry Vyukov" <dvyukov@google.com>
X-Original-Date Thu, 01 Jun 2017 16:43:16 +0100
X-Original-Message-ID <lsq.1496331796.223438850@decadent.org.uk>
X-Original-References <lsq.1496331794.574686034@decadent.org.uk>
X-Original-Sender linux-kernel-owner@vger.kernel.org
Xref csiph.com linux.kernel:1655318

Show key headers only | View raw


3.16.44-rc1 review patch.  If anyone has any objections, please let me know.

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

From: Eric Dumazet <edumazet@google.com>

commit 13baa00ad01bb3a9f893e3a08cbc2d072fc0c15d upstream.

It is now very clear that silly TCP listeners might play with
enabling/disabling timestamping while new children are added
to their accept queue.

Meaning net_enable_timestamp() can be called from BH context
while current state of the static key is not enabled.

Lets play safe and allow all contexts.

The work queue is scheduled only under the problematic cases,
which are the static key enable/disable transition, to not slow down
critical paths.

This extends and improves what we did in commit 5fa8bbda38c6 ("net: use
a work queue to defer net_disable_timestamp() work")

Fixes: b90e5794c5bd ("net: dont call jump_label_dec from irq context")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 net/core/dev.c | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1601,27 +1601,54 @@ EXPORT_SYMBOL(call_netdevice_notifiers);
 static struct static_key netstamp_needed __read_mostly;
 #ifdef HAVE_JUMP_LABEL
 static atomic_t netstamp_needed_deferred;
+static atomic_t netstamp_wanted;
 static void netstamp_clear(struct work_struct *work)
 {
 	int deferred = atomic_xchg(&netstamp_needed_deferred, 0);
+	int wanted;
 
-	while (deferred--)
-		static_key_slow_dec(&netstamp_needed);
+	wanted = atomic_add_return(deferred, &netstamp_wanted);
+	if (wanted > 0)
+		static_key_enable(&netstamp_needed);
+	else
+		static_key_disable(&netstamp_needed);
 }
 static DECLARE_WORK(netstamp_work, netstamp_clear);
 #endif
 
 void net_enable_timestamp(void)
 {
+#ifdef HAVE_JUMP_LABEL
+	int wanted;
+
+	while (1) {
+		wanted = atomic_read(&netstamp_wanted);
+		if (wanted <= 0)
+			break;
+		if (atomic_cmpxchg(&netstamp_wanted, wanted, wanted + 1) == wanted)
+			return;
+	}
+	atomic_inc(&netstamp_needed_deferred);
+	schedule_work(&netstamp_work);
+#else
 	static_key_slow_inc(&netstamp_needed);
+#endif
 }
 EXPORT_SYMBOL(net_enable_timestamp);
 
 void net_disable_timestamp(void)
 {
 #ifdef HAVE_JUMP_LABEL
-	/* net_disable_timestamp() can be called from non process context */
-	atomic_inc(&netstamp_needed_deferred);
+	int wanted;
+
+	while (1) {
+		wanted = atomic_read(&netstamp_wanted);
+		if (wanted <= 1)
+			break;
+		if (atomic_cmpxchg(&netstamp_wanted, wanted, wanted - 1) == wanted)
+			return;
+	}
+	atomic_dec(&netstamp_needed_deferred);
 	schedule_work(&netstamp_work);
 #else
 	static_key_slow_dec(&netstamp_needed);

Back to linux.kernel | Previous | Next | Find similar | Unroll thread


Thread

[PATCH 3.16 178/212] net: net_enable_timestamp() can be called  from irq contexts Ben Hutchings <ben@decadent.org.uk> - 2017-06-01 18:00 +0200

csiph-web