diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-23 10:07:36 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-23 10:07:36 -0700 |
| commit | bdbec69777671b0b686cac94da9432b90f44ceb3 (patch) | |
| tree | 29b35250619be615ff80f741f608af606f39580e | |
| parent | 3fc142cf909428a48916a8f0d1d4fa01eb86c0d6 (diff) | |
| download | patches-bdbec69777671b0b686cac94da9432b90f44ceb3.tar.gz | |
batman-adv fixes added
9 files changed, 554 insertions, 2 deletions
@@ -66,6 +66,15 @@ staging.current/staging-spectra-remove-duplicate-glob_version-definition.patch staging.current/staging-spectra-removes-unused-variable.patch staging.current/staging-spectra-initializa-lblk-variable.patch staging.current/staging-spectra-removes-unused-functions.patch +staging.current/staging-batman-adv-fix-merge-of-linus-tree.patch +staging.current/staging-batman-adv-unify-orig_hash_lock-spinlock-handling-to-avoid-deadlocks.patch +staging.current/staging-batman-adv-fix-batman-icmp-originating-from-secondary-interface.patch +staging.current/staging-batman-adv-always-reply-batman-icmp-packets-with-primary-mac.patch +staging.current/staging-batman-adv-fix-own-mac-address-detection.patch +staging.current/staging-batman-adv-create-batman_if-only-on-register-event.patch +staging.current/staging-batman-adv-don-t-use-net_dev-after-dev_put.patch +staging.current/staging-batman-adv-don-t-write-in-not-allocated-packet_buff.patch + ##################################################################### # Stuff to be merged after 2.6.36 is out @@ -91,5 +100,3 @@ staging.current/staging-spectra-removes-unused-functions.patch - - diff --git a/staging.current/staging-batman-adv-always-reply-batman-icmp-packets-with-primary-mac.patch b/staging.current/staging-batman-adv-always-reply-batman-icmp-packets-with-primary-mac.patch new file mode 100644 index 00000000000000..351fefc020bd69 --- /dev/null +++ b/staging.current/staging-batman-adv-always-reply-batman-icmp-packets-with-primary-mac.patch @@ -0,0 +1,86 @@ +From sven.eckelmann@gmx.de Mon Aug 23 10:02:03 2010 +From: Marek Lindner <lindner_marek@yahoo.de> +To: greg@kroah.com +Cc: b.a.t.m.a.n@lists.open-mesh.net, + Marek Lindner <lindner_marek@yahoo.de>, + Sven Eckelmann <sven.eckelmann@gmx.de> +Subject: Staging: batman-adv: always reply batman icmp packets with primary mac +Date: Mon, 9 Aug 2010 23:56:41 +0200 +Message-Id: <1281391002-21577-5-git-send-email-sven.eckelmann@gmx.de> + +From: Marek Lindner <lindner_marek@yahoo.de> + +When receiving an batman icmp echo request or in case of a time-to-live +exceeded batman would reply with the mac address of the outgoing +interface which might be a secondary interface. Because secondary +interfaces are not globally known this might lead to confusion. +Now, replies are sent with the mac address of the primary interface. + +Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> +Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/batman-adv/routing.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/staging/batman-adv/routing.c ++++ b/drivers/staging/batman-adv/routing.c +@@ -783,6 +783,8 @@ int recv_bat_packet(struct sk_buff *skb, + + static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) + { ++ /* FIXME: each batman_if will be attached to a softif */ ++ struct bat_priv *bat_priv = netdev_priv(soft_device); + struct orig_node *orig_node; + struct icmp_packet_rr *icmp_packet; + struct ethhdr *ethhdr; +@@ -801,6 +803,9 @@ static int recv_my_icmp_packet(struct sk + return NET_RX_DROP; + } + ++ if (!bat_priv->primary_if) ++ return NET_RX_DROP; ++ + /* answer echo request (ping) */ + /* get routing information */ + spin_lock_irqsave(&orig_hash_lock, flags); +@@ -830,7 +835,8 @@ static int recv_my_icmp_packet(struct sk + } + + memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); +- memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); ++ memcpy(icmp_packet->orig, ++ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + icmp_packet->msg_type = ECHO_REPLY; + icmp_packet->ttl = TTL; + +@@ -845,6 +851,8 @@ static int recv_my_icmp_packet(struct sk + + static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) + { ++ /* FIXME: each batman_if will be attached to a softif */ ++ struct bat_priv *bat_priv = netdev_priv(soft_device); + struct orig_node *orig_node; + struct icmp_packet *icmp_packet; + struct ethhdr *ethhdr; +@@ -865,6 +873,9 @@ static int recv_icmp_ttl_exceeded(struct + return NET_RX_DROP; + } + ++ if (!bat_priv->primary_if) ++ return NET_RX_DROP; ++ + /* get routing information */ + spin_lock_irqsave(&orig_hash_lock, flags); + orig_node = ((struct orig_node *) +@@ -892,7 +903,8 @@ static int recv_icmp_ttl_exceeded(struct + } + + memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); +- memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); ++ memcpy(icmp_packet->orig, ++ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + icmp_packet->msg_type = TTL_EXCEEDED; + icmp_packet->ttl = TTL; + diff --git a/staging.current/staging-batman-adv-create-batman_if-only-on-register-event.patch b/staging.current/staging-batman-adv-create-batman_if-only-on-register-event.patch new file mode 100644 index 00000000000000..7dc016b9b44296 --- /dev/null +++ b/staging.current/staging-batman-adv-create-batman_if-only-on-register-event.patch @@ -0,0 +1,47 @@ +From sven.eckelmann@gmx.de Mon Aug 23 10:02:47 2010 +From: Sven Eckelmann <sven.eckelmann@gmx.de> +To: greg@kroah.com +Cc: b.a.t.m.a.n@lists.open-mesh.net, + Sven Eckelmann <sven.eckelmann@gmx.de>, + stable <stable@kernel.org> +Subject: Staging: batman-adv: Create batman_if only on register event +Date: Sat, 21 Aug 2010 14:18:08 +0200 +Message-Id: <1282393090-27411-2-git-send-email-sven.eckelmann@gmx.de> + +We try to get all events for all net_devices to be able to add special +sysfs folders for the batman-adv configuration. This also includes such +events like NETDEV_POST_INIT which has no valid kobject according to +v2.6.32-rc3-13-g7ffbe3f. This would create an oops in that situation. + +It is enough to create the batman_if only on NETDEV_REGISTER events +because we will also receive those events for devices which already +existed when we registered the notifier call. + +Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/batman-adv/hard-interface.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/staging/batman-adv/hard-interface.c ++++ b/drivers/staging/batman-adv/hard-interface.c +@@ -393,15 +393,13 @@ static int hard_if_event(struct notifier + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); + +- if (!batman_if) +- batman_if = hardif_add_interface(net_dev); ++ if (!batman_if && event == NETDEV_REGISTER) ++ batman_if = hardif_add_interface(net_dev); + + if (!batman_if) + goto out; + + switch (event) { +- case NETDEV_REGISTER: +- break; + case NETDEV_UP: + hardif_activate_interface(soft_device, bat_priv, batman_if); + break; diff --git a/staging.current/staging-batman-adv-don-t-use-net_dev-after-dev_put.patch b/staging.current/staging-batman-adv-don-t-use-net_dev-after-dev_put.patch new file mode 100644 index 00000000000000..bdf4055b6faddb --- /dev/null +++ b/staging.current/staging-batman-adv-don-t-use-net_dev-after-dev_put.patch @@ -0,0 +1,81 @@ +From sven.eckelmann@gmx.de Mon Aug 23 10:03:12 2010 +From: Sven Eckelmann <sven.eckelmann@gmx.de> +To: greg@kroah.com +Cc: b.a.t.m.a.n@lists.open-mesh.net, + Sven Eckelmann <sven.eckelmann@gmx.de>, + stable <stable@kernel.org> +Subject: Staging: batman-adv: Don't use net_dev after dev_put +Date: Sat, 21 Aug 2010 14:18:09 +0200 +Message-Id: <1282393090-27411-3-git-send-email-sven.eckelmann@gmx.de> + +dev_put allows a device to be freed when all its references are dropped. +After that we are not allowed to access that information anymore. Access +to the data structure of a net_device must be surrounded a dev_hold +and ended using dev_put. + +batman-adv adds a device to its own management structure in +hardif_add_interface and will release it in hardif_remove_interface. +Thus it must hold a reference all the time between those functions to +prevent any access to the already released net_device structure. + +Reported-by: Tim Glaremin <Tim.Glaremin@web.de> +Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/batman-adv/hard-interface.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/staging/batman-adv/hard-interface.c ++++ b/drivers/staging/batman-adv/hard-interface.c +@@ -194,8 +194,6 @@ static void hardif_activate_interface(st + if (batman_if->if_status != IF_INACTIVE) + return; + +- dev_hold(batman_if->net_dev); +- + update_mac_addresses(batman_if); + batman_if->if_status = IF_TO_BE_ACTIVATED; + +@@ -222,8 +220,6 @@ static void hardif_deactivate_interface( + (batman_if->if_status != IF_TO_BE_ACTIVATED)) + return; + +- dev_put(batman_if->net_dev); +- + batman_if->if_status = IF_INACTIVE; + + bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev); +@@ -318,11 +314,13 @@ static struct batman_if *hardif_add_inte + if (ret != 1) + goto out; + ++ dev_hold(net_dev); ++ + batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); + if (!batman_if) { + pr_err("Can't add interface (%s): out of memory\n", + net_dev->name); +- goto out; ++ goto release_dev; + } + + batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); +@@ -346,6 +344,8 @@ free_dev: + kfree(batman_if->dev); + free_if: + kfree(batman_if); ++release_dev: ++ dev_put(net_dev); + out: + return NULL; + } +@@ -374,6 +374,7 @@ static void hardif_remove_interface(stru + batman_if->if_status = IF_TO_BE_REMOVED; + list_del_rcu(&batman_if->list); + sysfs_del_hardif(&batman_if->hardif_obj); ++ dev_put(batman_if->net_dev); + call_rcu(&batman_if->rcu, hardif_free_interface); + } + diff --git a/staging.current/staging-batman-adv-don-t-write-in-not-allocated-packet_buff.patch b/staging.current/staging-batman-adv-don-t-write-in-not-allocated-packet_buff.patch new file mode 100644 index 00000000000000..f93273efee9889 --- /dev/null +++ b/staging.current/staging-batman-adv-don-t-write-in-not-allocated-packet_buff.patch @@ -0,0 +1,54 @@ +From sven.eckelmann@gmx.de Mon Aug 23 10:03:36 2010 +From: Sven Eckelmann <sven.eckelmann@gmx.de> +To: greg@kroah.com +Cc: b.a.t.m.a.n@lists.open-mesh.net, + Sven Eckelmann <sven.eckelmann@gmx.de>, + stable <stable@kernel.org> +Subject: Staging: batman-adv: Don't write in not allocated packet_buff +Date: Sat, 21 Aug 2010 14:18:10 +0200 +Message-Id: <1282393090-27411-4-git-send-email-sven.eckelmann@gmx.de> + +Each net_device in a system will automatically managed as a possible +batman_if and holds different informations like a buffer with a prepared +originator messages. To reduce the memory usage, the packet_buff will +only be allocated when the interface is really added/enabled for +batman-adv. + +The function to update the hw address information inside the packet_buff +just assumes that the packet_buff is always initialised and thus the +kernel will just oops when we try to change the hw address of a not +already fully enabled interface. + +We must always check if the packet_buff is allocated before we try to +change information inside of it. + +Reported-by: Tim Glaremin <Tim.Glaremin@web.de> +Reported-by: Kazuki Shimada <zukky@bb.banban.jp> +Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/batman-adv/hard-interface.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/staging/batman-adv/hard-interface.c ++++ b/drivers/staging/batman-adv/hard-interface.c +@@ -129,6 +129,9 @@ static bool hardif_is_iface_up(struct ba + + static void update_mac_addresses(struct batman_if *batman_if) + { ++ if (!batman_if || !batman_if->packet_buff) ++ return; ++ + addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); + + memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, +@@ -334,6 +337,7 @@ static struct batman_if *hardif_add_inte + batman_if->if_num = -1; + batman_if->net_dev = net_dev; + batman_if->if_status = IF_NOT_IN_USE; ++ batman_if->packet_buff = NULL; + INIT_LIST_HEAD(&batman_if->list); + + check_known_mac_addr(batman_if->net_dev->dev_addr); diff --git a/staging.current/staging-batman-adv-fix-batman-icmp-originating-from-secondary-interface.patch b/staging.current/staging-batman-adv-fix-batman-icmp-originating-from-secondary-interface.patch new file mode 100644 index 00000000000000..13b5a0fd1b1253 --- /dev/null +++ b/staging.current/staging-batman-adv-fix-batman-icmp-originating-from-secondary-interface.patch @@ -0,0 +1,90 @@ +From sven.eckelmann@gmx.de Mon Aug 23 10:01:18 2010 +From: Marek Lindner <lindner_marek@yahoo.de> +To: greg@kroah.com +Cc: b.a.t.m.a.n@lists.open-mesh.net, + Marek Lindner <lindner_marek@yahoo.de>, + Sven Eckelmann <sven.eckelmann@gmx.de> +Subject: Staging: batman-adv: fix batman icmp originating from secondary interface +Date: Mon, 9 Aug 2010 23:56:40 +0200 +Message-Id: <1281391002-21577-4-git-send-email-sven.eckelmann@gmx.de> + +From: Marek Lindner <lindner_marek@yahoo.de> + +If a batman icmp packet had to be routed over a secondary interface +at the first hop, the mac address of that secondary interface would +be written in the 'orig' field of the icmp packet. A node which is +more than one hop away is not aware of the mac address because +secondary interfaces are not flooded through the whole mesh and +therefore can't send a reply. +This patch always sends the mac address of the primary interface +in the 'orig' field of the icmp packet. + +Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> +Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/batman-adv/icmp_socket.c | 12 ++++++++---- + drivers/staging/batman-adv/types.h | 1 + + 2 files changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/staging/batman-adv/icmp_socket.c ++++ b/drivers/staging/batman-adv/icmp_socket.c +@@ -67,6 +67,7 @@ static int bat_socket_open(struct inode + INIT_LIST_HEAD(&socket_client->queue_list); + socket_client->queue_len = 0; + socket_client->index = i; ++ socket_client->bat_priv = inode->i_private; + spin_lock_init(&socket_client->lock); + init_waitqueue_head(&socket_client->queue_wait); + +@@ -151,9 +152,8 @@ static ssize_t bat_socket_read(struct fi + static ssize_t bat_socket_write(struct file *file, const char __user *buff, + size_t len, loff_t *off) + { +- /* FIXME: each orig_node->batman_if will be attached to a softif */ +- struct bat_priv *bat_priv = netdev_priv(soft_device); + struct socket_client *socket_client = file->private_data; ++ struct bat_priv *bat_priv = socket_client->bat_priv; + struct icmp_packet_rr icmp_packet; + struct orig_node *orig_node; + struct batman_if *batman_if; +@@ -168,6 +168,9 @@ static ssize_t bat_socket_write(struct f + return -EINVAL; + } + ++ if (!bat_priv->primary_if) ++ return -EFAULT; ++ + if (len >= sizeof(struct icmp_packet_rr)) + packet_len = sizeof(struct icmp_packet_rr); + +@@ -223,7 +226,8 @@ static ssize_t bat_socket_write(struct f + if (batman_if->if_status != IF_ACTIVE) + goto dst_unreach; + +- memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN); ++ memcpy(icmp_packet.orig, ++ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + + if (packet_len == sizeof(struct icmp_packet_rr)) + memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN); +@@ -271,7 +275,7 @@ int bat_socket_setup(struct bat_priv *ba + goto err; + + d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, +- bat_priv->debug_dir, NULL, &fops); ++ bat_priv->debug_dir, bat_priv, &fops); + if (d) + goto err; + +--- a/drivers/staging/batman-adv/types.h ++++ b/drivers/staging/batman-adv/types.h +@@ -126,6 +126,7 @@ struct socket_client { + unsigned char index; + spinlock_t lock; + wait_queue_head_t queue_wait; ++ struct bat_priv *bat_priv; + }; + + struct socket_packet { diff --git a/staging.current/staging-batman-adv-fix-merge-of-linus-tree.patch b/staging.current/staging-batman-adv-fix-merge-of-linus-tree.patch new file mode 100644 index 00000000000000..2e182b2e05a480 --- /dev/null +++ b/staging.current/staging-batman-adv-fix-merge-of-linus-tree.patch @@ -0,0 +1,59 @@ +From sven.eckelmann@gmx.de Mon Aug 23 10:00:17 2010 +From: Sven Eckelmann <sven.eckelmann@gmx.de> +To: greg@kroah.com +Cc: b.a.t.m.a.n@lists.open-mesh.net, + Sven Eckelmann <sven.eckelmann@gmx.de> +Subject: Staging: batman-adv: Fix merge of linus tree +Date: Mon, 9 Aug 2010 23:56:38 +0200 +Message-Id: <1281391002-21577-2-git-send-email-sven.eckelmann@gmx.de> + +Greg Kroah-Hartman merged Linus 2.6.36 tree in +e9563355ac1175dd3440dc2ea5c28b27ed51a283 with his staging tree. +Different parts of the merge conflicts were resolved incorrectly and may +result in an abnormal behavior. + +Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/batman-adv/bat_sysfs.c | 4 ++++ + drivers/staging/batman-adv/hard-interface.c | 8 -------- + 2 files changed, 4 insertions(+), 8 deletions(-) + +--- a/drivers/staging/batman-adv/bat_sysfs.c ++++ b/drivers/staging/batman-adv/bat_sysfs.c +@@ -267,6 +267,10 @@ static ssize_t store_log_level(struct ko + if (atomic_read(&bat_priv->log_level) == log_level_tmp) + return count; + ++ bat_info(net_dev, "Changing log level from: %i to: %li\n", ++ atomic_read(&bat_priv->log_level), ++ log_level_tmp); ++ + atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp); + return count; + } +--- a/drivers/staging/batman-adv/hard-interface.c ++++ b/drivers/staging/batman-adv/hard-interface.c +@@ -442,8 +442,6 @@ int batman_skb_recv(struct sk_buff *skb, + struct bat_priv *bat_priv = netdev_priv(soft_device); + struct batman_packet *batman_packet; + struct batman_if *batman_if; +- struct net_device_stats *stats; +- struct rtnl_link_stats64 temp; + int ret; + + skb = skb_share_check(skb, GFP_ATOMIC); +@@ -479,12 +477,6 @@ int batman_skb_recv(struct sk_buff *skb, + if (batman_if->if_status != IF_ACTIVE) + goto err_free; + +- stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp); +- if (stats) { +- stats->rx_packets++; +- stats->rx_bytes += skb->len; +- } +- + batman_packet = (struct batman_packet *)skb->data; + + if (batman_packet->version != COMPAT_VERSION) { diff --git a/staging.current/staging-batman-adv-fix-own-mac-address-detection.patch b/staging.current/staging-batman-adv-fix-own-mac-address-detection.patch new file mode 100644 index 00000000000000..108c36de225150 --- /dev/null +++ b/staging.current/staging-batman-adv-fix-own-mac-address-detection.patch @@ -0,0 +1,43 @@ +From sven.eckelmann@gmx.de Mon Aug 23 10:02:21 2010 +From: Marek Lindner <lindner_marek@yahoo.de> +To: greg@kroah.com +Cc: b.a.t.m.a.n@lists.open-mesh.net, + Marek Lindner <lindner_marek@yahoo.de>, + Sven Eckelmann <sven.eckelmann@gmx.de> +Subject: Staging: batman-adv: fix own mac address detection +Date: Mon, 9 Aug 2010 23:56:42 +0200 +Message-Id: <1281391002-21577-6-git-send-email-sven.eckelmann@gmx.de> + +From: Marek Lindner <lindner_marek@yahoo.de> + +Earlier batman-adv versions would only create a batman_if struct after +a corresponding interface had been activated by a user. Now each +existing system interface has a batman_if struct and has to be checked +by verifying the IF_ACTIVE flag. + +Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> +Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/batman-adv/main.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/staging/batman-adv/main.c ++++ b/drivers/staging/batman-adv/main.c +@@ -250,10 +250,13 @@ int choose_orig(void *data, int32_t size + int is_my_mac(uint8_t *addr) + { + struct batman_if *batman_if; ++ + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { +- if ((batman_if->net_dev) && +- (compare_orig(batman_if->net_dev->dev_addr, addr))) { ++ if (batman_if->if_status != IF_ACTIVE) ++ continue; ++ ++ if (compare_orig(batman_if->net_dev->dev_addr, addr)) { + rcu_read_unlock(); + return 1; + } diff --git a/staging.current/staging-batman-adv-unify-orig_hash_lock-spinlock-handling-to-avoid-deadlocks.patch b/staging.current/staging-batman-adv-unify-orig_hash_lock-spinlock-handling-to-avoid-deadlocks.patch new file mode 100644 index 00000000000000..c3f1efb586c13b --- /dev/null +++ b/staging.current/staging-batman-adv-unify-orig_hash_lock-spinlock-handling-to-avoid-deadlocks.patch @@ -0,0 +1,85 @@ +From sven.eckelmann@gmx.de Mon Aug 23 10:00:38 2010 +From: Marek Lindner <lindner_marek@yahoo.de> +To: greg@kroah.com +Cc: b.a.t.m.a.n@lists.open-mesh.net, + Marek Lindner <lindner_marek@yahoo.de>, + Sven Eckelmann <sven.eckelmann@gmx.de>, + stable <stable@kernel.org> +Subject: Staging: batman-adv: unify orig_hash_lock spinlock handling to avoid deadlocks +Date: Mon, 9 Aug 2010 23:56:39 +0200 +Message-Id: <1281391002-21577-3-git-send-email-sven.eckelmann@gmx.de> + +From: Marek Lindner <lindner_marek@yahoo.de> + +The orig_hash_lock spinlock always has to be locked with IRQs being +disabled to avoid deadlocks between code that is being executed in +IRQ context and code that is being executed in non-IRQ context. + +Reported-by: Sven Eckelmann <sven.eckelmann@gmx.de> +Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> +Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/batman-adv/originator.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/staging/batman-adv/originator.c ++++ b/drivers/staging/batman-adv/originator.c +@@ -391,11 +391,12 @@ static int orig_node_add_if(struct orig_ + int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) + { + struct orig_node *orig_node; ++ unsigned long flags; + HASHIT(hashit); + + /* resize all orig nodes because orig_node->bcast_own(_sum) depend on + * if_num */ +- spin_lock(&orig_hash_lock); ++ spin_lock_irqsave(&orig_hash_lock, flags); + + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; +@@ -404,11 +405,11 @@ int orig_hash_add_if(struct batman_if *b + goto err; + } + +- spin_unlock(&orig_hash_lock); ++ spin_unlock_irqrestore(&orig_hash_lock, flags); + return 0; + + err: +- spin_unlock(&orig_hash_lock); ++ spin_unlock_irqrestore(&orig_hash_lock, flags); + return -ENOMEM; + } + +@@ -468,12 +469,13 @@ int orig_hash_del_if(struct batman_if *b + { + struct batman_if *batman_if_tmp; + struct orig_node *orig_node; ++ unsigned long flags; + HASHIT(hashit); + int ret; + + /* resize all orig nodes because orig_node->bcast_own(_sum) depend on + * if_num */ +- spin_lock(&orig_hash_lock); ++ spin_lock_irqsave(&orig_hash_lock, flags); + + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; +@@ -500,10 +502,10 @@ int orig_hash_del_if(struct batman_if *b + rcu_read_unlock(); + + batman_if->if_num = -1; +- spin_unlock(&orig_hash_lock); ++ spin_unlock_irqrestore(&orig_hash_lock, flags); + return 0; + + err: +- spin_unlock(&orig_hash_lock); ++ spin_unlock_irqrestore(&orig_hash_lock, flags); + return -ENOMEM; + } |
