|
@@ -1441,15 +1441,38 @@ int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
|
|
|
EXPORT_SYMBOL(call_netdevice_notifiers);
|
|
|
|
|
|
static struct jump_label_key netstamp_needed __read_mostly;
|
|
|
+#ifdef HAVE_JUMP_LABEL
|
|
|
+/* We are not allowed to call jump_label_dec() from irq context
|
|
|
+ * If net_disable_timestamp() is called from irq context, defer the
|
|
|
+ * jump_label_dec() calls.
|
|
|
+ */
|
|
|
+static atomic_t netstamp_needed_deferred;
|
|
|
+#endif
|
|
|
|
|
|
void net_enable_timestamp(void)
|
|
|
{
|
|
|
+#ifdef HAVE_JUMP_LABEL
|
|
|
+ int deferred = atomic_xchg(&netstamp_needed_deferred, 0);
|
|
|
+
|
|
|
+ if (deferred) {
|
|
|
+ while (--deferred)
|
|
|
+ jump_label_dec(&netstamp_needed);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ WARN_ON(in_interrupt());
|
|
|
jump_label_inc(&netstamp_needed);
|
|
|
}
|
|
|
EXPORT_SYMBOL(net_enable_timestamp);
|
|
|
|
|
|
void net_disable_timestamp(void)
|
|
|
{
|
|
|
+#ifdef HAVE_JUMP_LABEL
|
|
|
+ if (in_interrupt()) {
|
|
|
+ atomic_inc(&netstamp_needed_deferred);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+#endif
|
|
|
jump_label_dec(&netstamp_needed);
|
|
|
}
|
|
|
EXPORT_SYMBOL(net_disable_timestamp);
|