The following commit has been merged in the merge/master branch:
commit 8771ce195840bc65854d4491d9c0720b7ea5f2a6
Merge: 289e386bcec0d469fc629019b349f47d17789911 22d98bd45c01e978c9ae439b7d9d1f3c3c65b102
Author: Marek Lindner <mareklindner(a)neomailbox.ch>
Date: Tue Apr 12 00:00:10 2016 +0800
Merge branch 'maint' into next
diff --combined net/batman-adv/distributed-arp-table.c
index e96d7c7,0e57221..3e6b262
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@@ -1,4 -1,4 +1,4 @@@
-/* Copyright (C) 2011-2015 B.A.T.M.A.N. contributors:
+/* Copyright (C) 2011-2016 B.A.T.M.A.N. contributors:
*
* Antonio Quartulli
*
@@@ -30,7 -30,6 +30,7 @@@
#include <linux/in.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
+#include <linux/kref.h>
#include <linux/list.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
@@@ -63,27 -62,14 +63,27 @@@ static void batadv_dat_start_timer(stru
}
/**
- * batadv_dat_entry_free_ref - decrement the dat_entry refcounter and possibly
- * free it
- * @dat_entry: the entry to free
+ * batadv_dat_entry_release - release dat_entry from lists and queue for free
+ * after rcu grace period
+ * @ref: kref pointer of the dat_entry
*/
-static void batadv_dat_entry_free_ref(struct batadv_dat_entry *dat_entry)
+static void batadv_dat_entry_release(struct kref *ref)
{
- if (atomic_dec_and_test(&dat_entry->refcount))
- kfree_rcu(dat_entry, rcu);
+ struct batadv_dat_entry *dat_entry;
+
+ dat_entry = container_of(ref, struct batadv_dat_entry, refcount);
+
+ kfree_rcu(dat_entry, rcu);
+}
+
+/**
+ * batadv_dat_entry_put - decrement the dat_entry refcounter and possibly
+ * release it
+ * @dat_entry: dat_entry to be free'd
+ */
+static void batadv_dat_entry_put(struct batadv_dat_entry *dat_entry)
+{
+ kref_put(&dat_entry->refcount, batadv_dat_entry_release);
}
/**
@@@ -135,7 -121,7 +135,7 @@@ static void __batadv_dat_purge(struct b
continue;
hlist_del_rcu(&dat_entry->hash_entry);
- batadv_dat_entry_free_ref(dat_entry);
+ batadv_dat_entry_put(dat_entry);
}
spin_unlock_bh(list_lock);
}
@@@ -295,7 -281,7 +295,7 @@@ batadv_dat_entry_hash_find(struct batad
if (dat_entry->ip != ip)
continue;
- if (!atomic_inc_not_zero(&dat_entry->refcount))
+ if (!kref_get_unless_zero(&dat_entry->refcount))
continue;
dat_entry_tmp = dat_entry;
@@@ -340,8 -326,7 +340,8 @@@ static void batadv_dat_entry_add(struc
dat_entry->vid = vid;
ether_addr_copy(dat_entry->mac_addr, mac_addr);
dat_entry->last_update = jiffies;
- atomic_set(&dat_entry->refcount, 2);
+ kref_init(&dat_entry->refcount);
+ kref_get(&dat_entry->refcount);
hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat,
batadv_hash_dat, dat_entry,
@@@ -349,7 -334,7 +349,7 @@@
if (unlikely(hash_added != 0)) {
/* remove the reference for the hash */
- batadv_dat_entry_free_ref(dat_entry);
+ batadv_dat_entry_put(dat_entry);
goto out;
}
@@@ -358,7 -343,7 +358,7 @@@
out:
if (dat_entry)
- batadv_dat_entry_free_ref(dat_entry);
+ batadv_dat_entry_put(dat_entry);
}
#ifdef CONFIG_BATMAN_ADV_DEBUG
@@@ -542,12 -527,12 +542,12 @@@ static void batadv_choose_next_candidat
max_orig_node))
continue;
- if (!atomic_inc_not_zero(&orig_node->refcount))
+ if (!kref_get_unless_zero(&orig_node->refcount))
continue;
max = tmp_max;
if (max_orig_node)
- batadv_orig_node_free_ref(max_orig_node);
+ batadv_orig_node_put(max_orig_node);
max_orig_node = orig_node;
}
rcu_read_unlock();
@@@ -568,6 -553,7 +568,7 @@@
* be sent to
* @bat_priv: the bat priv with all the soft interface information
* @ip_dst: ipv4 to look up in the DHT
+ * @vid: VLAN identifier
*
* An originator O is selected if and only if its DHT_ID value is one of three
* closest values (from the LEFT, with wrap around if needed) then the hash
@@@ -576,7 -562,8 +577,8 @@@
* Return: the candidate array of size BATADV_DAT_CANDIDATE_NUM.
*/
static struct batadv_dat_candidate *
- batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
+ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst,
+ unsigned short vid)
{
int select;
batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key;
@@@ -592,7 -579,7 +594,7 @@@
return NULL;
dat.ip = ip_dst;
- dat.vid = 0;
+ dat.vid = vid;
ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat,
BATADV_DAT_ADDR_MAX);
@@@ -612,6 -599,7 +614,7 @@@
* @bat_priv: the bat priv with all the soft interface information
* @skb: payload to send
* @ip: the DHT key
+ * @vid: VLAN identifier
* @packet_subtype: unicast4addr packet subtype to use
*
* This function copies the skb with pskb_copy() and is sent as unicast packet
@@@ -622,7 -610,7 +625,7 @@@
*/
static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
struct sk_buff *skb, __be32 ip,
- int packet_subtype)
+ unsigned short vid, int packet_subtype)
{
int i;
bool ret = false;
@@@ -631,7 -619,7 +634,7 @@@
struct sk_buff *tmp_skb;
struct batadv_dat_candidate *cand;
- cand = batadv_dat_select_candidates(bat_priv, ip);
+ cand = batadv_dat_select_candidates(bat_priv, ip, vid);
if (!cand)
goto out;
@@@ -654,7 -642,9 +657,7 @@@
goto free_neigh;
}
- send_status = batadv_send_skb_packet(tmp_skb,
- neigh_node->if_incoming,
- neigh_node->addr);
+ send_status = batadv_send_unicast_skb(tmp_skb, neigh_node);
if (send_status == NET_XMIT_SUCCESS) {
/* count the sent packet */
switch (packet_subtype) {
@@@ -672,9 -662,9 +675,9 @@@
ret = true;
}
free_neigh:
- batadv_neigh_node_free_ref(neigh_node);
+ batadv_neigh_node_put(neigh_node);
free_orig:
- batadv_orig_node_free_ref(cand[i].orig_node);
+ batadv_orig_node_put(cand[i].orig_node);
}
out:
@@@ -838,7 -828,7 +841,7 @@@ int batadv_dat_cache_seq_print_text(str
out:
if (primary_if)
- batadv_hardif_free_ref(primary_if);
+ batadv_hardif_put(primary_if);
return 0;
}
@@@ -1022,12 -1012,12 +1025,12 @@@ bool batadv_dat_snoop_outgoing_arp_requ
ret = true;
} else {
/* Send the request to the DHT */
- ret = batadv_dat_send_data(bat_priv, skb, ip_dst,
+ ret = batadv_dat_send_data(bat_priv, skb, ip_dst, vid,
BATADV_P_DAT_DHT_GET);
}
out:
if (dat_entry)
- batadv_dat_entry_free_ref(dat_entry);
+ batadv_dat_entry_put(dat_entry);
return ret;
}
@@@ -1107,7 -1097,7 +1110,7 @@@ bool batadv_dat_snoop_incoming_arp_requ
}
out:
if (dat_entry)
- batadv_dat_entry_free_ref(dat_entry);
+ batadv_dat_entry_put(dat_entry);
if (ret)
kfree_skb(skb);
return ret;
@@@ -1150,8 -1140,8 +1153,8 @@@ void batadv_dat_snoop_outgoing_arp_repl
/* Send the ARP reply to the candidates for both the IP addresses that
* the node obtained from the ARP reply
*/
- batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT);
- batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT);
+ batadv_dat_send_data(bat_priv, skb, ip_src, vid, BATADV_P_DAT_DHT_PUT);
+ batadv_dat_send_data(bat_priv, skb, ip_dst, vid, BATADV_P_DAT_DHT_PUT);
}
/**
@@@ -1260,6 -1250,6 +1263,6 @@@ bool batadv_dat_drop_broadcast_packet(s
out:
if (dat_entry)
- batadv_dat_entry_free_ref(dat_entry);
+ batadv_dat_entry_put(dat_entry);
return ret;
}
--
linux integration