diff options
| author | Sven Eckelmann <sven@narfation.org> | 2012-08-20 03:03:59 -0400 |
|---|---|---|
| committer | Antonio Quartulli <ordex@autistici.org> | 2012-10-29 04:42:32 -0400 |
| commit | 36c1d1531130dcfadf845419fd15735b9b4c004f (patch) | |
| tree | 7bb3d3253eed07d3d32cb51c00ad3a17e496543e /net/batman-adv | |
| parent | c10dba051a3e287a4f023aaaeffa53fd642cf8c5 (diff) | |
batman-adv: Set special lockdep classes to avoid lockdep warning
Transmissions over batman-adv devices always start another nested transmission
over devices attached to the batman-adv interface. These devices usually use
the ethernet lockdep class for the tx_queue lock which is also set by default
for all batman-adv devices. Lockdep will detect a nested locking attempt of two
locks with the same class and warn about a possible deadlock.
This is the default and expected behavior and should not alarm the locking
correctness prove mechanism. Therefore, the locks for all netdevice specific tx
queues get a special batman-adv lock class to avoid a false positive for each
transmission.
Reported-by: Linus Luessing <linus.luessing@web.de>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Diffstat (limited to 'net/batman-adv')
| -rw-r--r-- | net/batman-adv/soft-interface.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index b9a28d2dd3e8..948860a2a576 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
| @@ -347,7 +347,51 @@ out: | |||
| 347 | return; | 347 | return; |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | /* batman-adv network devices have devices nesting below it and are a special | ||
| 351 | * "super class" of normal network devices; split their locks off into a | ||
| 352 | * separate class since they always nest. | ||
| 353 | */ | ||
| 354 | static struct lock_class_key batadv_netdev_xmit_lock_key; | ||
| 355 | static struct lock_class_key batadv_netdev_addr_lock_key; | ||
| 356 | |||
| 357 | /** | ||
| 358 | * batadv_set_lockdep_class_one - Set lockdep class for a single tx queue | ||
| 359 | * @dev: device which owns the tx queue | ||
| 360 | * @txq: tx queue to modify | ||
| 361 | * @_unused: always NULL | ||
| 362 | */ | ||
| 363 | static void batadv_set_lockdep_class_one(struct net_device *dev, | ||
| 364 | struct netdev_queue *txq, | ||
| 365 | void *_unused) | ||
| 366 | { | ||
| 367 | lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key); | ||
| 368 | } | ||
| 369 | |||
| 370 | /** | ||
| 371 | * batadv_set_lockdep_class - Set txq and addr_list lockdep class | ||
| 372 | * @dev: network device to modify | ||
| 373 | */ | ||
| 374 | static void batadv_set_lockdep_class(struct net_device *dev) | ||
| 375 | { | ||
| 376 | lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); | ||
| 377 | netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); | ||
| 378 | } | ||
| 379 | |||
| 380 | /** | ||
| 381 | * batadv_softif_init - Late stage initialization of soft interface | ||
| 382 | * @dev: registered network device to modify | ||
| 383 | * | ||
| 384 | * Returns error code on failures | ||
| 385 | */ | ||
| 386 | static int batadv_softif_init(struct net_device *dev) | ||
| 387 | { | ||
| 388 | batadv_set_lockdep_class(dev); | ||
| 389 | |||
| 390 | return 0; | ||
| 391 | } | ||
| 392 | |||
| 350 | static const struct net_device_ops batadv_netdev_ops = { | 393 | static const struct net_device_ops batadv_netdev_ops = { |
| 394 | .ndo_init = batadv_softif_init, | ||
| 351 | .ndo_open = batadv_interface_open, | 395 | .ndo_open = batadv_interface_open, |
| 352 | .ndo_stop = batadv_interface_release, | 396 | .ndo_stop = batadv_interface_release, |
| 353 | .ndo_get_stats = batadv_interface_stats, | 397 | .ndo_get_stats = batadv_interface_stats, |
