|
@@ -35,6 +35,7 @@
|
|
#include <linux/moduleparam.h>
|
|
#include <linux/moduleparam.h>
|
|
#include <net/pkt_sched.h>
|
|
#include <net/pkt_sched.h>
|
|
#include <net/net_namespace.h>
|
|
#include <net/net_namespace.h>
|
|
|
|
+#include <linux/lockdep.h>
|
|
|
|
|
|
#define TX_TIMEOUT (2*HZ)
|
|
#define TX_TIMEOUT (2*HZ)
|
|
|
|
|
|
@@ -227,6 +228,16 @@ static struct rtnl_link_ops ifb_link_ops __read_mostly = {
|
|
module_param(numifbs, int, 0);
|
|
module_param(numifbs, int, 0);
|
|
MODULE_PARM_DESC(numifbs, "Number of ifb devices");
|
|
MODULE_PARM_DESC(numifbs, "Number of ifb devices");
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * dev_ifb->queue_lock is usually taken after dev->ingress_lock,
|
|
|
|
+ * reversely to e.g. qdisc_lock_tree(). It should be safe until
|
|
|
|
+ * ifb doesn't take dev->queue_lock with dev_ifb->ingress_lock.
|
|
|
|
+ * But lockdep should know that ifb has different locks from dev.
|
|
|
|
+ */
|
|
|
|
+static struct lock_class_key ifb_queue_lock_key;
|
|
|
|
+static struct lock_class_key ifb_ingress_lock_key;
|
|
|
|
+
|
|
|
|
+
|
|
static int __init ifb_init_one(int index)
|
|
static int __init ifb_init_one(int index)
|
|
{
|
|
{
|
|
struct net_device *dev_ifb;
|
|
struct net_device *dev_ifb;
|
|
@@ -246,6 +257,10 @@ static int __init ifb_init_one(int index)
|
|
err = register_netdevice(dev_ifb);
|
|
err = register_netdevice(dev_ifb);
|
|
if (err < 0)
|
|
if (err < 0)
|
|
goto err;
|
|
goto err;
|
|
|
|
+
|
|
|
|
+ lockdep_set_class(&dev_ifb->queue_lock, &ifb_queue_lock_key);
|
|
|
|
+ lockdep_set_class(&dev_ifb->ingress_lock, &ifb_ingress_lock_key);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
err:
|
|
err:
|