aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 962e3de25a35..c7ef6c5d3782 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1441,15 +1441,38 @@ int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
1441EXPORT_SYMBOL(call_netdevice_notifiers); 1441EXPORT_SYMBOL(call_netdevice_notifiers);
1442 1442
1443static struct jump_label_key netstamp_needed __read_mostly; 1443static struct jump_label_key netstamp_needed __read_mostly;
1444#ifdef HAVE_JUMP_LABEL
1445/* We are not allowed to call jump_label_dec() from irq context
1446 * If net_disable_timestamp() is called from irq context, defer the
1447 * jump_label_dec() calls.
1448 */
1449static atomic_t netstamp_needed_deferred;
1450#endif
1444 1451
1445void net_enable_timestamp(void) 1452void net_enable_timestamp(void)
1446{ 1453{
1454#ifdef HAVE_JUMP_LABEL
1455 int deferred = atomic_xchg(&netstamp_needed_deferred, 0);
1456
1457 if (deferred) {
1458 while (--deferred)
1459 jump_label_dec(&netstamp_needed);
1460 return;
1461 }
1462#endif
1463 WARN_ON(in_interrupt());
1447 jump_label_inc(&netstamp_needed); 1464 jump_label_inc(&netstamp_needed);
1448} 1465}
1449EXPORT_SYMBOL(net_enable_timestamp); 1466EXPORT_SYMBOL(net_enable_timestamp);
1450 1467
1451void net_disable_timestamp(void) 1468void net_disable_timestamp(void)
1452{ 1469{
1470#ifdef HAVE_JUMP_LABEL
1471 if (in_interrupt()) {
1472 atomic_inc(&netstamp_needed_deferred);
1473 return;
1474 }
1475#endif
1453 jump_label_dec(&netstamp_needed); 1476 jump_label_dec(&netstamp_needed);
1454} 1477}
1455EXPORT_SYMBOL(net_disable_timestamp); 1478EXPORT_SYMBOL(net_disable_timestamp);