From: Linus Torvalds Date: Fri, 20 May 2011 20:43:21 +0000 (-0700) Subject: Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6 X-Git-Tag: v3.0-rc1~377 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06f4e926d256d902dd9a53dcb400fd74974ce087;p=pandora-kernel.git Merge git://git./linux/kernel/git/davem/net-next-2.6 * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits) macvlan: fix panic if lowerdev in a bond tg3: Add braces around 5906 workaround. tg3: Fix NETIF_F_LOOPBACK error macvlan: remove one synchronize_rcu() call networking: NET_CLS_ROUTE4 depends on INET irda: Fix error propagation in ircomm_lmp_connect_response() irda: Kill set but unused variable 'bytes' in irlan_check_command_param() irda: Kill set but unused variable 'clen' in ircomm_connect_indication() rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport() be2net: Kill set but unused variable 'req' in lancer_fw_download() irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication() atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined. rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer(). rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler() rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection() rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window() pkt_sched: Kill set but unused variable 'protocol' in tc_classify() isdn: capi: Use pr_debug() instead of ifdefs. tg3: Update version to 3.119 tg3: Apply rx_discards fix to 5719/5720 ... Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c as per Davem. --- 06f4e926d256d902dd9a53dcb400fd74974ce087 diff --cc arch/x86/Kconfig index 4168e5d8632a,2096cf180648..880fcb6c86f4 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@@ -72,6 -71,8 +72,7 @@@ config X8 select GENERIC_IRQ_SHOW select IRQ_FORCED_THREADING select USE_GENERIC_SMP_HELPERS if SMP - select ARCH_NO_SYSDEV_OPS + select HAVE_BPF_JIT if (X86_64 && NET) config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) diff --cc net/batman-adv/gateway_client.c index 150b6ce23df3,65f39530799d..61605a0f3f39 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@@ -31,25 -32,28 +32,20 @@@ static void gw_node_free_ref(struct gw_node *gw_node) { if (atomic_dec_and_test(&gw_node->refcount)) - call_rcu(&gw_node->rcu, gw_node_free_rcu); + kfree_rcu(gw_node, rcu); } - void *gw_get_selected(struct bat_priv *bat_priv) + static struct gw_node *gw_get_selected_gw_node(struct bat_priv *bat_priv) { - struct gw_node *curr_gateway_tmp; - struct orig_node *orig_node = NULL; + struct gw_node *gw_node; rcu_read_lock(); - curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw); - if (!curr_gateway_tmp) - goto out; - - orig_node = curr_gateway_tmp->orig_node; - if (!orig_node) + gw_node = rcu_dereference(bat_priv->curr_gw); + if (!gw_node) goto out; - if (!atomic_inc_not_zero(&orig_node->refcount)) - orig_node = NULL; + if (!atomic_inc_not_zero(&gw_node->refcount)) + gw_node = NULL; out: rcu_read_unlock(); diff --cc net/batman-adv/originator.c index ed23a5895d6c,080ec88330a3..40a30bbcd147 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@@ -59,9 -57,32 +57,24 @@@ err void neigh_node_free_ref(struct neigh_node *neigh_node) { if (atomic_dec_and_test(&neigh_node->refcount)) - call_rcu(&neigh_node->rcu, neigh_node_free_rcu); + kfree_rcu(neigh_node, rcu); } + /* increases the refcounter of a found router */ + struct neigh_node *orig_node_get_router(struct orig_node *orig_node) + { + struct neigh_node *router; + + rcu_read_lock(); + router = rcu_dereference(orig_node->router); + + if (router && !atomic_inc_not_zero(&router->refcount)) + router = NULL; + + rcu_read_unlock(); + return router; + } + struct neigh_node *create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, diff --cc net/batman-adv/soft-interface.c index 04efe022c13b,c76a33eeb3f1..d5aa60999e83 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@@ -79,40 -75,82 +75,74 @@@ int my_skb_head_push(struct sk_buff *sk static void softif_neigh_free_ref(struct softif_neigh *softif_neigh) { if (atomic_dec_and_test(&softif_neigh->refcount)) - call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); + kfree_rcu(softif_neigh, rcu); } - void softif_neigh_purge(struct bat_priv *bat_priv) + static void softif_neigh_vid_free_rcu(struct rcu_head *rcu) { - struct softif_neigh *softif_neigh, *softif_neigh_tmp; + struct softif_neigh_vid *softif_neigh_vid; + struct softif_neigh *softif_neigh; struct hlist_node *node, *node_tmp; + struct bat_priv *bat_priv; - spin_lock_bh(&bat_priv->softif_neigh_lock); + softif_neigh_vid = container_of(rcu, struct softif_neigh_vid, rcu); + bat_priv = softif_neigh_vid->bat_priv; + spin_lock_bh(&bat_priv->softif_neigh_lock); hlist_for_each_entry_safe(softif_neigh, node, node_tmp, - &bat_priv->softif_neigh_list, list) { + &softif_neigh_vid->softif_neigh_list, list) { + hlist_del_rcu(&softif_neigh->list); + softif_neigh_free_ref(softif_neigh); + } + spin_unlock_bh(&bat_priv->softif_neigh_lock); - if ((!time_after(jiffies, softif_neigh->last_seen + - msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) && - (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)) - continue; + kfree(softif_neigh_vid); + } - hlist_del_rcu(&softif_neigh->list); + static void softif_neigh_vid_free_ref(struct softif_neigh_vid *softif_neigh_vid) + { + if (atomic_dec_and_test(&softif_neigh_vid->refcount)) + call_rcu(&softif_neigh_vid->rcu, softif_neigh_vid_free_rcu); + } - if (bat_priv->softif_neigh == softif_neigh) { - bat_dbg(DBG_ROUTES, bat_priv, - "Current mesh exit point '%pM' vanished " - "(vid: %d).\n", - softif_neigh->addr, softif_neigh->vid); - softif_neigh_tmp = bat_priv->softif_neigh; - bat_priv->softif_neigh = NULL; - softif_neigh_free_ref(softif_neigh_tmp); - } + static struct softif_neigh_vid *softif_neigh_vid_get(struct bat_priv *bat_priv, + short vid) + { + struct softif_neigh_vid *softif_neigh_vid; + struct hlist_node *node; - softif_neigh_free_ref(softif_neigh); + rcu_read_lock(); + hlist_for_each_entry_rcu(softif_neigh_vid, node, + &bat_priv->softif_neigh_vids, list) { + if (softif_neigh_vid->vid != vid) + continue; + + if (!atomic_inc_not_zero(&softif_neigh_vid->refcount)) + continue; + + goto out; } - spin_unlock_bh(&bat_priv->softif_neigh_lock); + softif_neigh_vid = kzalloc(sizeof(struct softif_neigh_vid), + GFP_ATOMIC); + if (!softif_neigh_vid) + goto out; + + softif_neigh_vid->vid = vid; + softif_neigh_vid->bat_priv = bat_priv; + + /* initialize with 2 - caller decrements counter by one */ + atomic_set(&softif_neigh_vid->refcount, 2); + INIT_HLIST_HEAD(&softif_neigh_vid->softif_neigh_list); + INIT_HLIST_NODE(&softif_neigh_vid->list); + spin_lock_bh(&bat_priv->softif_neigh_vid_lock); + hlist_add_head_rcu(&softif_neigh_vid->list, + &bat_priv->softif_neigh_vids); + spin_unlock_bh(&bat_priv->softif_neigh_vid_lock); + + out: + rcu_read_unlock(); + return softif_neigh_vid; } static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, diff --cc net/mac80211/agg-tx.c index 53defafb9aae,cd5125f77cc5..c8be8eff70da --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@@ -136,6 -136,22 +136,14 @@@ void ieee80211_send_bar(struct ieee8021 ieee80211_tx_skb(sdata, skb); } + void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, + struct tid_ampdu_tx *tid_tx) + { + lockdep_assert_held(&sta->ampdu_mlme.mtx); + lockdep_assert_held(&sta->lock); + rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); + } + -static void kfree_tid_tx(struct rcu_head *rcu_head) -{ - struct tid_ampdu_tx *tid_tx = - container_of(rcu_head, struct tid_ampdu_tx, rcu_head); - - kfree(tid_tx); -} - int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, enum ieee80211_back_parties initiator, bool tx) @@@ -146,16 -162,19 +154,19 @@@ lockdep_assert_held(&sta->ampdu_mlme.mtx); - if (!tid_tx) - return -ENOENT; - spin_lock_bh(&sta->lock); + tid_tx = rcu_dereference_protected_tid_tx(sta, tid); + if (!tid_tx) { + spin_unlock_bh(&sta->lock); + return -ENOENT; + } + if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { /* not even started yet! */ - rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL); + ieee80211_assign_tid_tx(sta, tid, NULL); spin_unlock_bh(&sta->lock); - call_rcu(&tid_tx->rcu_head, kfree_tid_tx); + kfree_rcu(tid_tx, rcu_head); return 0; }