[B.A.T.M.A.N.] [PATCH] net, batman: don't crash on zero length strings in routing_algo
by Sasha Levin
The code that works with routing_algo assumes that the string passed is non
empty, this assumption is wrong:
sh-4.2# echo -ne '\0' > /sys/module/batman_adv/parameters/routing_algo
[ 34.531340] BUG: unable to handle kernel paging request at ffff880015142fff
[ 34.539191] IP: [<ffffffff8390ac7a>] batadv_param_set_ra+0x3a/0x90
[ 34.541128] PGD 5027063 PUD 502b063 PMD 1bfc6067 PTE 15142160
[ 34.541128] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
[ 34.541128] CPU 0
[ 34.541128] Pid: 6612, comm: sh Tainted: G W 3.7.0-rc6-sasha-00024-g33da443-dirty #157
[ 34.541128] RIP: 0010:[<ffffffff8390ac7a>] [<ffffffff8390ac7a>] batadv_param_set_ra+0x3a/0x90
[ 34.541128] RSP: 0018:ffff880014f81e48 EFLAGS: 00010292
[ 34.541128] RAX: 000000000000003b RBX: ffff880015143000 RCX: 0000000000000006
[ 34.550025] RDX: 0000000000000006 RSI: ffff8800151cb960 RDI: 0000000000000282
[ 34.550025] RBP: ffff880014f81e68 R08: 0000000000000003 R09: 0000000000000000
[ 34.550025] R10: 0000000000000000 R11: 0000000000000001 R12: ffff880015142fff
[ 34.550025] R13: ffffffff84e6b390 R14: ffff880014f86a00 R15: ffffffff83c35170
[ 34.550025] FS: 00007f9ebc796700(0000) GS:ffff88001a600000(0000) knlGS:0000000000000000
[ 34.550025] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 34.550025] CR2: ffff880015142fff CR3: 000000001522f000 CR4: 00000000000406f0
[ 34.550025] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 34.550025] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 34.550025] Process sh (pid: 6612, threadinfo ffff880014f80000, task ffff8800151cb000)
[ 34.550025] Stack:
[ 34.550025] ffff880014f81e68 ffff8800198ee020 0000000000000001 ffff880015143000
[ 34.550025] ffff880014f81e98 ffffffff81133776 ffff880014f81ea8 ffff880014f86a20
[ 34.550025] ffff880014f81f50 ffff880019d86d20 ffff880014f81ea8 ffffffff811335f8
[ 34.550025] Call Trace:
[ 34.550025] [<ffffffff81133776>] param_attr_store+0x46/0x80
[ 34.550025] [<ffffffff811335f8>] module_attr_store+0x18/0x40
[ 34.550025] [<ffffffff812ed751>] sysfs_write_file+0x101/0x170
[ 34.550025] [<ffffffff8126fcb8>] vfs_write+0xb8/0x180
[ 34.550025] [<ffffffff8126fe70>] sys_write+0x50/0xa0
[ 34.550025] [<ffffffff83b30018>] tracesys+0xe1/0xe6
[ 34.550025] Code: 4c 89 65 f0 4c 89 6d f8 49 89 f5 e8 71 c5 0b fe 48 c7 c7 38 2e df 84 4c 8d 60 ff 48 89 c6 31 c0 4c 89 e2 49 01 dc e8 a6 d8 15 00 <41> 80 3c 24 0a 75 05 41 c6 04 24 00 48 89 df e8 62 ff ff ff 48
[ 34.550025] RIP [<ffffffff8390ac7a>] batadv_param_set_ra+0x3a/0x90
[ 34.550025] RSP <ffff880014f81e48>
[ 34.550025] CR2: ffff880015142fff
[ 34.550025] ---[ end trace 6c53b662c574774b ]---
Signed-off-by: Sasha Levin <sasha.levin(a)oracle.com>
---
net/batman-adv/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index dc33a0c..3b8e368 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -426,7 +426,7 @@ static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
char *algo_name = (char *)val;
size_t name_len = strlen(algo_name);
- if (algo_name[name_len - 1] == '\n')
+ if (name_len > 0 && algo_name[name_len - 1] == '\n')
algo_name[name_len - 1] = '\0';
bat_algo_ops = batadv_algo_get(algo_name);
--
1.8.0
10 years, 1 month
[B.A.T.M.A.N.] [PATCH 1/7] batman-adv: Move soft-interface initialization to ndo_init
by Sven Eckelmann
The initialization of an net_device object should be done in the
init/constructor function and not from the outside after the register_netdevice
was done to avoid race conditions.
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
---
net/batman-adv/hard-interface.c | 5 ++
net/batman-adv/soft-interface.c | 147 ++++++++++++++++++---------------------
2 files changed, 73 insertions(+), 79 deletions(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 365ed74..50f4a5c 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -542,6 +542,11 @@ static int batadv_hard_if_event(struct notifier_block *this,
struct batadv_hard_iface *primary_if = NULL;
struct batadv_priv *bat_priv;
+ if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) {
+ batadv_sysfs_add_meshif(net_dev);
+ return NOTIFY_DONE;
+ }
+
hard_iface = batadv_hardif_get_by_netdev(net_dev);
if (!hard_iface && event == NETDEV_REGISTER)
hard_iface = batadv_hardif_add_interface(net_dev);
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 54800c7..b545595 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -407,9 +407,73 @@ static void batadv_set_lockdep_class(struct net_device *dev)
*/
static int batadv_softif_init(struct net_device *dev)
{
+ struct batadv_priv *bat_priv;
+ int ret;
+ size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM;
+
batadv_set_lockdep_class(dev);
+ bat_priv = netdev_priv(dev);
+
+ /* batadv_interface_stats() needs to be available as soon as
+ * register_netdevice() has been called
+ */
+ bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t));
+ if (!bat_priv->bat_counters)
+ return -ENOMEM;
+
+ atomic_set(&bat_priv->aggregated_ogms, 1);
+ atomic_set(&bat_priv->bonding, 0);
+ atomic_set(&bat_priv->bridge_loop_avoidance, 0);
+#ifdef CONFIG_BATMAN_ADV_DAT
+ atomic_set(&bat_priv->distributed_arp_table, 1);
+#endif
+ atomic_set(&bat_priv->ap_isolation, 0);
+ atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
+ atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
+ atomic_set(&bat_priv->gw_sel_class, 20);
+ atomic_set(&bat_priv->gw_bandwidth, 41);
+ atomic_set(&bat_priv->orig_interval, 1000);
+ atomic_set(&bat_priv->hop_penalty, 30);
+ atomic_set(&bat_priv->log_level, 0);
+ atomic_set(&bat_priv->fragmentation, 1);
+ atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
+ atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
+
+ atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
+ atomic_set(&bat_priv->bcast_seqno, 1);
+ atomic_set(&bat_priv->tt.vn, 0);
+ atomic_set(&bat_priv->tt.local_changes, 0);
+ atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
+#ifdef CONFIG_BATMAN_ADV_BLA
+ atomic_set(&bat_priv->bla.num_requests, 0);
+#endif
+ bat_priv->tt.last_changeset = NULL;
+ bat_priv->tt.last_changeset_len = 0;
+
+ bat_priv->primary_if = NULL;
+ bat_priv->num_ifaces = 0;
+
+ ret = batadv_algo_select(bat_priv, batadv_routing_algo);
+ if (ret < 0)
+ goto free_bat_counters;
+
+ ret = batadv_debugfs_add_meshif(dev);
+ if (ret < 0)
+ goto free_bat_counters;
+
+ ret = batadv_mesh_init(dev);
+ if (ret < 0)
+ goto unreg_debugfs;
+
return 0;
+
+unreg_debugfs:
+ batadv_debugfs_del_meshif(dev);
+free_bat_counters:
+ free_percpu(bat_priv->bat_counters);
+
+ return ret;
}
static const struct net_device_ops batadv_netdev_ops = {
@@ -451,97 +515,22 @@ static void batadv_interface_setup(struct net_device *dev)
struct net_device *batadv_softif_create(const char *name)
{
struct net_device *soft_iface;
- struct batadv_priv *bat_priv;
int ret;
- size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM;
- soft_iface = alloc_netdev(sizeof(*bat_priv), name,
+ soft_iface = alloc_netdev(sizeof(struct batadv_priv), name,
batadv_interface_setup);
-
if (!soft_iface)
- goto out;
-
- bat_priv = netdev_priv(soft_iface);
-
- /* batadv_interface_stats() needs to be available as soon as
- * register_netdevice() has been called
- */
- bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t));
- if (!bat_priv->bat_counters)
- goto free_soft_iface;
+ return NULL;
ret = register_netdevice(soft_iface);
if (ret < 0) {
pr_err("Unable to register the batman interface '%s': %i\n",
name, ret);
- goto free_bat_counters;
+ free_netdev(soft_iface);
+ return NULL;
}
- atomic_set(&bat_priv->aggregated_ogms, 1);
- atomic_set(&bat_priv->bonding, 0);
- atomic_set(&bat_priv->bridge_loop_avoidance, 0);
-#ifdef CONFIG_BATMAN_ADV_DAT
- atomic_set(&bat_priv->distributed_arp_table, 1);
-#endif
- atomic_set(&bat_priv->ap_isolation, 0);
- atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
- atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
- atomic_set(&bat_priv->gw_sel_class, 20);
- atomic_set(&bat_priv->gw_bandwidth, 41);
- atomic_set(&bat_priv->orig_interval, 1000);
- atomic_set(&bat_priv->hop_penalty, 30);
- atomic_set(&bat_priv->log_level, 0);
- atomic_set(&bat_priv->fragmentation, 1);
- atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
- atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
-
- atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
- atomic_set(&bat_priv->bcast_seqno, 1);
- atomic_set(&bat_priv->tt.vn, 0);
- atomic_set(&bat_priv->tt.local_changes, 0);
- atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
-#ifdef CONFIG_BATMAN_ADV_BLA
- atomic_set(&bat_priv->bla.num_requests, 0);
-#endif
- bat_priv->tt.last_changeset = NULL;
- bat_priv->tt.last_changeset_len = 0;
-
- bat_priv->primary_if = NULL;
- bat_priv->num_ifaces = 0;
-
- ret = batadv_algo_select(bat_priv, batadv_routing_algo);
- if (ret < 0)
- goto unreg_soft_iface;
-
- ret = batadv_sysfs_add_meshif(soft_iface);
- if (ret < 0)
- goto unreg_soft_iface;
-
- ret = batadv_debugfs_add_meshif(soft_iface);
- if (ret < 0)
- goto unreg_sysfs;
-
- ret = batadv_mesh_init(soft_iface);
- if (ret < 0)
- goto unreg_debugfs;
-
return soft_iface;
-
-unreg_debugfs:
- batadv_debugfs_del_meshif(soft_iface);
-unreg_sysfs:
- batadv_sysfs_del_meshif(soft_iface);
-unreg_soft_iface:
- free_percpu(bat_priv->bat_counters);
- unregister_netdevice(soft_iface);
- return NULL;
-
-free_bat_counters:
- free_percpu(bat_priv->bat_counters);
-free_soft_iface:
- free_netdev(soft_iface);
-out:
- return NULL;
}
void batadv_softif_destroy(struct net_device *soft_iface)
--
1.7.10.4
10 years, 1 month
[B.A.T.M.A.N.] [PATCHv2 1/5] batman-adv: Use common Jenkins Hash implementation
by Sven Eckelmann
An unoptimized version of the Jenkins one-at-a-time hash function is copied all
over the code wherever an hashtable is used. Instead the optimized version
shared between the whole kernel should be used to reduce code duplication and
keep bugs at a single point.
Only the DAT code must use the old implementation because it is used as
distributed hash function which has to be common for all nodes.
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
---
Removed special choose_tt function and instead also use jhash
bridge_loop_avoidance.c | 20 ++++++--------------
hash.h | 22 ----------------------
main.h | 1 +
originator.h | 15 ++-------------
vis.c | 15 ++-------------
5 files changed, 11 insertions(+), 62 deletions(-)
diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index ec12c79..1400274 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -41,14 +41,10 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
{
struct batadv_claim *claim = (struct batadv_claim *)data;
- uint32_t hash = 0;
+ uint32_t hash;
- hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
- hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
-
- hash += (hash << 3);
- hash ^= (hash >> 11);
- hash += (hash << 15);
+ hash = jhash(&claim->addr, sizeof(claim->addr), 0);
+ hash = jhash(&claim->vid, sizeof(claim->vid), hash);
return hash % size;
}
@@ -58,14 +54,10 @@ static inline uint32_t batadv_choose_backbone_gw(const void *data,
uint32_t size)
{
struct batadv_claim *claim = (struct batadv_claim *)data;
- uint32_t hash = 0;
+ uint32_t hash;
- hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
- hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
-
- hash += (hash << 3);
- hash ^= (hash >> 11);
- hash += (hash << 15);
+ hash = jhash(&claim->addr, sizeof(claim->addr), 0);
+ hash = jhash(&claim->vid, sizeof(claim->vid), hash);
return hash % size;
}
diff --git a/hash.h b/hash.h
index e053339..977de9c 100644
--- a/hash.h
+++ b/hash.h
@@ -82,28 +82,6 @@ static inline void batadv_hash_delete(struct batadv_hashtable *hash,
}
/**
- * batadv_hash_bytes - hash some bytes and add them to the previous hash
- * @hash: previous hash value
- * @data: data to be hashed
- * @size: number of bytes to be hashed
- *
- * Returns the new hash value.
- */
-static inline uint32_t batadv_hash_bytes(uint32_t hash, void *data,
- uint32_t size)
-{
- const unsigned char *key = data;
- int i;
-
- for (i = 0; i < size; i++) {
- hash += key[i];
- hash += (hash << 10);
- hash ^= (hash >> 6);
- }
- return hash;
-}
-
-/**
* batadv_hash_add - adds data to the hashtable
* @hash: storage hash table
* @compare: callback to determine if 2 hash elements are identical
diff --git a/main.h b/main.h
index 2032de2..f58e373 100644
--- a/main.h
+++ b/main.h
@@ -147,6 +147,7 @@ enum batadv_uev_type {
#include <linux/workqueue.h> /* workqueue */
#include <linux/percpu.h>
#include <linux/slab.h>
+#include <linux/jhash.h>
#include <net/sock.h> /* struct sock */
#include <linux/jiffies.h>
#include <linux/seq_file.h>
diff --git a/originator.h b/originator.h
index 9778e65..1311d39 100644
--- a/originator.h
+++ b/originator.h
@@ -46,20 +46,9 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
*/
static inline uint32_t batadv_choose_orig(const void *data, uint32_t size)
{
- const unsigned char *key = data;
- uint32_t hash = 0;
- size_t i;
-
- for (i = 0; i < 6; i++) {
- hash += key[i];
- hash += (hash << 10);
- hash ^= (hash >> 6);
- }
-
- hash += (hash << 3);
- hash ^= (hash >> 11);
- hash += (hash << 15);
+ uint32_t hash;
+ hash = jhash(data, ETH_ALEN, 0);
return hash % size;
}
diff --git a/vis.c b/vis.c
index 0f65a9d..2eb6878 100644
--- a/vis.c
+++ b/vis.c
@@ -72,21 +72,10 @@ static uint32_t batadv_vis_info_choose(const void *data, uint32_t size)
{
const struct batadv_vis_info *vis_info = data;
const struct batadv_vis_packet *packet;
- const unsigned char *key;
- uint32_t hash = 0;
- size_t i;
+ uint32_t hash;
packet = (struct batadv_vis_packet *)vis_info->skb_packet->data;
- key = packet->vis_orig;
- for (i = 0; i < ETH_ALEN; i++) {
- hash += key[i];
- hash += (hash << 10);
- hash ^= (hash >> 6);
- }
-
- hash += (hash << 3);
- hash ^= (hash >> 11);
- hash += (hash << 15);
+ hash = jhash(&packet->vis_orig, sizeof(packet->vis_orig), 0);
return hash % size;
}
--
1.7.10.4
10 years, 1 month
[B.A.T.M.A.N.] [RFC] batman-adv boot setup scheme on OpenWRT
by Gui Iribarren
Hello Marek and folks,
chasing a race condition, I might have delved a little too deep into
openwrt boot sequence :(
AFAICU, currently there's a /etc/hotplug.d/net/99-batman-adv script
which tries to configure both bat0 , and any interfaces coming up that
might have to be included there. Problem is, hotplug.d/net scripts are
called when interface is "added" but not necessarilly brought up yet.
So there's a "sleep 3s" that works in most cases as a window for slow
hardware bring up the interface.
...in most cases :(
on an old nanoloco2, creating 2 wifi-ifaces in ap mode and 1 in ibss
mode, managed with batman-adv, the sleep 3s is not enough. A 6s
timeout works around it, but maybe there's a better solution?
I've divided the script, putting the "add candidate interfaces to
bat0" into /etc/hotplug.d/*iface*/99-batman-adv , which gets called
precisely after an interface is actually brought up.
This works as expected, and i could even eliminate the original 3s sleep.
hotplug.d/iface script adds candidate interfaces to batX after they
are brought up
hotplug.d/net script configures batX as they appear,
Would that work in general? Or was the single hotplug.d/net
implemented that way, for a reason i'm missing?
Thanks!
Gui
10 years, 2 months
[B.A.T.M.A.N.] net, batman: lockdep circular dependency warning
by Sasha Levin
Hi all,
While fuzzing with trinity inside a KVM tools (lkvm) guest running latest -next
kernel, I've stumbled on the following:
[ 1002.969392] ======================================================
[ 1002.971639] [ INFO: possible circular locking dependency detected ]
[ 1002.975805] 3.7.0-rc5-next-20121112-sasha-00018-g2f4ce0e #127 Tainted: G W
[ 1002.983691] -------------------------------------------------------
[ 1002.983691] trinity-child18/8149 is trying to acquire lock:
[ 1002.983691] (s_active#313){++++.+}, at: [<ffffffff812f9941>] sysfs_addrm_finish+0x31/0x60
[ 1002.983691]
[ 1002.983691] but task is already holding lock:
[ 1002.983691] (rtnl_mutex){+.+.+.}, at: [<ffffffff834fcc62>] rtnl_lock+0x12/0x20
[ 1002.983691]
[ 1002.983691] which lock already depends on the new lock.
[ 1002.983691]
[ 1002.983691]
[ 1002.983691] the existing dependency chain (in reverse order) is:
[ 1002.983691]
-> #1 (rtnl_mutex){+.+.+.}:
[ 1002.983691] [<ffffffff81180d0a>] check_prevs_add+0xba/0x1a0
[ 1002.983691] [<ffffffff81181490>] validate_chain.isra.23+0x6a0/0x7b0
[ 1002.983691] [<ffffffff81183e3b>] __lock_acquire+0x9db/0xa90
[ 1002.983691] [<ffffffff8118635a>] lock_acquire+0x1ca/0x270
[ 1002.983691] [<ffffffff83bf647a>] __mutex_lock_common+0x5a/0x550
[ 1002.983691] [<ffffffff83bf69af>] mutex_lock_nested+0x3f/0x50
[ 1002.983691] [<ffffffff834fcc62>] rtnl_lock+0x12/0x20
[ 1002.983691] [<ffffffff834eeb3c>] netdev_run_todo+0x7c/0x180
[ 1002.983691] [<ffffffff834fcfa9>] rtnl_unlock+0x9/0x10
[ 1002.983691] [<ffffffff839d7da1>] batadv_store_mesh_iface+0x121/0x160
[ 1002.983691] [<ffffffff819d303f>] kobj_attr_store+0xf/0x30
[ 1002.983691] [<ffffffff812f7d41>] sysfs_write_file+0x101/0x170
[ 1002.983691] [<ffffffff8127ac58>] vfs_write+0xb8/0x180
[ 1002.983691] [<ffffffff8127af57>] sys_pwrite64+0x67/0x90
[ 1002.983691] [<ffffffff83bfafd8>] tracesys+0xe1/0xe6
[ 1002.983691]
-> #0 (s_active#313){++++.+}:
[ 1002.983691] [<ffffffff81180725>] check_prev_add+0x115/0x640
[ 1002.983691] [<ffffffff81180d0a>] check_prevs_add+0xba/0x1a0
[ 1002.983691] [<ffffffff81181490>] validate_chain.isra.23+0x6a0/0x7b0
[ 1002.983691] [<ffffffff81183e3b>] __lock_acquire+0x9db/0xa90
[ 1002.983691] [<ffffffff8118635a>] lock_acquire+0x1ca/0x270
[ 1002.983691] [<ffffffff812f8eaa>] sysfs_deactivate+0x11a/0x190
[ 1002.983691] [<ffffffff812f9941>] sysfs_addrm_finish+0x31/0x60
[ 1002.983691] [<ffffffff812f9a0a>] __sysfs_remove_dir+0x9a/0xd0
[ 1002.983691] [<ffffffff812f9f2f>] sysfs_remove_dir+0x3f/0x50
[ 1002.983691] [<ffffffff819d3806>] kobject_del+0x16/0x40
[ 1002.983691] [<ffffffff819d3930>] kobject_cleanup+0x100/0x190
[ 1002.983691] [<ffffffff819d39cd>] kobject_release+0xd/0x10
[ 1002.983691] [<ffffffff819d33cc>] kobject_put+0x4c/0x60
[ 1002.983691] [<ffffffff839d8134>] batadv_sysfs_del_hardif+0x14/0x30
[ 1002.983691] [<ffffffff839cdacd>] batadv_hardif_remove_interface+0x5d/0x90
[ 1002.983691] [<ffffffff839cdba1>] batadv_hard_if_event+0xa1/0x2f0
[ 1002.983691] [<ffffffff8114271e>] notifier_call_chain+0xee/0x130
[ 1002.983691] [<ffffffff81142d31>] raw_notifier_call_chain+0x11/0x20
[ 1002.983691] [<ffffffff834e8dc2>] call_netdevice_notifiers+0x52/0x60
[ 1002.983691] [<ffffffff834ef4cd>] rollback_registered_many+0x14d/0x210
[ 1002.983691] [<ffffffff834ef5bc>] rollback_registered+0x2c/0x40
[ 1002.983691] [<ffffffff834ef650>] unregister_netdevice_queue+0x70/0xa0
[ 1002.983691] [<ffffffff834ef7bb>] unregister_netdev+0x1b/0x30
[ 1002.983691] [<ffffffff82a51fcc>] usbnet_disconnect+0x8c/0xf0
[ 1002.983691] [<ffffffff82b0aca7>] usb_unbind_interface+0x67/0x160
[ 1002.983691] [<ffffffff81e580a1>] __device_release_driver+0x81/0xe0
[ 1002.983691] [<ffffffff81e581f9>] device_release_driver+0x29/0x40
[ 1002.983691] [<ffffffff81e56c98>] bus_remove_device+0x138/0x150
[ 1002.983691] [<ffffffff81e54e8d>] device_del+0x13d/0x1a0
[ 1002.983691] [<ffffffff82b08459>] usb_disable_device+0xd9/0x270
[ 1002.983691] [<ffffffff82b08f38>] usb_set_configuration+0x268/0x7b0
[ 1002.983691] [<ffffffff82b0e5e3>] usb_remove_store+0x43/0x80
[ 1002.983691] [<ffffffff81e536c3>] dev_attr_store+0x13/0x30
[ 1002.983691] [<ffffffff812f7d41>] sysfs_write_file+0x101/0x170
[ 1002.983691] [<ffffffff8127ac58>] vfs_write+0xb8/0x180
[ 1002.983691] [<ffffffff8127ae10>] sys_write+0x50/0xa0
[ 1002.983691] [<ffffffff83bfafd8>] tracesys+0xe1/0xe6
[ 1002.983691]
[ 1002.983691] other info that might help us debug this:
[ 1002.983691]
[ 1002.983691] Possible unsafe locking scenario:
[ 1002.983691]
[ 1002.983691] CPU0 CPU1
[ 1002.983691] ---- ----
[ 1002.983691] lock(rtnl_mutex);
[ 1002.983691] lock(s_active#313);
[ 1002.983691] lock(rtnl_mutex);
[ 1002.983691] lock(s_active#313);
[ 1002.983691]
[ 1002.983691] *** DEADLOCK ***
[ 1002.983691]
[ 1002.983691] 4 locks held by trinity-child18/8149:
[ 1002.983691] #0: (&buffer->mutex){+.+.+.}, at: [<ffffffff812f7c7f>] sysfs_write_file+0x3f/0x170
[ 1002.983691] #1: (&__lockdep_no_validate__){......}, at: [<ffffffff82b0e5c8>] usb_remove_store+0x28/0x80
[ 1002.983691] #2: (&__lockdep_no_validate__){......}, at: [<ffffffff81e581f1>] device_release_driver+0x21/0x40
[ 1002.983691] #3: (rtnl_mutex){+.+.+.}, at: [<ffffffff834fcc62>] rtnl_lock+0x12/0x20
[ 1002.983691]
[ 1002.983691] stack backtrace:
[ 1002.983691] Pid: 8149, comm: trinity-child18 Tainted: G W 3.7.0-rc5-next-20121112-sasha-00018-g2f4ce0e #127
[ 1002.983691] Call Trace:
[ 1002.983691] [<ffffffff83b322b9>] print_circular_bug+0xd3/0xe4
[ 1002.983691] [<ffffffff81180725>] check_prev_add+0x115/0x640
[ 1002.983691] [<ffffffff81180d0a>] check_prevs_add+0xba/0x1a0
[ 1002.983691] [<ffffffff8117e134>] ? graph_unlock+0xa4/0xb0
[ 1002.983691] [<ffffffff81181490>] validate_chain.isra.23+0x6a0/0x7b0
[ 1002.983691] [<ffffffff81183e3b>] __lock_acquire+0x9db/0xa90
[ 1002.983691] [<ffffffff81181ce9>] ? mark_held_locks+0xf9/0x130
[ 1002.983691] [<ffffffff811844af>] ? lockdep_init_map+0xcf/0x5e0
[ 1002.983691] [<ffffffff8118635a>] lock_acquire+0x1ca/0x270
[ 1002.983691] [<ffffffff812f9941>] ? sysfs_addrm_finish+0x31/0x60
[ 1002.983691] [<ffffffff812f8eaa>] sysfs_deactivate+0x11a/0x190
[ 1002.983691] [<ffffffff812f9941>] ? sysfs_addrm_finish+0x31/0x60
[ 1002.983691] [<ffffffff812f9941>] sysfs_addrm_finish+0x31/0x60
[ 1002.983691] [<ffffffff812f9a0a>] __sysfs_remove_dir+0x9a/0xd0
[ 1002.983691] [<ffffffff812f9f2f>] sysfs_remove_dir+0x3f/0x50
[ 1002.983691] [<ffffffff819d3806>] kobject_del+0x16/0x40
[ 1002.983691] [<ffffffff819d3930>] kobject_cleanup+0x100/0x190
[ 1002.983691] [<ffffffff819d39cd>] kobject_release+0xd/0x10
[ 1002.983691] [<ffffffff819d33cc>] kobject_put+0x4c/0x60
[ 1002.983691] [<ffffffff839d8134>] batadv_sysfs_del_hardif+0x14/0x30
[ 1002.983691] [<ffffffff839cd040>] ? batadv_primary_if_update_addr+0x280/0x280
[ 1002.983691] [<ffffffff839cdacd>] batadv_hardif_remove_interface+0x5d/0x90
[ 1002.983691] [<ffffffff839cdba1>] batadv_hard_if_event+0xa1/0x2f0
[ 1002.983691] [<ffffffff8114271e>] notifier_call_chain+0xee/0x130
[ 1002.983691] [<ffffffff81142d31>] raw_notifier_call_chain+0x11/0x20
[ 1002.983691] [<ffffffff834e8dc2>] call_netdevice_notifiers+0x52/0x60
[ 1002.983691] [<ffffffff834ef4cd>] rollback_registered_many+0x14d/0x210
[ 1002.983691] [<ffffffff834ef5bc>] rollback_registered+0x2c/0x40
[ 1002.983691] [<ffffffff834ef650>] unregister_netdevice_queue+0x70/0xa0
[ 1002.983691] [<ffffffff834ef7bb>] unregister_netdev+0x1b/0x30
[ 1002.983691] [<ffffffff82a51fcc>] usbnet_disconnect+0x8c/0xf0
[ 1002.983691] [<ffffffff82b0aca7>] usb_unbind_interface+0x67/0x160
[ 1002.983691] [<ffffffff81e580a1>] __device_release_driver+0x81/0xe0
[ 1002.983691] [<ffffffff81e581f9>] device_release_driver+0x29/0x40
[ 1002.983691] [<ffffffff81e56c98>] bus_remove_device+0x138/0x150
[ 1002.983691] [<ffffffff81e54e8d>] device_del+0x13d/0x1a0
[ 1002.983691] [<ffffffff82b08459>] usb_disable_device+0xd9/0x270
[ 1002.983691] [<ffffffff82b08f38>] usb_set_configuration+0x268/0x7b0
[ 1002.983691] [<ffffffff82b0e5c8>] ? usb_remove_store+0x28/0x80
[ 1002.983691] [<ffffffff82b0e5e3>] usb_remove_store+0x43/0x80
[ 1002.983691] [<ffffffff81e536c3>] dev_attr_store+0x13/0x30
[ 1002.983691] [<ffffffff812f7d41>] sysfs_write_file+0x101/0x170
[ 1002.983691] [<ffffffff8127ac58>] vfs_write+0xb8/0x180
[ 1002.983691] [<ffffffff8127ae10>] sys_write+0x50/0xa0
[ 1002.983691] [<ffffffff83bfafd8>] tracesys+0xe1/0xe6
Thanks,
Sasha
10 years, 2 months
[B.A.T.M.A.N.] [PATCH] batman-adv: don't compile the BLA switch if not requested
by Antonio Quartulli
When the Bridge Loop Avoidance component is not compiled-in, its boolean switch
should be not compiled as well. This patch surrounds the switch with a proper
ifdef.
This behaviour was introduced by 9fd6b0615b5499b270d39a92b8790e206cf75833
("batman-adv: add bridge loop avoidance compile option")
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
soft-interface.c | 2 ++
types.h | 2 ++
2 files changed, 4 insertions(+)
diff --git a/soft-interface.c b/soft-interface.c
index 8000639..aa34267 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -480,7 +480,9 @@ struct net_device *batadv_softif_create(const char *name)
atomic_set(&bat_priv->aggregated_ogms, 1);
atomic_set(&bat_priv->bonding, 0);
+#ifdef CONFIG_BATMAN_ADV_BLA
atomic_set(&bat_priv->bridge_loop_avoidance, 0);
+#endif
#ifdef CONFIG_BATMAN_ADV_DAT
atomic_set(&bat_priv->distributed_arp_table, 1);
#endif
diff --git a/types.h b/types.h
index ae9ac9a..030ce41 100644
--- a/types.h
+++ b/types.h
@@ -273,7 +273,9 @@ struct batadv_priv {
atomic_t bonding; /* boolean */
atomic_t fragmentation; /* boolean */
atomic_t ap_isolation; /* boolean */
+#ifdef CONFIG_BATMAN_ADV_BLA
atomic_t bridge_loop_avoidance; /* boolean */
+#endif
#ifdef CONFIG_BATMAN_ADV_DAT
atomic_t distributed_arp_table; /* boolean */
#endif
--
1.8.0
10 years, 2 months
[B.A.T.M.A.N.] [PATCHv2] batman-adv: don't print the last_seen time for bat0 TT local entry
by Antonio Quartulli
bat0 MAC address will never deleted from the local translation table, therefore
printing its last_Seen time is useless and will also produce ugly output and
eventually a variable overflow.
This was introduced by 59cb0861498776c62bd17584c31f34477fa301a0 ("batman-adv:
improve local translation table output")
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
translation-table.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/translation-table.c b/translation-table.c
index 1335294..5f44232 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -478,6 +478,8 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
int last_seen_secs;
int last_seen_msecs;
unsigned long last_seen_jiffies;
+ bool no_purge;
+ uint16_t np_flag = BATADV_TT_CLIENT_NOPURGE;
primary_if = batadv_seq_print_text_primary_if_get(seq);
if (!primary_if)
@@ -504,19 +506,21 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
last_seen_secs = last_seen_msecs / 1000;
last_seen_msecs = last_seen_msecs % 1000;
+ no_purge = tt_common_entry->flags & np_flag;
+
seq_printf(seq, " * %pM [%c%c%c%c%c] %3u.%03u\n",
tt_common_entry->addr,
(tt_common_entry->flags &
BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
- (tt_common_entry->flags &
- BATADV_TT_CLIENT_NOPURGE ? 'P' : '.'),
+ no_purge ? 'P' : '.',
(tt_common_entry->flags &
BATADV_TT_CLIENT_NEW ? 'N' : '.'),
(tt_common_entry->flags &
BATADV_TT_CLIENT_PENDING ? 'X' : '.'),
(tt_common_entry->flags &
BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
- last_seen_secs, last_seen_msecs);
+ no_purge ? last_seen_secs : 0,
+ no_purge ? last_seen_msecs : 0);
}
rcu_read_unlock();
}
--
1.8.0
10 years, 2 months
[B.A.T.M.A.N.] [PATCH] batman-adv: remove useless NULL check
by Antonio Quartulli
debugfs_remove_recursive() checks whether its argument is not null
on its own, therefore it is possible to remove the external check.
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
debugfs.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/debugfs.c b/debugfs.c
index 6f58ddd..9df070c 100644
--- a/debugfs.c
+++ b/debugfs.c
@@ -397,10 +397,8 @@ err:
void batadv_debugfs_destroy(void)
{
- if (batadv_debugfs) {
- debugfs_remove_recursive(batadv_debugfs);
- batadv_debugfs = NULL;
- }
+ debugfs_remove_recursive(batadv_debugfs);
+ batadv_debugfs = NULL;
}
int batadv_debugfs_add_meshif(struct net_device *dev)
--
1.8.0
10 years, 2 months
[B.A.T.M.A.N.] [PATCH] batman-adv: Initialize lockdep class keys for hashes
by Antonio Quartulli
Different hashes have the same class key key because they get
initialised with the same one. For this reason lockdep can create
false warning when they are used recursively.
Re-initialise the key for each hash after the invocation to hash_new()
to avoid this problem.
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
originator.c | 6 ++++++
translation-table.c | 10 ++++++++++
vis.c | 6 ++++++
3 files changed, 22 insertions(+)
diff --git a/originator.c b/originator.c
index 8c32cf1..109081c 100644
--- a/originator.c
+++ b/originator.c
@@ -29,6 +29,9 @@
#include "soft-interface.h"
#include "bridge_loop_avoidance.h"
+/* hash class keys */
+static struct lock_class_key batadv_orig_hash_lock_class_key;
+
static void batadv_purge_orig(struct work_struct *work);
static void batadv_start_purge_timer(struct batadv_priv *bat_priv)
@@ -57,6 +60,9 @@ int batadv_originator_init(struct batadv_priv *bat_priv)
if (!bat_priv->orig_hash)
goto err;
+ batadv_hash_set_lock_class(bat_priv->orig_hash,
+ &batadv_orig_hash_lock_class_key);
+
batadv_start_purge_timer(bat_priv);
return 0;
diff --git a/translation-table.c b/translation-table.c
index 4657d9e..1bcb705 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -29,6 +29,10 @@
#include <linux/crc16.h>
+/* hash class keys */
+static struct lock_class_key batadv_tt_local_hash_lock_class_key;
+static struct lock_class_key batadv_tt_global_hash_lock_class_key;
+
static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
struct batadv_orig_node *orig_node);
static void batadv_tt_purge(struct work_struct *work);
@@ -235,6 +239,9 @@ static int batadv_tt_local_init(struct batadv_priv *bat_priv)
if (!bat_priv->tt.local_hash)
return -ENOMEM;
+ batadv_hash_set_lock_class(bat_priv->tt.local_hash,
+ &batadv_tt_local_hash_lock_class_key);
+
return 0;
}
@@ -691,6 +698,9 @@ static int batadv_tt_global_init(struct batadv_priv *bat_priv)
if (!bat_priv->tt.global_hash)
return -ENOMEM;
+ batadv_hash_set_lock_class(bat_priv->tt.global_hash,
+ &batadv_tt_global_hash_lock_class_key);
+
return 0;
}
diff --git a/vis.c b/vis.c
index 0f65a9d..60eb9b7 100644
--- a/vis.c
+++ b/vis.c
@@ -28,6 +28,9 @@
#define BATADV_MAX_VIS_PACKET_SIZE 1000
+/* hash class keys */
+static struct lock_class_key batadv_vis_hash_lock_class_key;
+
static void batadv_start_vis_timer(struct batadv_priv *bat_priv);
/* free the info */
@@ -852,6 +855,9 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
goto err;
}
+ batadv_hash_set_lock_class(bat_priv->vis.hash,
+ &batadv_vis_hash_lock_class_key);
+
bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
if (!bat_priv->vis.my_info)
goto err;
--
1.8.0
10 years, 2 months
[B.A.T.M.A.N.] [PATCH 0/6] CATWOMAN: Network coding in batman-adv
by Martin Hundebøll
I hereby bring you network coding in batman-adv. (Changed accoring
to Antonios partlial review). This allows a relay to send two packets
(to two destinations) in a single transmission. Tests[1] have shown
an increase in throughput up to 1.6 under the right circumstances.
For this to work, you will need to compile batman-adv with
CONFIG_BATMAN_ADV_NC=y and a wireless interface with working
promiscuous mode. The rest is taken care of by batman-adv and the
following patches.
[1] http://www.open-mesh.org/projects/open-mesh/wiki/2011-08-18-network-codin...
Martin Hundebøll (6):
batman-adv: Add the initial code for network coding.
batman-adv: Detect coding nodes and remove these after timeout
batman-adv: Buffer unicast packets before forward.
batman-adv: Code and transmit packets if possible.
batman-adv: Save overheard and tx packets for decoding.
batman-adv: Receive coded packets and decode them.
Makefile | 2 +
Makefile.kbuild | 1 +
bat_iv_ogm.c | 5 +
compat.c | 10 +
compat.h | 1 +
debugfs.c | 18 +
gen-compat-autoconf.sh | 1 +
main.c | 6 +
main.h | 13 +-
network-coding.c | 1817 ++++++++++++++++++++++++++++++++++++++++++++++++
network-coding.h | 123 ++++
originator.c | 6 +
packet.h | 33 +
routing.c | 26 +-
send.c | 5 +
soft-interface.c | 14 +
sysfs-class-net-mesh | 8 +
sysfs.c | 6 +
types.h | 123 ++++
19 files changed, 2209 insertions(+), 9 deletions(-)
create mode 100644 network-coding.c
create mode 100644 network-coding.h
--
1.8.0.1
10 years, 2 months