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

Conflicts:
	drivers/net/ethernet/intel/e1000e/ethtool.c
	drivers/net/vmxnet3/vmxnet3_drv.c
	drivers/net/wireless/iwlwifi/dvm/tx.c
	net/ipv6/route.c

The ipv6 route.c conflict is simple, just ignore the 'net' side change
as we fixed the same problem in 'net-next' by eliminating cached
neighbours from ipv6 routes.

The e1000e conflict is an addition of a new statistic in the ethtool
code, trivial.

The vmxnet3 conflict is about one change in 'net' removing a guarding
conditional, whilst in 'net-next' we had a netdev_info() conversion.

The iwlwifi conflict is dealing with a WARN_ON() conversion in
'net-next' vs. a revert happening in 'net'.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2013-02-05 14:12:20 -05:00
commit 188d1f76d0
38 changed files with 290 additions and 165 deletions

View File

@ -21,7 +21,7 @@ int bcma_nflash_init(struct bcma_drv_cc *cc)
struct bcma_bus *bus = cc->core->bus; struct bcma_bus *bus = cc->core->bus;
if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 &&
cc->core->id.rev != 0x38) { cc->core->id.rev != 38) {
bcma_err(bus, "NAND flash on unsupported board!\n"); bcma_err(bus, "NAND flash on unsupported board!\n");
return -ENOTSUPP; return -ENOTSUPP;
} }

View File

@ -1053,6 +1053,7 @@ static ssize_t bonding_store_primary(struct device *d,
pr_info("%s: Setting primary slave to None.\n", pr_info("%s: Setting primary slave to None.\n",
bond->dev->name); bond->dev->name);
bond->primary_slave = NULL; bond->primary_slave = NULL;
memset(bond->params.primary, 0, sizeof(bond->params.primary));
bond_select_active_slave(bond); bond_select_active_slave(bond);
goto out; goto out;
} }

View File

@ -491,8 +491,12 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface,
priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface),
IFX_WRITE_LOW_16BIT(mask)); IFX_WRITE_LOW_16BIT(mask));
/* According to C_CAN documentation, the reserved bit
* in IFx_MASK2 register is fixed 1
*/
priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface),
IFX_WRITE_HIGH_16BIT(mask)); IFX_WRITE_HIGH_16BIT(mask) | BIT(13));
priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface),
IFX_WRITE_LOW_16BIT(id)); IFX_WRITE_LOW_16BIT(id));

View File

@ -36,13 +36,13 @@
#define DRV_VER "4.6.62.0u" #define DRV_VER "4.6.62.0u"
#define DRV_NAME "be2net" #define DRV_NAME "be2net"
#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" #define BE_NAME "Emulex BladeEngine2"
#define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" #define BE3_NAME "Emulex BladeEngine3"
#define OC_NAME "Emulex OneConnect 10Gbps NIC" #define OC_NAME "Emulex OneConnect"
#define OC_NAME_BE OC_NAME "(be3)" #define OC_NAME_BE OC_NAME "(be3)"
#define OC_NAME_LANCER OC_NAME "(Lancer)" #define OC_NAME_LANCER OC_NAME "(Lancer)"
#define OC_NAME_SH OC_NAME "(Skyhawk)" #define OC_NAME_SH OC_NAME "(Skyhawk)"
#define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver" #define DRV_DESC "Emulex OneConnect 10Gbps NIC Driver"
#define BE_VENDOR_ID 0x19a2 #define BE_VENDOR_ID 0x19a2
#define EMULEX_VENDOR_ID 0x10df #define EMULEX_VENDOR_ID 0x10df

View File

@ -25,7 +25,7 @@
MODULE_VERSION(DRV_VER); MODULE_VERSION(DRV_VER);
MODULE_DEVICE_TABLE(pci, be_dev_ids); MODULE_DEVICE_TABLE(pci, be_dev_ids);
MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); MODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
MODULE_AUTHOR("ServerEngines Corporation"); MODULE_AUTHOR("Emulex Corporation");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static unsigned int num_vfs; static unsigned int num_vfs;

View File

@ -1812,7 +1812,7 @@ static void rhine_tx(struct net_device *dev)
rp->tx_skbuff[entry]->len, rp->tx_skbuff[entry]->len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
} }
dev_kfree_skb_irq(rp->tx_skbuff[entry]); dev_kfree_skb(rp->tx_skbuff[entry]);
rp->tx_skbuff[entry] = NULL; rp->tx_skbuff[entry] = NULL;
entry = (++rp->dirty_tx) % TX_RING_SIZE; entry = (++rp->dirty_tx) % TX_RING_SIZE;
} }
@ -2024,11 +2024,7 @@ static void rhine_slow_event_task(struct work_struct *work)
if (intr_status & IntrPCIErr) if (intr_status & IntrPCIErr)
netif_warn(rp, hw, dev, "PCI error\n"); netif_warn(rp, hw, dev, "PCI error\n");
napi_disable(&rp->napi); iowrite16(RHINE_EVENT & 0xffff, rp->base + IntrEnable);
rhine_irq_disable(rp);
/* Slow and safe. Consider __napi_schedule as a replacement ? */
napi_enable(&rp->napi);
napi_schedule(&rp->napi);
out_unlock: out_unlock:
mutex_unlock(&rp->task_lock); mutex_unlock(&rp->task_lock);

View File

@ -298,11 +298,12 @@ static void tun_flow_cleanup(unsigned long data)
} }
static void tun_flow_update(struct tun_struct *tun, u32 rxhash, static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
u16 queue_index) struct tun_file *tfile)
{ {
struct hlist_head *head; struct hlist_head *head;
struct tun_flow_entry *e; struct tun_flow_entry *e;
unsigned long delay = tun->ageing_time; unsigned long delay = tun->ageing_time;
u16 queue_index = tfile->queue_index;
if (!rxhash) if (!rxhash)
return; return;
@ -311,7 +312,9 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
rcu_read_lock(); rcu_read_lock();
if (tun->numqueues == 1) /* We may get a very small possibility of OOO during switching, not
* worth to optimize.*/
if (tun->numqueues == 1 || tfile->detached)
goto unlock; goto unlock;
e = tun_flow_find(head, rxhash); e = tun_flow_find(head, rxhash);
@ -411,21 +414,21 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
tun = rtnl_dereference(tfile->tun); tun = rtnl_dereference(tfile->tun);
if (tun) { if (tun && !tfile->detached) {
u16 index = tfile->queue_index; u16 index = tfile->queue_index;
BUG_ON(index >= tun->numqueues); BUG_ON(index >= tun->numqueues);
dev = tun->dev; dev = tun->dev;
rcu_assign_pointer(tun->tfiles[index], rcu_assign_pointer(tun->tfiles[index],
tun->tfiles[tun->numqueues - 1]); tun->tfiles[tun->numqueues - 1]);
rcu_assign_pointer(tfile->tun, NULL);
ntfile = rtnl_dereference(tun->tfiles[index]); ntfile = rtnl_dereference(tun->tfiles[index]);
ntfile->queue_index = index; ntfile->queue_index = index;
--tun->numqueues; --tun->numqueues;
if (clean) if (clean) {
rcu_assign_pointer(tfile->tun, NULL);
sock_put(&tfile->sk); sock_put(&tfile->sk);
else } else
tun_disable_queue(tun, tfile); tun_disable_queue(tun, tfile);
synchronize_net(); synchronize_net();
@ -439,10 +442,13 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
} }
if (clean) { if (clean) {
if (tun && tun->numqueues == 0 && tun->numdisabled == 0 && if (tun && tun->numqueues == 0 && tun->numdisabled == 0) {
!(tun->flags & TUN_PERSIST)) netif_carrier_off(tun->dev);
if (tun->dev->reg_state == NETREG_REGISTERED)
if (!(tun->flags & TUN_PERSIST) &&
tun->dev->reg_state == NETREG_REGISTERED)
unregister_netdevice(tun->dev); unregister_netdevice(tun->dev);
}
BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED, BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED,
&tfile->socket.flags)); &tfile->socket.flags));
@ -470,6 +476,10 @@ static void tun_detach_all(struct net_device *dev)
rcu_assign_pointer(tfile->tun, NULL); rcu_assign_pointer(tfile->tun, NULL);
--tun->numqueues; --tun->numqueues;
} }
list_for_each_entry(tfile, &tun->disabled, next) {
wake_up_all(&tfile->wq.wait);
rcu_assign_pointer(tfile->tun, NULL);
}
BUG_ON(tun->numqueues != 0); BUG_ON(tun->numqueues != 0);
synchronize_net(); synchronize_net();
@ -500,7 +510,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
goto out; goto out;
err = -EINVAL; err = -EINVAL;
if (rtnl_dereference(tfile->tun)) if (rtnl_dereference(tfile->tun) && !tfile->detached)
goto out; goto out;
err = -EBUSY; err = -EBUSY;
@ -1203,7 +1213,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
tun->dev->stats.rx_packets++; tun->dev->stats.rx_packets++;
tun->dev->stats.rx_bytes += len; tun->dev->stats.rx_bytes += len;
tun_flow_update(tun, rxhash, tfile->queue_index); tun_flow_update(tun, rxhash, tfile);
return total_len; return total_len;
} }
@ -1662,10 +1672,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
device_create_file(&tun->dev->dev, &dev_attr_owner) || device_create_file(&tun->dev->dev, &dev_attr_owner) ||
device_create_file(&tun->dev->dev, &dev_attr_group)) device_create_file(&tun->dev->dev, &dev_attr_group))
pr_err("Failed to create tun sysfs files\n"); pr_err("Failed to create tun sysfs files\n");
netif_carrier_on(tun->dev);
} }
netif_carrier_on(tun->dev);
tun_debug(KERN_INFO, tun, "tun_set_iff\n"); tun_debug(KERN_INFO, tun, "tun_set_iff\n");
if (ifr->ifr_flags & IFF_NO_PI) if (ifr->ifr_flags & IFF_NO_PI)
@ -1817,7 +1827,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
ret = tun_attach(tun, file); ret = tun_attach(tun, file);
} else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
tun = rtnl_dereference(tfile->tun); tun = rtnl_dereference(tfile->tun);
if (!tun || !(tun->flags & TUN_TAP_MQ)) if (!tun || !(tun->flags & TUN_TAP_MQ) || tfile->detached)
ret = -EINVAL; ret = -EINVAL;
else else
__tun_detach(tfile, false); __tun_detach(tfile, false);

View File

@ -461,6 +461,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
/* 4. Gobi 1000 devices */ /* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */

View File

@ -380,6 +380,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
unsigned long lockflags; unsigned long lockflags;
size_t size = dev->rx_urb_size; size_t size = dev->rx_urb_size;
/* prevent rx skb allocation when error ratio is high */
if (test_bit(EVENT_RX_KILL, &dev->flags)) {
usb_free_urb(urb);
return -ENOLINK;
}
skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
if (!skb) { if (!skb) {
netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
@ -539,6 +545,17 @@ static void rx_complete (struct urb *urb)
break; break;
} }
/* stop rx if packet error rate is high */
if (++dev->pkt_cnt > 30) {
dev->pkt_cnt = 0;
dev->pkt_err = 0;
} else {
if (state == rx_cleanup)
dev->pkt_err++;
if (dev->pkt_err > 20)
set_bit(EVENT_RX_KILL, &dev->flags);
}
state = defer_bh(dev, skb, &dev->rxq, state); state = defer_bh(dev, skb, &dev->rxq, state);
if (urb) { if (urb) {
@ -791,6 +808,11 @@ int usbnet_open (struct net_device *net)
(dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" : (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" :
"simple"); "simple");
/* reset rx error state */
dev->pkt_cnt = 0;
dev->pkt_err = 0;
clear_bit(EVENT_RX_KILL, &dev->flags);
// delay posting reads until we're fully open // delay posting reads until we're fully open
tasklet_schedule (&dev->bh); tasklet_schedule (&dev->bh);
if (info->manage_power) { if (info->manage_power) {
@ -1103,13 +1125,11 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
if (info->tx_fixup) { if (info->tx_fixup) {
skb = info->tx_fixup (dev, skb, GFP_ATOMIC); skb = info->tx_fixup (dev, skb, GFP_ATOMIC);
if (!skb) { if (!skb) {
if (netif_msg_tx_err(dev)) { /* packet collected; minidriver waiting for more */
netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); if (info->flags & FLAG_MULTI_PACKET)
goto drop;
} else {
/* cdc_ncm collected packet; waits for more */
goto not_drop; goto not_drop;
} netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n");
goto drop;
} }
} }
length = skb->len; length = skb->len;
@ -1254,6 +1274,9 @@ static void usbnet_bh (unsigned long param)
} }
} }
/* restart RX again after disabling due to high error rate */
clear_bit(EVENT_RX_KILL, &dev->flags);
// waiting for all pending urbs to complete? // waiting for all pending urbs to complete?
if (dev->wait) { if (dev->wait) {
if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) {

View File

@ -150,8 +150,7 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)
if (ret & 1) { /* Link is up. */ if (ret & 1) { /* Link is up. */
netdev_info(adapter->netdev, "NIC Link is Up %d Mbps\n", netdev_info(adapter->netdev, "NIC Link is Up %d Mbps\n",
adapter->link_speed); adapter->link_speed);
if (!netif_carrier_ok(adapter->netdev)) netif_carrier_on(adapter->netdev);
netif_carrier_on(adapter->netdev);
if (affectTxQueue) { if (affectTxQueue) {
for (i = 0; i < adapter->num_tx_queues; i++) for (i = 0; i < adapter->num_tx_queues; i++)
@ -160,8 +159,7 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue)
} }
} else { } else {
netdev_info(adapter->netdev, "NIC Link is Down\n"); netdev_info(adapter->netdev, "NIC Link is Down\n");
if (netif_carrier_ok(adapter->netdev)) netif_carrier_off(adapter->netdev);
netif_carrier_off(adapter->netdev);
if (affectTxQueue) { if (affectTxQueue) {
for (i = 0; i < adapter->num_tx_queues; i++) for (i = 0; i < adapter->num_tx_queues; i++)
@ -3060,6 +3058,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues); netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues);
netif_carrier_off(netdev);
err = register_netdev(netdev); err = register_netdev(netdev);
if (err) { if (err) {

View File

@ -1027,7 +1027,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
static bool static bool
brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
{ {
bool morepending = false;
struct bcma_device *core; struct bcma_device *core;
struct tx_status txstatus, *txs; struct tx_status txstatus, *txs;
u32 s1, s2; u32 s1, s2;
@ -1041,23 +1040,20 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
txs = &txstatus; txs = &txstatus;
core = wlc_hw->d11core; core = wlc_hw->d11core;
*fatal = false; *fatal = false;
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
while (!(*fatal)
&& (s1 & TXS_V)) {
/* !give others some time to run! */
if (n >= max_tx_num) {
morepending = true;
break;
}
while (n < max_tx_num) {
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
if (s1 == 0xffffffff) { if (s1 == 0xffffffff) {
brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
__func__); __func__);
*fatal = true; *fatal = true;
return false; return false;
} }
s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); /* only process when valid */
if (!(s1 & TXS_V))
break;
s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
txs->status = s1 & TXS_STATUS_MASK; txs->status = s1 & TXS_STATUS_MASK;
txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
txs->sequence = s2 & TXS_SEQ_MASK; txs->sequence = s2 & TXS_SEQ_MASK;
@ -1065,15 +1061,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
txs->lasttxtime = 0; txs->lasttxtime = 0;
*fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
if (*fatal == true)
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); return false;
n++; n++;
} }
if (*fatal) return n >= max_tx_num;
return false;
return morepending;
} }
static void brcms_c_tbtt(struct brcms_c_info *wlc) static void brcms_c_tbtt(struct brcms_c_info *wlc)

View File

@ -1145,6 +1145,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
next_reclaimed = ssn; next_reclaimed = ssn;
} }
if (tid != IWL_TID_NON_QOS) {
priv->tid_data[sta_id][tid].next_reclaimed =
next_reclaimed;
IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
next_reclaimed);
}
iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs); iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
iwlagn_check_ratid_empty(priv, sta_id, tid); iwlagn_check_ratid_empty(priv, sta_id, tid);
@ -1195,30 +1202,12 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
if (!is_agg) if (!is_agg)
iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
/*
* W/A for FW bug - the seq_ctl isn't updated when the
* queues are flushed. Fetch it from the packet itself
*/
if (!is_agg && status == TX_STATUS_FAIL_FIFO_FLUSHED) {
next_reclaimed = le16_to_cpu(hdr->seq_ctrl);
next_reclaimed =
SEQ_TO_SN(next_reclaimed + 0x10);
}
is_offchannel_skb = is_offchannel_skb =
(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN); (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN);
freed++; freed++;
} }
if (tid != IWL_TID_NON_QOS) { WARN_ON(!is_agg && freed != 1);
priv->tid_data[sta_id][tid].next_reclaimed =
next_reclaimed;
IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
next_reclaimed);
}
if (!is_agg && freed != 1)
IWL_ERR(priv, "Q: %d, freed %d\n", txq_id, freed);
/* /*
* An offchannel frame can be send only on the AUX queue, where * An offchannel frame can be send only on the AUX queue, where

View File

@ -1557,7 +1557,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
scan_rsp->number_of_sets); scan_rsp->number_of_sets);
ret = -1; ret = -1;
goto done; goto check_next_scan;
} }
bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
@ -1628,7 +1628,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
if (!beacon_size || beacon_size > bytes_left) { if (!beacon_size || beacon_size > bytes_left) {
bss_info += bytes_left; bss_info += bytes_left;
bytes_left = 0; bytes_left = 0;
return -1; ret = -1;
goto check_next_scan;
} }
/* Initialize the current working beacon pointer for this BSS /* Initialize the current working beacon pointer for this BSS
@ -1684,7 +1685,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
dev_err(priv->adapter->dev, dev_err(priv->adapter->dev,
"%s: bytes left < IE length\n", "%s: bytes left < IE length\n",
__func__); __func__);
goto done; goto check_next_scan;
} }
if (element_id == WLAN_EID_DS_PARAMS) { if (element_id == WLAN_EID_DS_PARAMS) {
channel = *(current_ptr + sizeof(struct ieee_types_header)); channel = *(current_ptr + sizeof(struct ieee_types_header));
@ -1747,6 +1748,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
} }
} }
check_next_scan:
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
if (list_empty(&adapter->scan_pending_q)) { if (list_empty(&adapter->scan_pending_q)) {
spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
@ -1807,7 +1809,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
} }
} }
done:
return ret; return ret;
} }

View File

@ -542,8 +542,8 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)
WARN_ON(skb_queue_empty(&rx_queue)); WARN_ON(skb_queue_empty(&rx_queue));
while (!skb_queue_empty(&rx_queue)) { while (!skb_queue_empty(&rx_queue)) {
_skb = skb_dequeue(&rx_queue); _skb = skb_dequeue(&rx_queue);
_rtl_usb_rx_process_agg(hw, skb); _rtl_usb_rx_process_agg(hw, _skb);
ieee80211_rx_irqsafe(hw, skb); ieee80211_rx_irqsafe(hw, _skb);
} }
} }

View File

@ -165,12 +165,16 @@ static void tx_poll_stop(struct vhost_net *net)
} }
/* Caller must have TX VQ lock */ /* Caller must have TX VQ lock */
static void tx_poll_start(struct vhost_net *net, struct socket *sock) static int tx_poll_start(struct vhost_net *net, struct socket *sock)
{ {
int ret;
if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED)) if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED))
return; return 0;
vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file); ret = vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
net->tx_poll_state = VHOST_NET_POLL_STARTED; if (!ret)
net->tx_poll_state = VHOST_NET_POLL_STARTED;
return ret;
} }
/* In case of DMA done not in order in lower device driver for some reason. /* In case of DMA done not in order in lower device driver for some reason.
@ -642,20 +646,23 @@ static void vhost_net_disable_vq(struct vhost_net *n,
vhost_poll_stop(n->poll + VHOST_NET_VQ_RX); vhost_poll_stop(n->poll + VHOST_NET_VQ_RX);
} }
static void vhost_net_enable_vq(struct vhost_net *n, static int vhost_net_enable_vq(struct vhost_net *n,
struct vhost_virtqueue *vq) struct vhost_virtqueue *vq)
{ {
struct socket *sock; struct socket *sock;
int ret;
sock = rcu_dereference_protected(vq->private_data, sock = rcu_dereference_protected(vq->private_data,
lockdep_is_held(&vq->mutex)); lockdep_is_held(&vq->mutex));
if (!sock) if (!sock)
return; return 0;
if (vq == n->vqs + VHOST_NET_VQ_TX) { if (vq == n->vqs + VHOST_NET_VQ_TX) {
n->tx_poll_state = VHOST_NET_POLL_STOPPED; n->tx_poll_state = VHOST_NET_POLL_STOPPED;
tx_poll_start(n, sock); ret = tx_poll_start(n, sock);
} else } else
vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file); ret = vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file);
return ret;
} }
static struct socket *vhost_net_stop_vq(struct vhost_net *n, static struct socket *vhost_net_stop_vq(struct vhost_net *n,
@ -827,15 +834,18 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
r = PTR_ERR(ubufs); r = PTR_ERR(ubufs);
goto err_ubufs; goto err_ubufs;
} }
oldubufs = vq->ubufs;
vq->ubufs = ubufs;
vhost_net_disable_vq(n, vq); vhost_net_disable_vq(n, vq);
rcu_assign_pointer(vq->private_data, sock); rcu_assign_pointer(vq->private_data, sock);
vhost_net_enable_vq(n, vq);
r = vhost_init_used(vq); r = vhost_init_used(vq);
if (r) if (r)
goto err_vq; goto err_used;
r = vhost_net_enable_vq(n, vq);
if (r)
goto err_used;
oldubufs = vq->ubufs;
vq->ubufs = ubufs;
n->tx_packets = 0; n->tx_packets = 0;
n->tx_zcopy_err = 0; n->tx_zcopy_err = 0;
@ -859,6 +869,11 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
mutex_unlock(&n->dev.mutex); mutex_unlock(&n->dev.mutex);
return 0; return 0;
err_used:
rcu_assign_pointer(vq->private_data, oldsock);
vhost_net_enable_vq(n, vq);
if (ubufs)
vhost_ubuf_put_and_wait(ubufs);
err_ubufs: err_ubufs:
fput(sock->file); fput(sock->file);
err_vq: err_vq:

View File

@ -77,26 +77,38 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
init_poll_funcptr(&poll->table, vhost_poll_func); init_poll_funcptr(&poll->table, vhost_poll_func);
poll->mask = mask; poll->mask = mask;
poll->dev = dev; poll->dev = dev;
poll->wqh = NULL;
vhost_work_init(&poll->work, fn); vhost_work_init(&poll->work, fn);
} }
/* Start polling a file. We add ourselves to file's wait queue. The caller must /* Start polling a file. We add ourselves to file's wait queue. The caller must
* keep a reference to a file until after vhost_poll_stop is called. */ * keep a reference to a file until after vhost_poll_stop is called. */
void vhost_poll_start(struct vhost_poll *poll, struct file *file) int vhost_poll_start(struct vhost_poll *poll, struct file *file)
{ {
unsigned long mask; unsigned long mask;
int ret = 0;
mask = file->f_op->poll(file, &poll->table); mask = file->f_op->poll(file, &poll->table);
if (mask) if (mask)
vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask); vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask);
if (mask & POLLERR) {
if (poll->wqh)
remove_wait_queue(poll->wqh, &poll->wait);
ret = -EINVAL;
}
return ret;
} }
/* Stop polling a file. After this function returns, it becomes safe to drop the /* Stop polling a file. After this function returns, it becomes safe to drop the
* file reference. You must also flush afterwards. */ * file reference. You must also flush afterwards. */
void vhost_poll_stop(struct vhost_poll *poll) void vhost_poll_stop(struct vhost_poll *poll)
{ {
remove_wait_queue(poll->wqh, &poll->wait); if (poll->wqh) {
remove_wait_queue(poll->wqh, &poll->wait);
poll->wqh = NULL;
}
} }
static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
@ -792,7 +804,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
fput(filep); fput(filep);
if (pollstart && vq->handle_kick) if (pollstart && vq->handle_kick)
vhost_poll_start(&vq->poll, vq->kick); r = vhost_poll_start(&vq->poll, vq->kick);
mutex_unlock(&vq->mutex); mutex_unlock(&vq->mutex);

View File

@ -42,7 +42,7 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work);
void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn,
unsigned long mask, struct vhost_dev *dev); unsigned long mask, struct vhost_dev *dev);
void vhost_poll_start(struct vhost_poll *poll, struct file *file); int vhost_poll_start(struct vhost_poll *poll, struct file *file);
void vhost_poll_stop(struct vhost_poll *poll); void vhost_poll_stop(struct vhost_poll *poll);
void vhost_poll_flush(struct vhost_poll *poll); void vhost_poll_flush(struct vhost_poll *poll);
void vhost_poll_queue(struct vhost_poll *poll); void vhost_poll_queue(struct vhost_poll *poll);

View File

@ -33,6 +33,7 @@ struct usbnet {
wait_queue_head_t *wait; wait_queue_head_t *wait;
struct mutex phy_mutex; struct mutex phy_mutex;
unsigned char suspend_count; unsigned char suspend_count;
unsigned char pkt_cnt, pkt_err;
/* i/o info: pipes etc */ /* i/o info: pipes etc */
unsigned in, out; unsigned in, out;
@ -70,6 +71,7 @@ struct usbnet {
# define EVENT_DEV_OPEN 7 # define EVENT_DEV_OPEN 7
# define EVENT_DEVICE_REPORT_IDLE 8 # define EVENT_DEVICE_REPORT_IDLE 8
# define EVENT_NO_RUNTIME_PM 9 # define EVENT_NO_RUNTIME_PM 9
# define EVENT_RX_KILL 10
}; };
static inline struct usb_driver *driver_of(struct usb_interface *intf) static inline struct usb_driver *driver_of(struct usb_interface *intf)

View File

@ -34,17 +34,17 @@ extern int udpv6_connect(struct sock *sk,
struct sockaddr *uaddr, struct sockaddr *uaddr,
int addr_len); int addr_len);
extern int datagram_recv_ctl(struct sock *sk, extern int ip6_datagram_recv_ctl(struct sock *sk,
struct msghdr *msg, struct msghdr *msg,
struct sk_buff *skb); struct sk_buff *skb);
extern int datagram_send_ctl(struct net *net, extern int ip6_datagram_send_ctl(struct net *net,
struct sock *sk, struct sock *sk,
struct msghdr *msg, struct msghdr *msg,
struct flowi6 *fl6, struct flowi6 *fl6,
struct ipv6_txoptions *opt, struct ipv6_txoptions *opt,
int *hlimit, int *tclass, int *hlimit, int *tclass,
int *dontfrag); int *dontfrag);
#define LOOPBACK4_IPV6 cpu_to_be32(0x7f000006) #define LOOPBACK4_IPV6 cpu_to_be32(0x7f000006)

View File

@ -1790,10 +1790,13 @@ static ssize_t pktgen_thread_write(struct file *file,
return -EFAULT; return -EFAULT;
i += len; i += len;
mutex_lock(&pktgen_thread_lock); mutex_lock(&pktgen_thread_lock);
pktgen_add_device(t, f); ret = pktgen_add_device(t, f);
mutex_unlock(&pktgen_thread_lock); mutex_unlock(&pktgen_thread_lock);
ret = count; if (!ret) {
sprintf(pg_result, "OK: add_device=%s", f); ret = count;
sprintf(pg_result, "OK: add_device=%s", f);
} else
sprintf(pg_result, "ERROR: can not add device %s", f);
goto out; goto out;
} }

View File

@ -686,7 +686,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->network_header = old->network_header; new->network_header = old->network_header;
new->mac_header = old->mac_header; new->mac_header = old->mac_header;
new->inner_transport_header = old->inner_transport_header; new->inner_transport_header = old->inner_transport_header;
new->inner_network_header = old->inner_transport_header; new->inner_network_header = old->inner_network_header;
skb_dst_copy(new, old); skb_dst_copy(new, old);
new->rxhash = old->rxhash; new->rxhash = old->rxhash;
new->ooo_okay = old->ooo_okay; new->ooo_okay = old->ooo_okay;

View File

@ -310,6 +310,12 @@ void tcp_slow_start(struct tcp_sock *tp)
{ {
int cnt; /* increase in packets */ int cnt; /* increase in packets */
unsigned int delta = 0; unsigned int delta = 0;
u32 snd_cwnd = tp->snd_cwnd;
if (unlikely(!snd_cwnd)) {
pr_err_once("snd_cwnd is nul, please report this bug.\n");
snd_cwnd = 1U;
}
/* RFC3465: ABC Slow start /* RFC3465: ABC Slow start
* Increase only after a full MSS of bytes is acked * Increase only after a full MSS of bytes is acked
@ -324,7 +330,7 @@ void tcp_slow_start(struct tcp_sock *tp)
if (sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tcp_max_ssthresh) if (sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tcp_max_ssthresh)
cnt = sysctl_tcp_max_ssthresh >> 1; /* limited slow start */ cnt = sysctl_tcp_max_ssthresh >> 1; /* limited slow start */
else else
cnt = tp->snd_cwnd; /* exponential increase */ cnt = snd_cwnd; /* exponential increase */
/* RFC3465: ABC /* RFC3465: ABC
* We MAY increase by 2 if discovered delayed ack * We MAY increase by 2 if discovered delayed ack
@ -334,11 +340,11 @@ void tcp_slow_start(struct tcp_sock *tp)
tp->bytes_acked = 0; tp->bytes_acked = 0;
tp->snd_cwnd_cnt += cnt; tp->snd_cwnd_cnt += cnt;
while (tp->snd_cwnd_cnt >= tp->snd_cwnd) { while (tp->snd_cwnd_cnt >= snd_cwnd) {
tp->snd_cwnd_cnt -= tp->snd_cwnd; tp->snd_cwnd_cnt -= snd_cwnd;
delta++; delta++;
} }
tp->snd_cwnd = min(tp->snd_cwnd + delta, tp->snd_cwnd_clamp); tp->snd_cwnd = min(snd_cwnd + delta, tp->snd_cwnd_clamp);
} }
EXPORT_SYMBOL_GPL(tcp_slow_start); EXPORT_SYMBOL_GPL(tcp_slow_start);

View File

@ -3482,7 +3482,8 @@ static bool tcp_process_frto(struct sock *sk, int flag)
((tp->frto_counter >= 2) && (flag & FLAG_RETRANS_DATA_ACKED))) ((tp->frto_counter >= 2) && (flag & FLAG_RETRANS_DATA_ACKED)))
tp->undo_marker = 0; tp->undo_marker = 0;
if (!before(tp->snd_una, tp->frto_highmark)) { if (!before(tp->snd_una, tp->frto_highmark) ||
!tcp_packets_in_flight(tp)) {
tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3), flag); tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3), flag);
return true; return true;
} }
@ -5647,8 +5648,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
* the remote receives only the retransmitted (regular) SYNs: either * the remote receives only the retransmitted (regular) SYNs: either
* the original SYN-data or the corresponding SYN-ACK is lost. * the original SYN-data or the corresponding SYN-ACK is lost.
*/ */
syn_drop = (cookie->len <= 0 && data && syn_drop = (cookie->len <= 0 && data && tp->total_retrans);
inet_csk(sk)->icsk_retransmits);
tcp_fastopen_cache_set(sk, mss, cookie, syn_drop); tcp_fastopen_cache_set(sk, mss, cookie, syn_drop);

View File

@ -496,6 +496,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
* errors returned from accept(). * errors returned from accept().
*/ */
inet_csk_reqsk_queue_drop(sk, req, prev); inet_csk_reqsk_queue_drop(sk, req, prev);
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
goto out; goto out;
case TCP_SYN_SENT: case TCP_SYN_SENT:
@ -1501,8 +1502,10 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
* clogging syn queue with openreqs with exponentially increasing * clogging syn queue with openreqs with exponentially increasing
* timeout. * timeout.
*/ */
if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
goto drop; goto drop;
}
req = inet_reqsk_alloc(&tcp_request_sock_ops); req = inet_reqsk_alloc(&tcp_request_sock_ops);
if (!req) if (!req)
@ -1667,6 +1670,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
drop_and_free: drop_and_free:
reqsk_free(req); reqsk_free(req);
drop: drop:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
return 0; return 0;
} }
EXPORT_SYMBOL(tcp_v4_conn_request); EXPORT_SYMBOL(tcp_v4_conn_request);

View File

@ -1656,6 +1656,7 @@ static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev)
if (dev->addr_len != IEEE802154_ADDR_LEN) if (dev->addr_len != IEEE802154_ADDR_LEN)
return -1; return -1;
memcpy(eui, dev->dev_addr, 8); memcpy(eui, dev->dev_addr, 8);
eui[0] ^= 2;
return 0; return 0;
} }

View File

@ -380,7 +380,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
if (skb->protocol == htons(ETH_P_IPV6)) { if (skb->protocol == htons(ETH_P_IPV6)) {
sin->sin6_addr = ipv6_hdr(skb)->saddr; sin->sin6_addr = ipv6_hdr(skb)->saddr;
if (np->rxopt.all) if (np->rxopt.all)
datagram_recv_ctl(sk, msg, skb); ip6_datagram_recv_ctl(sk, msg, skb);
if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin->sin6_scope_id = IP6CB(skb)->iif; sin->sin6_scope_id = IP6CB(skb)->iif;
} else { } else {
@ -468,7 +468,8 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
} }
int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) int ip6_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,
struct sk_buff *skb)
{ {
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct inet6_skb_parm *opt = IP6CB(skb); struct inet6_skb_parm *opt = IP6CB(skb);
@ -598,11 +599,12 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
} }
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ip6_datagram_recv_ctl);
int datagram_send_ctl(struct net *net, struct sock *sk, int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
struct msghdr *msg, struct flowi6 *fl6, struct msghdr *msg, struct flowi6 *fl6,
struct ipv6_txoptions *opt, struct ipv6_txoptions *opt,
int *hlimit, int *tclass, int *dontfrag) int *hlimit, int *tclass, int *dontfrag)
{ {
struct in6_pktinfo *src_info; struct in6_pktinfo *src_info;
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
@ -872,4 +874,4 @@ int datagram_send_ctl(struct net *net, struct sock *sk,
exit_f: exit_f:
return err; return err;
} }
EXPORT_SYMBOL_GPL(datagram_send_ctl); EXPORT_SYMBOL_GPL(ip6_datagram_send_ctl);

View File

@ -390,8 +390,8 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
msg.msg_control = (void*)(fl->opt+1); msg.msg_control = (void*)(fl->opt+1);
memset(&flowi6, 0, sizeof(flowi6)); memset(&flowi6, 0, sizeof(flowi6));
err = datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt, &junk, err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt,
&junk, &junk); &junk, &junk, &junk);
if (err) if (err)
goto done; goto done;
err = -EINVAL; err = -EINVAL;

View File

@ -476,8 +476,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
msg.msg_controllen = optlen; msg.msg_controllen = optlen;
msg.msg_control = (void*)(opt+1); msg.msg_control = (void*)(opt+1);
retv = datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk, &junk, retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk,
&junk); &junk, &junk);
if (retv) if (retv)
goto done; goto done;
update: update:
@ -1002,7 +1002,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
release_sock(sk); release_sock(sk);
if (skb) { if (skb) {
int err = datagram_recv_ctl(sk, &msg, skb); int err = ip6_datagram_recv_ctl(sk, &msg, skb);
kfree_skb(skb); kfree_skb(skb);
if (err) if (err)
return err; return err;

View File

@ -507,7 +507,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
sock_recv_ts_and_drops(msg, sk, skb); sock_recv_ts_and_drops(msg, sk, skb);
if (np->rxopt.all) if (np->rxopt.all)
datagram_recv_ctl(sk, msg, skb); ip6_datagram_recv_ctl(sk, msg, skb);
err = copied; err = copied;
if (flags & MSG_TRUNC) if (flags & MSG_TRUNC)
@ -822,8 +822,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
memset(opt, 0, sizeof(struct ipv6_txoptions)); memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(struct ipv6_txoptions); opt->tot_len = sizeof(struct ipv6_txoptions);
err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
&hlimit, &tclass, &dontfrag); &hlimit, &tclass, &dontfrag);
if (err < 0) { if (err < 0) {
fl6_sock_release(flowlabel); fl6_sock_release(flowlabel);
return err; return err;

View File

@ -423,6 +423,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
} }
inet_csk_reqsk_queue_drop(sk, req, prev); inet_csk_reqsk_queue_drop(sk, req, prev);
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
goto out; goto out;
case TCP_SYN_SENT: case TCP_SYN_SENT:
@ -959,8 +960,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
goto drop; goto drop;
} }
if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
goto drop; goto drop;
}
req = inet6_reqsk_alloc(&tcp6_request_sock_ops); req = inet6_reqsk_alloc(&tcp6_request_sock_ops);
if (req == NULL) if (req == NULL)
@ -1109,6 +1112,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
drop_and_free: drop_and_free:
reqsk_free(req); reqsk_free(req);
drop: drop:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
return 0; /* don't send reset */ return 0; /* don't send reset */
} }

View File

@ -467,7 +467,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
ip_cmsg_recv(msg, skb); ip_cmsg_recv(msg, skb);
} else { } else {
if (np->rxopt.all) if (np->rxopt.all)
datagram_recv_ctl(sk, msg, skb); ip6_datagram_recv_ctl(sk, msg, skb);
} }
err = copied; err = copied;
@ -1143,8 +1143,8 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
memset(opt, 0, sizeof(struct ipv6_txoptions)); memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(*opt); opt->tot_len = sizeof(*opt);
err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
&hlimit, &tclass, &dontfrag); &hlimit, &tclass, &dontfrag);
if (err < 0) { if (err < 0) {
fl6_sock_release(flowlabel); fl6_sock_release(flowlabel);
return err; return err;

View File

@ -168,6 +168,51 @@ l2tp_session_id_hash_2(struct l2tp_net *pn, u32 session_id)
} }
/* Lookup the tunnel socket, possibly involving the fs code if the socket is
* owned by userspace. A struct sock returned from this function must be
* released using l2tp_tunnel_sock_put once you're done with it.
*/
struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel)
{
int err = 0;
struct socket *sock = NULL;
struct sock *sk = NULL;
if (!tunnel)
goto out;
if (tunnel->fd >= 0) {
/* Socket is owned by userspace, who might be in the process
* of closing it. Look the socket up using the fd to ensure
* consistency.
*/
sock = sockfd_lookup(tunnel->fd, &err);
if (sock)
sk = sock->sk;
} else {
/* Socket is owned by kernelspace */
sk = tunnel->sock;
}
out:
return sk;
}
EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_lookup);
/* Drop a reference to a tunnel socket obtained via. l2tp_tunnel_sock_put */
void l2tp_tunnel_sock_put(struct sock *sk)
{
struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
if (tunnel) {
if (tunnel->fd >= 0) {
/* Socket is owned by userspace */
sockfd_put(sk->sk_socket);
}
sock_put(sk);
}
}
EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_put);
/* Lookup a session by id in the global session list /* Lookup a session by id in the global session list
*/ */
static struct l2tp_session *l2tp_session_find_2(struct net *net, u32 session_id) static struct l2tp_session *l2tp_session_find_2(struct net *net, u32 session_id)
@ -1607,6 +1652,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
tunnel->old_sk_destruct = sk->sk_destruct; tunnel->old_sk_destruct = sk->sk_destruct;
sk->sk_destruct = &l2tp_tunnel_destruct; sk->sk_destruct = &l2tp_tunnel_destruct;
tunnel->sock = sk; tunnel->sock = sk;
tunnel->fd = fd;
lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock"); lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock");
sk->sk_allocation = GFP_ATOMIC; sk->sk_allocation = GFP_ATOMIC;
@ -1642,24 +1688,32 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
*/ */
int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
{ {
int err = 0; int err = -EBADF;
struct socket *sock = tunnel->sock ? tunnel->sock->sk_socket : NULL; struct socket *sock = NULL;
struct sock *sk = NULL;
sk = l2tp_tunnel_sock_lookup(tunnel);
if (!sk)
goto out;
sock = sk->sk_socket;
BUG_ON(!sock);
/* Force the tunnel socket to close. This will eventually /* Force the tunnel socket to close. This will eventually
* cause the tunnel to be deleted via the normal socket close * cause the tunnel to be deleted via the normal socket close
* mechanisms when userspace closes the tunnel socket. * mechanisms when userspace closes the tunnel socket.
*/ */
if (sock != NULL) { err = inet_shutdown(sock, 2);
err = inet_shutdown(sock, 2);
/* If the tunnel's socket was created by the kernel, /* If the tunnel's socket was created by the kernel,
* close the socket here since the socket was not * close the socket here since the socket was not
* created by userspace. * created by userspace.
*/ */
if (sock->file == NULL) if (sock->file == NULL)
err = inet_release(sock); err = inet_release(sock);
}
l2tp_tunnel_sock_put(sk);
out:
return err; return err;
} }
EXPORT_SYMBOL_GPL(l2tp_tunnel_delete); EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);

View File

@ -188,7 +188,8 @@ struct l2tp_tunnel {
int (*recv_payload_hook)(struct sk_buff *skb); int (*recv_payload_hook)(struct sk_buff *skb);
void (*old_sk_destruct)(struct sock *); void (*old_sk_destruct)(struct sock *);
struct sock *sock; /* Parent socket */ struct sock *sock; /* Parent socket */
int fd; int fd; /* Parent fd, if tunnel socket
* was created by userspace */
uint8_t priv[0]; /* private data */ uint8_t priv[0]; /* private data */
}; };
@ -228,6 +229,8 @@ static inline struct l2tp_tunnel *l2tp_sock_to_tunnel(struct sock *sk)
return tunnel; return tunnel;
} }
extern struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel);
extern void l2tp_tunnel_sock_put(struct sock *sk);
extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id); extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id);
extern struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth); extern struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth);
extern struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname); extern struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname);

View File

@ -554,8 +554,8 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk,
memset(opt, 0, sizeof(struct ipv6_txoptions)); memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(struct ipv6_txoptions); opt->tot_len = sizeof(struct ipv6_txoptions);
err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
&hlimit, &tclass, &dontfrag); &hlimit, &tclass, &dontfrag);
if (err < 0) { if (err < 0) {
fl6_sock_release(flowlabel); fl6_sock_release(flowlabel);
return err; return err;
@ -646,7 +646,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len, int noblock, struct msghdr *msg, size_t len, int noblock,
int flags, int *addr_len) int flags, int *addr_len)
{ {
struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)msg->msg_name; struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)msg->msg_name;
size_t copied = 0; size_t copied = 0;
int err = -EOPNOTSUPP; int err = -EOPNOTSUPP;
@ -688,8 +688,8 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
lsa->l2tp_scope_id = IP6CB(skb)->iif; lsa->l2tp_scope_id = IP6CB(skb)->iif;
} }
if (inet->cmsg_flags) if (np->rxopt.all)
ip_cmsg_recv(msg, skb); ip6_datagram_recv_ctl(sk, msg, skb);
if (flags & MSG_TRUNC) if (flags & MSG_TRUNC)
copied = skb->len; copied = skb->len;

View File

@ -2361,13 +2361,15 @@ static int packet_release(struct socket *sock)
packet_flush_mclist(sk); packet_flush_mclist(sk);
memset(&req_u, 0, sizeof(req_u)); if (po->rx_ring.pg_vec) {
memset(&req_u, 0, sizeof(req_u));
if (po->rx_ring.pg_vec)
packet_set_ring(sk, &req_u, 1, 0); packet_set_ring(sk, &req_u, 1, 0);
}
if (po->tx_ring.pg_vec) if (po->tx_ring.pg_vec) {
memset(&req_u, 0, sizeof(req_u));
packet_set_ring(sk, &req_u, 1, 1); packet_set_ring(sk, &req_u, 1, 1);
}
fanout_release(sk); fanout_release(sk);

View File

@ -438,18 +438,18 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
if (q->rate) { if (q->rate) {
struct sk_buff_head *list = &sch->q; struct sk_buff_head *list = &sch->q;
delay += packet_len_2_sched_time(skb->len, q);
if (!skb_queue_empty(list)) { if (!skb_queue_empty(list)) {
/* /*
* Last packet in queue is reference point (now). * Last packet in queue is reference point (now),
* First packet in queue is already in flight, * calculate this time bonus and subtract
* calculate this time bonus and substract
* from delay. * from delay.
*/ */
delay -= now - netem_skb_cb(skb_peek(list))->time_to_send; delay -= netem_skb_cb(skb_peek_tail(list))->time_to_send - now;
delay = max_t(psched_tdiff_t, 0, delay);
now = netem_skb_cb(skb_peek_tail(list))->time_to_send; now = netem_skb_cb(skb_peek_tail(list))->time_to_send;
} }
delay += packet_len_2_sched_time(skb->len, q);
} }
cb->time_to_send = now + delay; cb->time_to_send = now + delay;

View File

@ -465,7 +465,7 @@ static int svc_udp_get_dest_address4(struct svc_rqst *rqstp,
} }
/* /*
* See net/ipv6/datagram.c : datagram_recv_ctl * See net/ipv6/datagram.c : ip6_datagram_recv_ctl
*/ */
static int svc_udp_get_dest_address6(struct svc_rqst *rqstp, static int svc_udp_get_dest_address6(struct svc_rqst *rqstp,
struct cmsghdr *cmh) struct cmsghdr *cmh)

View File

@ -1358,7 +1358,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
&iwe, IW_EV_UINT_LEN); &iwe, IW_EV_UINT_LEN);
} }
buf = kmalloc(30, GFP_ATOMIC); buf = kmalloc(31, GFP_ATOMIC);
if (buf) { if (buf) {
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;