Commit b8fa7d41 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull networking changes from David Miller:
 "The most important bit here is the TCP syncookies issue, which seems
  to have been busted for some time.  That fix has been verified in
  production by the reporter.

  1) Persistent TUN devices erroneously hold on to the network namespace
     in such a way that it cannot be shutdown.  Fix from Stanislav
     Kinsbursky with help from Eric Dumazet.

  2) TCP SYN cookies have been broken for a while due to how the route
     lookup flow key is managed, connections can be delayed by as much
     as 20 seconds due to this bug.  Fix from Eric Dumazet.

  3) Missing jiffies.h include in lib/dynamic_queue_limits.c can break
     the build, from Tom Herbert.

  4) Add USB device ID for Sitecom LN-031, from Joerg Neikes.

  5) Fix OOPS in delayed workqueue in iwlegacy, from Stanislaw Gruszka.

  6) rt2x00 TX queue can be disabled forever due to races, fix by
     synchronizing pause/unpause with a lock.  Also from Stanislaw
     Gruszka.

  7) Statistics and endian fix in bnx2x driver from Yuval Mintz, Eilon
     Greenstein, and Ariel Elior."

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  tun: don't hold network namespace by tun sockets
  bnx2x: FCoE statistics id fixed
  bnx2x: dcb bit indices flags used as bits
  bnx2x: added cpu_to_le16 when preparing ramrod's data
  bnx2x: pfc statistics counts pfc events twice
  rt2x00: fix random stalls
  iwl3945: fix possible il->txq NULL pointer dereference in delayed works
  dql: Fix undefined jiffies
  tcp: fix syncookie regression
  usb: asix: Patch for Sitecom LN-031
parents 69539ab1 750084b5
...@@ -1934,7 +1934,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) ...@@ -1934,7 +1934,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
} }
if (bp->port.pmf) if (bp->port.pmf)
bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0);
else else
bnx2x__link_status_update(bp); bnx2x__link_status_update(bp);
......
...@@ -1179,10 +1179,16 @@ static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, ...@@ -1179,10 +1179,16 @@ static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp,
*/ */
static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp) static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp)
{ {
if (!CHIP_IS_E1x(fp->bp)) struct bnx2x *bp = fp->bp;
if (!CHIP_IS_E1x(bp)) {
#ifdef BCM_CNIC
/* there are special statistics counters for FCoE 136..140 */
if (IS_FCOE_FP(fp))
return bp->cnic_base_cl_id + (bp->pf_num >> 1);
#endif
return fp->cl_id; return fp->cl_id;
else }
return fp->cl_id + BP_PORT(fp->bp) * FP_SB_MAX_E1x; return fp->cl_id + BP_PORT(bp) * FP_SB_MAX_E1x;
} }
static inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp, static inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp,
......
...@@ -735,7 +735,9 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) ...@@ -735,7 +735,9 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
bp->dcbx_error); bp->dcbx_error);
/* mark DCBX result for PMF migration */ /* mark DCBX result for PMF migration */
bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 1); bnx2x_update_drv_flags(bp,
1 << DRV_FLAGS_DCB_CONFIGURED,
1);
#ifdef BCM_DCBNL #ifdef BCM_DCBNL
/* /*
* Add new app tlvs to dcbnl * Add new app tlvs to dcbnl
...@@ -1020,7 +1022,7 @@ void bnx2x_dcbx_init(struct bnx2x *bp) ...@@ -1020,7 +1022,7 @@ void bnx2x_dcbx_init(struct bnx2x *bp)
DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n", DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n",
dcbx_lldp_params_offset); dcbx_lldp_params_offset);
bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0);
if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) {
bnx2x_dcbx_admin_mib_updated_params(bp, bnx2x_dcbx_admin_mib_updated_params(bp,
...@@ -1857,7 +1859,7 @@ void bnx2x_dcbx_pmf_update(struct bnx2x *bp) ...@@ -1857,7 +1859,7 @@ void bnx2x_dcbx_pmf_update(struct bnx2x *bp)
* read it from shmem and update bp and netdev accordingly * read it from shmem and update bp and netdev accordingly
*/ */
if (SHMEM2_HAS(bp, drv_flags) && if (SHMEM2_HAS(bp, drv_flags) &&
GET_FLAGS(SHMEM2_RD(bp, drv_flags), DRV_FLAGS_DCB_CONFIGURED)) { GET_FLAGS(SHMEM2_RD(bp, drv_flags), 1 << DRV_FLAGS_DCB_CONFIGURED)) {
/* Read neg results if dcbx is in the FW */ /* Read neg results if dcbx is in the FW */
if (bnx2x_dcbx_read_shmem_neg_results(bp)) if (bnx2x_dcbx_read_shmem_neg_results(bp))
return; return;
......
...@@ -5601,7 +5601,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, ...@@ -5601,7 +5601,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp,
/* Fill the ramrod data with provided parameters */ /* Fill the ramrod data with provided parameters */
rdata->function_mode = cpu_to_le16(start_params->mf_mode); rdata->function_mode = cpu_to_le16(start_params->mf_mode);
rdata->sd_vlan_tag = start_params->sd_vlan_tag; rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag);
rdata->path_id = BP_PATH(bp); rdata->path_id = BP_PATH(bp);
rdata->network_cos_mode = start_params->network_cos_mode; rdata->network_cos_mode = start_params->network_cos_mode;
......
...@@ -554,23 +554,11 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) ...@@ -554,23 +554,11 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl); UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl);
/* collect PFC stats */ /* collect PFC stats */
DIFF_64(diff.hi, new->tx_stat_gtpp_hi,
pstats->pfc_frames_tx_hi,
diff.lo, new->tx_stat_gtpp_lo,
pstats->pfc_frames_tx_lo);
pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi; pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi;
pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo; pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo;
ADD_64(pstats->pfc_frames_tx_hi, diff.hi,
pstats->pfc_frames_tx_lo, diff.lo);
DIFF_64(diff.hi, new->rx_stat_grpp_hi,
pstats->pfc_frames_rx_hi,
diff.lo, new->rx_stat_grpp_lo,
pstats->pfc_frames_rx_lo);
pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi; pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi;
pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo; pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo;
ADD_64(pstats->pfc_frames_rx_hi, diff.hi,
pstats->pfc_frames_rx_lo, diff.lo);
} }
estats->pause_frames_received_hi = estats->pause_frames_received_hi =
......
...@@ -359,7 +359,7 @@ static void tun_free_netdev(struct net_device *dev) ...@@ -359,7 +359,7 @@ static void tun_free_netdev(struct net_device *dev)
{ {
struct tun_struct *tun = netdev_priv(dev); struct tun_struct *tun = netdev_priv(dev);
sock_put(tun->socket.sk); sk_release_kernel(tun->socket.sk);
} }
/* Net device open. */ /* Net device open. */
...@@ -980,10 +980,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -980,10 +980,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
return ret; return ret;
} }
static int tun_release(struct socket *sock)
{
if (sock->sk)
sock_put(sock->sk);
return 0;
}
/* Ops structure to mimic raw sockets with tun */ /* Ops structure to mimic raw sockets with tun */
static const struct proto_ops tun_socket_ops = { static const struct proto_ops tun_socket_ops = {
.sendmsg = tun_sendmsg, .sendmsg = tun_sendmsg,
.recvmsg = tun_recvmsg, .recvmsg = tun_recvmsg,
.release = tun_release,
}; };
static struct proto tun_proto = { static struct proto tun_proto = {
...@@ -1110,10 +1118,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) ...@@ -1110,10 +1118,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
err = -ENOMEM; err = -ENOMEM;
sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto); sk = sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
if (!sk) if (!sk)
goto err_free_dev; goto err_free_dev;
sk_change_net(sk, net);
tun->socket.wq = &tun->wq; tun->socket.wq = &tun->wq;
init_waitqueue_head(&tun->wq.wait); init_waitqueue_head(&tun->wq.wait);
tun->socket.ops = &tun_socket_ops; tun->socket.ops = &tun_socket_ops;
...@@ -1174,7 +1183,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) ...@@ -1174,7 +1183,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
return 0; return 0;
err_free_sk: err_free_sk:
sock_put(sk); tun_free_netdev(dev);
err_free_dev: err_free_dev:
free_netdev(dev); free_netdev(dev);
failed: failed:
......
...@@ -1598,6 +1598,10 @@ static const struct usb_device_id products [] = { ...@@ -1598,6 +1598,10 @@ static const struct usb_device_id products [] = {
// Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
USB_DEVICE (0x6189, 0x182d), USB_DEVICE (0x6189, 0x182d),
.driver_info = (unsigned long) &ax8817x_info, .driver_info = (unsigned long) &ax8817x_info,
}, {
// Sitecom LN-031 "USB 2.0 10/100/1000 Ethernet adapter"
USB_DEVICE (0x0df6, 0x0056),
.driver_info = (unsigned long) &ax88178_info,
}, { }, {
// corega FEther USB2-TX // corega FEther USB2-TX
USB_DEVICE (0x07aa, 0x0017), USB_DEVICE (0x07aa, 0x0017),
......
...@@ -2475,7 +2475,7 @@ il3945_bg_alive_start(struct work_struct *data) ...@@ -2475,7 +2475,7 @@ il3945_bg_alive_start(struct work_struct *data)
container_of(data, struct il_priv, alive_start.work); container_of(data, struct il_priv, alive_start.work);
mutex_lock(&il->mutex); mutex_lock(&il->mutex);
if (test_bit(S_EXIT_PENDING, &il->status)) if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL)
goto out; goto out;
il3945_alive_start(il); il3945_alive_start(il);
......
...@@ -1870,11 +1870,12 @@ il3945_bg_reg_txpower_periodic(struct work_struct *work) ...@@ -1870,11 +1870,12 @@ il3945_bg_reg_txpower_periodic(struct work_struct *work)
struct il_priv *il = container_of(work, struct il_priv, struct il_priv *il = container_of(work, struct il_priv,
_3945.thermal_periodic.work); _3945.thermal_periodic.work);
if (test_bit(S_EXIT_PENDING, &il->status))
return;
mutex_lock(&il->mutex); mutex_lock(&il->mutex);
if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL)
goto out;
il3945_reg_txpower_periodic(il); il3945_reg_txpower_periodic(il);
out:
mutex_unlock(&il->mutex); mutex_unlock(&il->mutex);
} }
......
...@@ -426,10 +426,14 @@ void rt2x00lib_txdone(struct queue_entry *entry, ...@@ -426,10 +426,14 @@ void rt2x00lib_txdone(struct queue_entry *entry,
/* /*
* If the data queue was below the threshold before the txdone * If the data queue was below the threshold before the txdone
* handler we must make sure the packet queue in the mac80211 stack * handler we must make sure the packet queue in the mac80211 stack
* is reenabled when the txdone handler has finished. * is reenabled when the txdone handler has finished. This has to be
* serialized with rt2x00mac_tx(), otherwise we can wake up queue
* before it was stopped.
*/ */
spin_lock_bh(&entry->queue->tx_lock);
if (!rt2x00queue_threshold(entry->queue)) if (!rt2x00queue_threshold(entry->queue))
rt2x00queue_unpause_queue(entry->queue); rt2x00queue_unpause_queue(entry->queue);
spin_unlock_bh(&entry->queue->tx_lock);
} }
EXPORT_SYMBOL_GPL(rt2x00lib_txdone); EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
......
...@@ -152,13 +152,22 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -152,13 +152,22 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false)))
goto exit_fail; goto exit_fail;
/*
* Pausing queue has to be serialized with rt2x00lib_txdone(). Note
* we should not use spin_lock_bh variant as bottom halve was already
* disabled before ieee80211_xmit() call.
*/
spin_lock(&queue->tx_lock);
if (rt2x00queue_threshold(queue)) if (rt2x00queue_threshold(queue))
rt2x00queue_pause_queue(queue); rt2x00queue_pause_queue(queue);
spin_unlock(&queue->tx_lock);
return; return;
exit_fail: exit_fail:
spin_lock(&queue->tx_lock);
rt2x00queue_pause_queue(queue); rt2x00queue_pause_queue(queue);
spin_unlock(&queue->tx_lock);
exit_free_skb: exit_free_skb:
ieee80211_free_txskb(hw, skb); ieee80211_free_txskb(hw, skb);
} }
......
...@@ -619,6 +619,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, ...@@ -619,6 +619,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags))
rt2x00queue_align_frame(skb); rt2x00queue_align_frame(skb);
/*
* That function must be called with bh disabled.
*/
spin_lock(&queue->tx_lock); spin_lock(&queue->tx_lock);
if (unlikely(rt2x00queue_full(queue))) { if (unlikely(rt2x00queue_full(queue))) {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/dynamic_queue_limits.h> #include <linux/dynamic_queue_limits.h>
#define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0) #define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)
......
...@@ -278,6 +278,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ...@@ -278,6 +278,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
struct rtable *rt; struct rtable *rt;
__u8 rcv_wscale; __u8 rcv_wscale;
bool ecn_ok = false; bool ecn_ok = false;
struct flowi4 fl4;
if (!sysctl_tcp_syncookies || !th->ack || th->rst) if (!sysctl_tcp_syncookies || !th->ack || th->rst)
goto out; goto out;
...@@ -346,9 +347,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ...@@ -346,9 +347,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
* hasn't changed since we received the original syn, but I see * hasn't changed since we received the original syn, but I see
* no easy way to do this. * no easy way to do this.
*/ */
{
struct flowi4 fl4;
flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk),
RT_SCOPE_UNIVERSE, IPPROTO_TCP, RT_SCOPE_UNIVERSE, IPPROTO_TCP,
inet_sk_flowi_flags(sk), inet_sk_flowi_flags(sk),
...@@ -360,7 +358,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ...@@ -360,7 +358,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
reqsk_free(req); reqsk_free(req);
goto out; goto out;
} }
}
/* Try to redo what tcp_v4_send_synack did. */ /* Try to redo what tcp_v4_send_synack did. */
req->window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW); req->window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW);
...@@ -373,5 +370,10 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ...@@ -373,5 +370,10 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
ireq->rcv_wscale = rcv_wscale; ireq->rcv_wscale = rcv_wscale;
ret = get_cookie_sock(sk, skb, req, &rt->dst); ret = get_cookie_sock(sk, skb, req, &rt->dst);
/* ip_queue_xmit() depends on our flow being setup
* Normal sockets get it right from inet_csk_route_child_sock()
*/
if (ret)
inet_sk(ret)->cork.fl.u.ip4 = fl4;
out: return ret; out: return ret;
} }
...@@ -1466,9 +1466,13 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, ...@@ -1466,9 +1466,13 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen; inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
newinet->inet_id = newtp->write_seq ^ jiffies; newinet->inet_id = newtp->write_seq ^ jiffies;
if (!dst && (dst = inet_csk_route_child_sock(sk, newsk, req)) == NULL) if (!dst) {
dst = inet_csk_route_child_sock(sk, newsk, req);
if (!dst)
goto put_and_exit; goto put_and_exit;
} else {
/* syncookie case : see end of cookie_v4_check() */
}
sk_setup_caps(newsk, dst); sk_setup_caps(newsk, dst);
tcp_mtup_init(newsk); tcp_mtup_init(newsk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment