Re: [B.A.T.M.A.N.] [PATCHv3] batman-adv: postpone sysfs removal when unregistering

2013-01-12 Thread Marek Lindner
On Friday, January 11, 2013 17:19:51 Simon Wunderlich wrote:
 When processing the unregister notify for a hard interface, removing
 the sysfs files may lead to a circular deadlock (rtnl mutex -
 s_active).
 
 To overcome this problem, postpone the sysfs removal in a worker.
 
 Reported-by: Sasha Levin sasha.le...@oracle.com
 Reported-by: Sven Eckelmann s...@narfation.org
 Signed-off-by: Simon Wunderlich s...@hrz.tu-chemnitz.de
 ---
 Changes from PATCHv2:
  * kerneldoc for functions
 
 Changes from PATCHv1:
  * INIT_WORK() in respective struct initialization functions
  * kerneldoc
 
 Changes from RFCv1:
  * use work_struct properly, instead of delayed_work
  * postpone for softifs as well as for hardifs
 
 Postponing the sysfs removal for the hardif unregister is easier than
 other alternatives involving deferring. This should bring us to the
 same level to the bridge code, which also messes with sysfs in the
 notifier processing function, and uses rtnl_trylock when called
 from within sysfs.
 
 As far as I could understand the net/core code, only the unregister
 case is the critical one, so the original bug should hopefully be
 fixed.
 ---
  hard-interface.c |   24 ++--
  soft-interface.c |   32 +---
  types.h  |6 ++
  3 files changed, 57 insertions(+), 5 deletions(-)

Applied in revision a33c882.

Thanks,
Marek


[B.A.T.M.A.N.] [PATCH] batman-adv: replace redudant primary_if_get calls

2013-01-12 Thread Marek Lindner
The batadv_priv struct carries a pointer to its own interface
struct. Therefore, it is not necessary to retrieve the soft_iface
via the primary interface.

Signed-off-by: Marek Lindner lindner_ma...@yahoo.de
---
 distributed-arp-table.c |   22 --
 sysfs.c |   10 +-
 translation-table.c |   25 ++---
 3 files changed, 11 insertions(+), 46 deletions(-)

diff --git a/distributed-arp-table.c b/distributed-arp-table.c
index 7485a78..71c4f53 100644
--- a/distributed-arp-table.c
+++ b/distributed-arp-table.c
@@ -804,7 +804,6 @@ bool batadv_dat_snoop_outgoing_arp_request(struct 
batadv_priv *bat_priv,
bool ret = false;
struct batadv_dat_entry *dat_entry = NULL;
struct sk_buff *skb_new;
-   struct batadv_hard_iface *primary_if = NULL;
 
if (!atomic_read(bat_priv-distributed_arp_table))
goto out;
@@ -826,22 +825,18 @@ bool batadv_dat_snoop_outgoing_arp_request(struct 
batadv_priv *bat_priv,
 
dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
if (dat_entry) {
-   primary_if = batadv_primary_if_get_selected(bat_priv);
-   if (!primary_if)
-   goto out;
-
skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
-primary_if-soft_iface, ip_dst, hw_src,
+bat_priv-soft_iface, ip_dst, hw_src,
 dat_entry-mac_addr, hw_src);
if (!skb_new)
goto out;
 
skb_reset_mac_header(skb_new);
skb_new-protocol = eth_type_trans(skb_new,
-  primary_if-soft_iface);
+  bat_priv-soft_iface);
bat_priv-stats.rx_packets++;
bat_priv-stats.rx_bytes += skb-len + ETH_HLEN;
-   primary_if-soft_iface-last_rx = jiffies;
+   bat_priv-soft_iface-last_rx = jiffies;
 
netif_rx(skb_new);
batadv_dbg(BATADV_DBG_DAT, bat_priv, ARP request replied 
locally\n);
@@ -854,8 +849,6 @@ bool batadv_dat_snoop_outgoing_arp_request(struct 
batadv_priv *bat_priv,
 out:
if (dat_entry)
batadv_dat_entry_free_ref(dat_entry);
-   if (primary_if)
-   batadv_hardif_free_ref(primary_if);
return ret;
 }
 
@@ -875,7 +868,6 @@ bool batadv_dat_snoop_incoming_arp_request(struct 
batadv_priv *bat_priv,
__be32 ip_src, ip_dst;
uint8_t *hw_src;
struct sk_buff *skb_new;
-   struct batadv_hard_iface *primary_if = NULL;
struct batadv_dat_entry *dat_entry = NULL;
bool ret = false;
int err;
@@ -900,12 +892,8 @@ bool batadv_dat_snoop_incoming_arp_request(struct 
batadv_priv *bat_priv,
if (!dat_entry)
goto out;
 
-   primary_if = batadv_primary_if_get_selected(bat_priv);
-   if (!primary_if)
-   goto out;
-
skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
-primary_if-soft_iface, ip_dst, hw_src,
+bat_priv-soft_iface, ip_dst, hw_src,
 dat_entry-mac_addr, hw_src);
 
if (!skb_new)
@@ -929,8 +917,6 @@ bool batadv_dat_snoop_incoming_arp_request(struct 
batadv_priv *bat_priv,
 out:
if (dat_entry)
batadv_dat_entry_free_ref(dat_entry);
-   if (primary_if)
-   batadv_hardif_free_ref(primary_if);
if (ret)
kfree_skb(skb);
return ret;
diff --git a/sysfs.c b/sysfs.c
index afbba31..6a44fed 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -688,15 +688,10 @@ int batadv_throw_uevent(struct batadv_priv *bat_priv, 
enum batadv_uev_type type,
enum batadv_uev_action action, const char *data)
 {
int ret = -ENOMEM;
-   struct batadv_hard_iface *primary_if;
struct kobject *bat_kobj;
char *uevent_env[4] = { NULL, NULL, NULL, NULL };
 
-   primary_if = batadv_primary_if_get_selected(bat_priv);
-   if (!primary_if)
-   goto out;
-
-   bat_kobj = primary_if-soft_iface-dev.kobj;
+   bat_kobj = bat_priv-soft_iface-dev.kobj;
 
uevent_env[0] = kmalloc(strlen(BATADV_UEV_TYPE_VAR) +
strlen(batadv_uev_type_str[type]) + 1,
@@ -732,9 +727,6 @@ out:
kfree(uevent_env[1]);
kfree(uevent_env[2]);
 
-   if (primary_if)
-   batadv_hardif_free_ref(primary_if);
-
if (ret)
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
   Impossible to send uevent for (%s,%s,%s) event 
(err: %d)\n,
diff --git a/translation-table.c b/translation-table.c
index fb15b4c..607fd3c 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -387,25 +387,19 @@ static void batadv_tt_prepare_packet_buff(struct 
batadv_priv