]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 13 Jun 2015 06:54:16 +0000 (20:54 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 13 Jun 2015 06:54:16 +0000 (20:54 -1000)
Pull networking fixes from David Miller:

 1) Fix uninitialized struct station_info in cfg80211_wireless_stats(),
    from Johannes Berg.

 2) Revert commit attempt to fix ipv6 protocol resubmission, it adds
    regressions.

 3) Endless loops can be created in bridge port lists, fix from Nikolay
    Aleksandrov.

 4) Don't WARN_ON() if sk->sk_forward_alloc is non-zero in
    sk_clear_memalloc, it is a legal situation during swap deactivation.
    Fix from Mel Gorman.

 5) Fix order of disabling interrupts and unlocking NAPI in enic driver
    to avoid a race.  From Govindarajulu Varadarajan.

 6) High and low register writes are swapped when programming the start
    of periodic output in igb driver.  From Richard Cochran.

 7) Fix device rename handling in mpls stack, from Robert Shearman.

 8) Do not trigger compaction synchronously when optimistically trying
    to allocate an order 3 page in alloc_skb_with_frags() and
    skb_page_frag_refill().  From Shaohua Li.

 9) Authentication with COOKIE_ECHO is not handled properly in SCTP, fix
    from Marcelo Ricardo Leitner.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  Doc: networking: Fix URL for wiki.wireshark.org in udplite.txt
  sctp: allow authenticating DATA chunks that are bundled with COOKIE_ECHO
  net: don't wait for order-3 page allocation
  mpls: handle device renames for per-device sysctls
  net: igb: fix the start time for periodic output signals
  enic: fix memory leak in rq_clean
  enic: check return value for stat dump
  enic: unlock napi busy poll before unmasking intr
  net, swap: Remove a warning and clarify why sk_mem_reclaim is required when deactivating swap
  bridge: fix multicast router rlist endless loop
  tipc: disconnect socket directly after probe failure
  Revert "ipv6: Fix protocol resubmission"
  cfg80211: wext: clear sinfo struct before calling driver

13 files changed:
Documentation/networking/udplite.txt
drivers/net/ethernet/cisco/enic/enic_ethtool.c
drivers/net/ethernet/cisco/enic/enic_main.c
drivers/net/ethernet/cisco/enic/vnic_rq.c
drivers/net/ethernet/intel/igb/igb_ptp.c
net/bridge/br_multicast.c
net/core/skbuff.c
net/core/sock.c
net/ipv6/ip6_input.c
net/mpls/af_mpls.c
net/sctp/auth.c
net/tipc/socket.c
net/wireless/wext-compat.c

index d727a38291005f962848ed40a1ab11db4c167899..53a726855e49bfa4c313e46e15df1eec7cb610ae 100644 (file)
@@ -20,7 +20,7 @@
        files/UDP-Lite-HOWTO.txt
 
    o The Wireshark UDP-Lite WiKi (with capture files):
-       http://wiki.wireshark.org/Lightweight_User_Datagram_Protocol
+       https://wiki.wireshark.org/Lightweight_User_Datagram_Protocol
 
    o The Protocol Spec, RFC 3828, http://www.ietf.org/rfc/rfc3828.txt
 
index 28d9ca675a274f9876473bcce7e6995a14e1289e..68d47b196daec3d3c5d0b8af19f8d167735e1e79 100644 (file)
@@ -131,8 +131,15 @@ static void enic_get_drvinfo(struct net_device *netdev,
 {
        struct enic *enic = netdev_priv(netdev);
        struct vnic_devcmd_fw_info *fw_info;
+       int err;
 
-       enic_dev_fw_info(enic, &fw_info);
+       err = enic_dev_fw_info(enic, &fw_info);
+       /* return only when pci_zalloc_consistent fails in vnic_dev_fw_info
+        * For other failures, like devcmd failure, we return previously
+        * recorded info.
+        */
+       if (err == -ENOMEM)
+               return;
 
        strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
        strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
@@ -181,8 +188,15 @@ static void enic_get_ethtool_stats(struct net_device *netdev,
        struct enic *enic = netdev_priv(netdev);
        struct vnic_stats *vstats;
        unsigned int i;
-
-       enic_dev_stats_dump(enic, &vstats);
+       int err;
+
+       err = enic_dev_stats_dump(enic, &vstats);
+       /* return only when pci_zalloc_consistent fails in vnic_dev_stats_dump
+        * For other failures, like devcmd failure, we return previously
+        * recorded stats.
+        */
+       if (err == -ENOMEM)
+               return;
 
        for (i = 0; i < enic_n_tx_stats; i++)
                *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].index];
index 204bd182473bceaaabaa5b1eba5ed618de751808..eadae1b412c652974dde24a9a76c5d74a8c3fa29 100644 (file)
@@ -615,8 +615,15 @@ static struct rtnl_link_stats64 *enic_get_stats(struct net_device *netdev,
 {
        struct enic *enic = netdev_priv(netdev);
        struct vnic_stats *stats;
+       int err;
 
-       enic_dev_stats_dump(enic, &stats);
+       err = enic_dev_stats_dump(enic, &stats);
+       /* return only when pci_zalloc_consistent fails in vnic_dev_stats_dump
+        * For other failures, like devcmd failure, we return previously
+        * recorded stats.
+        */
+       if (err == -ENOMEM)
+               return net_stats;
 
        net_stats->tx_packets = stats->tx.tx_frames_ok;
        net_stats->tx_bytes = stats->tx.tx_bytes_ok;
@@ -1407,6 +1414,7 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget)
                 */
                enic_calc_int_moderation(enic, &enic->rq[rq]);
 
+       enic_poll_unlock_napi(&enic->rq[rq]);
        if (work_done < work_to_do) {
 
                /* Some work done, but not enough to stay in polling,
@@ -1418,7 +1426,6 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget)
                        enic_set_int_moderation(enic, &enic->rq[rq]);
                vnic_intr_unmask(&enic->intr[intr]);
        }
-       enic_poll_unlock_napi(&enic->rq[rq]);
 
        return work_done;
 }
index 36a2ed606c911f21355360fad81eb39b18162c59..c4b2183bf352fb2a1881001777df91857c2d1f79 100644 (file)
@@ -188,16 +188,15 @@ void vnic_rq_clean(struct vnic_rq *rq,
        struct vnic_rq_buf *buf;
        u32 fetch_index;
        unsigned int count = rq->ring.desc_count;
+       int i;
 
        buf = rq->to_clean;
 
-       while (vnic_rq_desc_used(rq) > 0) {
-
+       for (i = 0; i < rq->ring.desc_count; i++) {
                (*buf_clean)(rq, buf);
-
-               buf = rq->to_clean = buf->next;
-               rq->ring.desc_avail++;
+               buf = buf->next;
        }
+       rq->ring.desc_avail = rq->ring.desc_count - 1;
 
        /* Use current fetch_index as the ring starting point */
        fetch_index = ioread32(&rq->ctrl->fetch_index);
index e3b9b63ad01083cb987429f57c9ebef84d86f4db..c3a9392cbc192229f4178c913fad8ab64d8c44c3 100644 (file)
@@ -538,8 +538,8 @@ static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp,
                        igb->perout[i].start.tv_nsec = rq->perout.start.nsec;
                        igb->perout[i].period.tv_sec = ts.tv_sec;
                        igb->perout[i].period.tv_nsec = ts.tv_nsec;
-                       wr32(trgttiml, rq->perout.start.sec);
-                       wr32(trgttimh, rq->perout.start.nsec);
+                       wr32(trgttimh, rq->perout.start.sec);
+                       wr32(trgttiml, rq->perout.start.nsec);
                        tsauxc |= tsauxc_mask;
                        tsim |= tsim_mask;
                } else {
index 22fd0419b31455965223566f4676b46efedd8722..ff667e18b2d6313f0a806752a4ef88435e939c4d 100644 (file)
@@ -1167,6 +1167,9 @@ static void br_multicast_add_router(struct net_bridge *br,
        struct net_bridge_port *p;
        struct hlist_node *slot = NULL;
 
+       if (!hlist_unhashed(&port->rlist))
+               return;
+
        hlist_for_each_entry(p, &br->router_list, rlist) {
                if ((unsigned long) port >= (unsigned long) p)
                        break;
@@ -1194,12 +1197,8 @@ static void br_multicast_mark_router(struct net_bridge *br,
        if (port->multicast_router != 1)
                return;
 
-       if (!hlist_unhashed(&port->rlist))
-               goto timer;
-
        br_multicast_add_router(br, port);
 
-timer:
        mod_timer(&port->multicast_router_timer,
                  now + br->multicast_querier_interval);
 }
index 3cfff2a3d651fb7d7cd2baaa3698c123eb7fc00f..41ec02242ea7c2ff57a6b506b685df22c62f3dcc 100644 (file)
@@ -4398,7 +4398,7 @@ struct sk_buff *alloc_skb_with_frags(unsigned long header_len,
 
                while (order) {
                        if (npages >= 1 << order) {
-                               page = alloc_pages(gfp_mask |
+                               page = alloc_pages((gfp_mask & ~__GFP_WAIT) |
                                                   __GFP_COMP |
                                                   __GFP_NOWARN |
                                                   __GFP_NORETRY,
index 292f42228bfb361b5748998bbcc538b1e16a2f22..dc30dc5bb1b892923397fee073d42e9e5ef53a7e 100644 (file)
@@ -354,15 +354,12 @@ void sk_clear_memalloc(struct sock *sk)
 
        /*
         * SOCK_MEMALLOC is allowed to ignore rmem limits to ensure forward
-        * progress of swapping. However, if SOCK_MEMALLOC is cleared while
-        * it has rmem allocations there is a risk that the user of the
-        * socket cannot make forward progress due to exceeding the rmem
-        * limits. By rights, sk_clear_memalloc() should only be called
-        * on sockets being torn down but warn and reset the accounting if
-        * that assumption breaks.
+        * progress of swapping. SOCK_MEMALLOC may be cleared while
+        * it has rmem allocations due to the last swapfile being deactivated
+        * but there is a risk that the socket is unusable due to exceeding
+        * the rmem limits. Reclaim the reserves and obey rmem limits again.
         */
-       if (WARN_ON(sk->sk_forward_alloc))
-               sk_mem_reclaim(sk);
+       sk_mem_reclaim(sk);
 }
 EXPORT_SYMBOL_GPL(sk_clear_memalloc);
 
@@ -1883,7 +1880,7 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t gfp)
 
        pfrag->offset = 0;
        if (SKB_FRAG_PAGE_ORDER) {
-               pfrag->page = alloc_pages(gfp | __GFP_COMP |
+               pfrag->page = alloc_pages((gfp & ~__GFP_WAIT) | __GFP_COMP |
                                          __GFP_NOWARN | __GFP_NORETRY,
                                          SKB_FRAG_PAGE_ORDER);
                if (likely(pfrag->page)) {
index 41a73da371a9230511f8c3e58351b3cf0034d1dc..f2e464eba5efdb7b2a8abe3c2cecedae473777e7 100644 (file)
@@ -212,13 +212,13 @@ static int ip6_input_finish(struct sock *sk, struct sk_buff *skb)
         */
 
        rcu_read_lock();
+resubmit:
        idev = ip6_dst_idev(skb_dst(skb));
        if (!pskb_pull(skb, skb_transport_offset(skb)))
                goto discard;
        nhoff = IP6CB(skb)->nhoff;
        nexthdr = skb_network_header(skb)[nhoff];
 
-resubmit:
        raw = raw6_local_deliver(skb, nexthdr);
        ipprot = rcu_dereference(inet6_protos[nexthdr]);
        if (ipprot) {
@@ -246,12 +246,10 @@ resubmit:
                        goto discard;
 
                ret = ipprot->handler(skb);
-               if (ret < 0) {
-                       nexthdr = -ret;
+               if (ret > 0)
                        goto resubmit;
-               } else if (ret == 0) {
+               else if (ret == 0)
                        IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS);
-               }
        } else {
                if (!raw) {
                        if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
index bff427f31924706f6e4b8b5259ae64f1dd932f7f..1f93a5978f2ad43fc81a16427e34d07ca2c0f34e 100644 (file)
@@ -564,6 +564,17 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event,
        case NETDEV_UNREGISTER:
                mpls_ifdown(dev);
                break;
+       case NETDEV_CHANGENAME:
+               mdev = mpls_dev_get(dev);
+               if (mdev) {
+                       int err;
+
+                       mpls_dev_sysctl_unregister(mdev);
+                       err = mpls_dev_sysctl_register(dev, mdev);
+                       if (err)
+                               return notifier_from_errno(err);
+               }
+               break;
        }
        return NOTIFY_OK;
 }
index fb7976aee61c84f38aecdc5c5f0d8be20e577fa9..4f15b7d730e13d6aaa58ba7a28262c9831afea95 100644 (file)
@@ -381,13 +381,14 @@ nomem:
 }
 
 
-/* Public interface to creat the association shared key.
+/* Public interface to create the association shared key.
  * See code above for the algorithm.
  */
 int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
 {
        struct sctp_auth_bytes  *secret;
        struct sctp_shared_key *ep_key;
+       struct sctp_chunk *chunk;
 
        /* If we don't support AUTH, or peer is not capable
         * we don't need to do anything.
@@ -410,6 +411,14 @@ int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
        sctp_auth_key_put(asoc->asoc_shared_key);
        asoc->asoc_shared_key = secret;
 
+       /* Update send queue in case any chunk already in there now
+        * needs authenticating
+        */
+       list_for_each_entry(chunk, &asoc->outqueue.out_chunk_list, list) {
+               if (sctp_auth_send_cid(chunk->chunk_hdr->type, asoc))
+                       chunk->auth = 1;
+       }
+
        return 0;
 }
 
index 9074b5cede38b8edd75890b684a706d96b9f71ba..f485600c4507bc152cef654ae5667a03a52d990c 100644 (file)
@@ -2142,11 +2142,17 @@ static void tipc_sk_timeout(unsigned long data)
        peer_node = tsk_peer_node(tsk);
 
        if (tsk->probing_state == TIPC_CONN_PROBING) {
-               /* Previous probe not answered -> self abort */
-               skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
-                                     TIPC_CONN_MSG, SHORT_H_SIZE, 0,
-                                     own_node, peer_node, tsk->portid,
-                                     peer_port, TIPC_ERR_NO_PORT);
+               if (!sock_owned_by_user(sk)) {
+                       sk->sk_socket->state = SS_DISCONNECTING;
+                       tsk->connected = 0;
+                       tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk),
+                                             tsk_peer_port(tsk));
+                       sk->sk_state_change(sk);
+               } else {
+                       /* Try again later */
+                       sk_reset_timer(sk, &sk->sk_timer, (HZ / 20));
+               }
+
        } else {
                skb = tipc_msg_create(CONN_MANAGER, CONN_PROBE,
                                      INT_H_SIZE, 0, peer_node, own_node,
index fff1bef6ed6d916f9019a63d708652f4ab07cddf..fd682832a0e3635d52c734871d5402d270336dc3 100644 (file)
@@ -1333,6 +1333,8 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
        memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
        wdev_unlock(wdev);
 
+       memset(&sinfo, 0, sizeof(sinfo));
+
        if (rdev_get_station(rdev, dev, bssid, &sinfo))
                return NULL;