* linux-next: manual merge of the net-next tree with the net tree
From: Stephen Rothwell @ 2013-02-12 0:57 UTC (permalink / raw)
To: David Miller, netdev
Cc: linux-next, linux-kernel, Yuval Mintz, Michael S. Tsirkin,
Eric Dumazet
[-- Attachment #1: Type: text/plain, Size: 517 bytes --]
Hi all,
Today's linux-next merge of the net-next tree got a conflict in
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c between commit
0aba93e2b9fb ("bnx2x: set gso_type") from the net tree and commit
cbf1de72324a ("bnx2x: fix GRO parameters") from the net-next tree.
I fixed it up (since the former commit says that the latter is the more
complex fix, I just used that) and can carry the fix as necessary (no
action is required).
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: decnet: /proc/sys/net/decnet sysctl entries disappear
From: Ben Hutchings @ 2013-02-12 0:46 UTC (permalink / raw)
To: Larry Baker; +Cc: netdev@vger.kernel.org
In-Reply-To: <FAAC90D7-8126-44CA-AACF-A5F8237C1A8E@usgs.gov>
Please read and follow the advice in Documentation/SubmittingPatches,
including in particular about the Developer's Certificate of Origin.
On Tue, 2013-02-12 at 00:26 +0000, Larry Baker wrote:
[...]
> Other changes are:
>
> . Updated banner
> . DECnet device up/down KERN_INFO messages
> . debug module parameter
> . NETDEV_UP/DOWN KERN_DEBUG messages if (debug & 8)
> . dn_route.c uses dn_hiord[ETH_ALEN] in dn_dev.c
Each patch should do one thing. So send one patch with the sysctl
patch, and additional patches for the other changes.
> --- original/net/decnet/af_decnet.c
> +++ patched/net/decnet/af_decnet.c
> @@ -1,2 +1 @@
> -
> /*
> @@ -42,2 +41,5 @@
> * prepare for sendpage etc.
> + * Larry Baker : Register static /proc/sys/net/decnet entries before
> + * dynamic /proc/sys/net/decnet/conf entries in
> + * dn_dev_init().
> */
[...]
There is no log changes in file headers; this information is all
recorded by the git version control system.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH] atl1c: add error checking for pci_map_single functions
From: xiong @ 2013-02-12 0:44 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-kernel, qca-linux-team, nic-devel, jwboyer, xiong
it is reported that code hit DMA-API errors on 3.8-rc6+,
(see https://bugzilla.redhat.com/show_bug.cgi?id=908436, and
https://bugzilla.redhat.com/show_bug.cgi?id=908550)
this patch just adds error handler for
pci_map_single and skb_frag_dma_map.
Signed-off-by: xiong <xiong@qca.qualcomm.com>
---
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 71 ++++++++++++++++++++++---
1 file changed, 64 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 571b514..8f33315 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -21,7 +21,7 @@
#include "atl1c.h"
-#define ATL1C_DRV_VERSION "1.0.1.0-NAPI"
+#define ATL1C_DRV_VERSION "1.0.1.1-NAPI"
char atl1c_driver_name[] = "atl1c";
char atl1c_driver_version[] = ATL1C_DRV_VERSION;
@@ -1649,6 +1649,7 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter)
u16 num_alloc = 0;
u16 rfd_next_to_use, next_next;
struct atl1c_rx_free_desc *rfd_desc;
+ dma_addr_t mapping;
next_next = rfd_next_to_use = rfd_ring->next_to_use;
if (++next_next == rfd_ring->count)
@@ -1675,9 +1676,18 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter)
ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
buffer_info->skb = skb;
buffer_info->length = adapter->rx_buffer_len;
- buffer_info->dma = pci_map_single(pdev, vir_addr,
+ mapping = pci_map_single(pdev, vir_addr,
buffer_info->length,
PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(pdev, mapping))) {
+ dev_kfree_skb(skb);
+ buffer_info->skb = NULL;
+ buffer_info->length = 0;
+ ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
+ netif_warn(adapter, rx_err, adapter->netdev, "RX pci_map_single failed");
+ break;
+ }
+ buffer_info->dma = mapping;
ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
ATL1C_PCIMAP_FROMDEVICE);
rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -2012,7 +2022,29 @@ check_sum:
return 0;
}
-static void atl1c_tx_map(struct atl1c_adapter *adapter,
+static void atl1c_tx_rollback(struct atl1c_adapter *adpt,
+ struct atl1c_tpd_desc *first_tpd,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adpt->tpd_ring[type];
+ struct atl1c_buffer *buffer_info;
+ struct atl1c_tpd_desc *tpd;
+ u16 first_index, index;
+
+ first_index = first_tpd - (struct atl1c_tpd_desc *)tpd_ring->desc;
+ index = first_index;
+ while (index != tpd_ring->next_to_use) {
+ tpd = ATL1C_TPD_DESC(tpd_ring, index);
+ buffer_info = &tpd_ring->buffer_info[index];
+ atl1c_clean_buffer(adpt->pdev, buffer_info, 0);
+ memset(tpd, 0, sizeof(struct atl1c_tpd_desc));
+ if (++index == tpd_ring->count)
+ index = 0;
+ }
+ tpd_ring->next_to_use = first_index;
+}
+
+static int atl1c_tx_map(struct atl1c_adapter *adapter,
struct sk_buff *skb, struct atl1c_tpd_desc *tpd,
enum atl1c_trans_queue type)
{
@@ -2037,7 +2069,10 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
buffer_info->length = map_len;
buffer_info->dma = pci_map_single(adapter->pdev,
skb->data, hdr_len, PCI_DMA_TODEVICE);
- ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+ if (unlikely(pci_dma_mapping_error(adapter->pdev,
+ buffer_info->dma)))
+ goto err_dma;
+
ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
ATL1C_PCIMAP_TODEVICE);
mapped_len += map_len;
@@ -2059,6 +2094,10 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
buffer_info->dma =
pci_map_single(adapter->pdev, skb->data + mapped_len,
buffer_info->length, PCI_DMA_TODEVICE);
+ if (unlikely(pci_dma_mapping_error(adapter->pdev,
+ buffer_info->dma)))
+ goto err_dma;
+
ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
ATL1C_PCIMAP_TODEVICE);
@@ -2080,6 +2119,9 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
frag, 0,
buffer_info->length,
DMA_TO_DEVICE);
+ if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma))
+ goto err_dma;
+
ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_PAGE,
ATL1C_PCIMAP_TODEVICE);
@@ -2092,6 +2134,13 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter,
/* The last buffer info contain the skb address,
so it will be free after unmap */
buffer_info->skb = skb;
+
+ return 0;
+
+err_dma:
+ buffer_info->dma = 0;
+ buffer_info->length = 0;
+ return -1;
}
static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
@@ -2154,10 +2203,18 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
if (skb_network_offset(skb) != ETH_HLEN)
tpd->word1 |= 1 << TPD_ETH_TYPE_SHIFT; /* Ethernet frame */
- atl1c_tx_map(adapter, skb, tpd, type);
- atl1c_tx_queue(adapter, skb, tpd, type);
+ if (atl1c_tx_map(adapter, skb, tpd, type) < 0) {
+ netif_info(adapter, tx_done, adapter->netdev,
+ "tx-skb droppted due to dma error\n");
+ /* roll back tpd/buffer */
+ atl1c_tx_rollback(adapter, tpd, type);
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ dev_kfree_skb(skb);
+ } else {
+ atl1c_tx_queue(adapter, skb, tpd, type);
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ }
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
return NETDEV_TX_OK;
}
--
1.7.11.7
^ permalink raw reply related
* decnet: /proc/sys/net/decnet sysctl entries disappear
From: Larry Baker @ 2013-02-12 0:26 UTC (permalink / raw)
To: netdev
[-- Attachment #1: Type: text/plain, Size: 401 bytes --]
Beginning with kernel 2.6.27, the decnet kernel module /proc/sys/net/decnet sysctl entries disappear. With the generous assistance of Eric Biederman, I have developed these patches to restore the previous behavior and add minor features. (N.b, Eric verified kernel 3.4-rc1 no longer has this behavior.)
I have developed three sets of patches, to account for changes in the kernel networking APIs.
[-- Attachment #2: linux-2.6.27-decnet-sysctl.patch --]
[-- Type: application/octet-stream, Size: 7709 bytes --]
Title
linux-2.6.27-decnet-sysctl.patch
decnet kernel module patches for Linux 2.6.27 through 2.6.32
Author
Larry Baker
US Geological Survey
baker@usgs.gov
Description
The decnet kernel module is configured using entries under /proc/sys/net/decnet.
There are executor settings in /proc/sys/net/decnet, template device settings
in /proc/sys/net/decnet/conf/{ddcmp,ethernet,ipgre,loopback}, and active device
settings for DECnet devices in /proc/sys/net/decnet/conf/{lo,eth0,...}. All
Ethernet interfaces and the loopback interface are configured as DECnet devices
when the decnet kernel module is loaded.
The executor settings and template device settings are static; active device
settings are dynamic. The active device settings for a network device are
copied from the appropriate template device settings when the network device is
configured as a DECnet device. The active device settings are discarded when a
DECnet device is unconfigured (e.g., when the DECnet node address is set).
When the DECnet node address is set (e.g., by writing the new address to
/proc/sys/net/decnet/node_address) all DECnet devices are unconfigured, the new
DECnet node address is saved, and all Ethernet interfaces and the loopback
interface are reconfigured as DECnet devices.
When a DECnet device is unconfigured, its active device settings entries are
unregistered from the sysctl network namespace (/proc/sys/net). When a DECnet
device is reconfigured, its active device settings entries are reregistered.
In kernel 2.6.27 the sysctl data structures were changed from a list to a tree.
The registration/unregistration behavior also changed. As a result, when any
active device settings entries are unregistered, all the decnet kernel module
configuration settings entries in the sysctl network namespace are no longer
visible. The only entries that are visible are the active device settings
entries that are reregistered when the DECnet devices are reconfigured.
The fix is to register an empty static /proc/sys/net/decnet/conf entry (ala
mkdir) before any of the (static or dynamic) entries beneath it are registered.
This workaround is not needed in 3.4 and later kernels.
After this patch, the registration order for sysctl entries is:
. Static executor entries in /proc/sys/net/decnet
. Static empty path entry /proc/sys/net/decnet/conf
. Static template device entries in /proc/sys/net/decnet/conf/<type>
. Dynamic active device entries in /proc/sys/net/decnet/conf/<dev-name>
Unregistration order is the reverse.
Other changes are:
. Updated banner
. DECnet device up/down KERN_INFO messages
. debug module parameter
. NETDEV_UP/DOWN KERN_DEBUG messages if (debug & 8)
. dn_route.c uses dn_hiord[ETH_ALEN] in dn_dev.c
--- original/net/decnet/af_decnet.c
+++ patched/net/decnet/af_decnet.c
@@ -1,2 +1 @@
-
/*
@@ -42,2 +41,5 @@
* prepare for sendpage etc.
+ * Larry Baker : Register static /proc/sys/net/decnet entries before
+ * dynamic /proc/sys/net/decnet/conf entries in
+ * dn_dev_init().
*/
@@ -2090,2 +2092,4 @@
case NETDEV_UP:
+ if (decnet_debug_level & 8)
+ printk(KERN_DEBUG "DECnet: %s NETDEV_UP", dev->name);
dn_dev_up(dev);
@@ -2093,2 +2097,4 @@
case NETDEV_DOWN:
+ if (decnet_debug_level & 8)
+ printk(KERN_DEBUG "DECnet: %s NETDEV_DOWN", dev->name);
dn_dev_down(dev);
@@ -2363,3 +2369,3 @@
-static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n";
+static char banner[] __initdata = KERN_INFO "DECnet: DECnet for Linux: V.2.6.27 (C) 1995-2013 Linux DECnet Project Team\n";
@@ -2375,2 +2381,4 @@
+ dn_register_sysctl();
+
dn_neigh_init();
@@ -2385,3 +2393,2 @@
proc_net_fops_create(&init_net, "decnet", S_IRUGO, &dn_socket_seq_fops);
- dn_register_sysctl();
out:
@@ -2404,4 +2411,2 @@
- dn_unregister_sysctl();
-
unregister_netdevice_notifier(&dn_dev_notifier);
@@ -2413,2 +2418,4 @@
+ dn_unregister_sysctl();
+
proc_net_remove(&init_net, "decnet");
--- original/net/decnet/dn_dev.c
+++ patched/net/decnet/dn_dev.c
@@ -24,2 +24,6 @@
* devices. All mtu based now.
+ * Larry Baker : Register empty static /proc/sys/net/decnet/conf
+ * before registering any entries beneath it due to
+ * tree-based sysctl tables since kernel 2.6.27.
+ * Workaround not needed in 3.4 and later kernels.
*/
@@ -60,3 +64,3 @@
static char dn_rt_all_rt_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x03,0x00,0x00};
-static char dn_hiord[ETH_ALEN] = {0xAA,0x00,0x04,0x00,0x00,0x00};
+unsigned char dn_hiord[ETH_ALEN] = {0xAA,0x00,0x04,0x00,0x00,0x00};
static unsigned char dn_eco_version[3] = {0x02,0x00,0x00};
@@ -172,2 +176,4 @@
+static struct ctl_table_header *dn_conf_path = NULL;
+
static struct dn_dev_sysctl_table {
@@ -224,2 +230,13 @@
+static ctl_table empty[] = {
+ { }
+};
+
+static struct ctl_path dn_conf[] = {
+ { .procname = "net", .ctl_name = CTL_NET, },
+ { .procname = "decnet", .ctl_name = NET_DECNET, },
+ { .procname = "conf", .ctl_name = NET_DECNET_CONF, },
+ { },
+};
+
static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms)
@@ -1176,2 +1193,3 @@
struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;
+ char dn_ascbuf[DN_ASCBUF_LEN];
@@ -1213,2 +1231,5 @@
+ dn_addr2asc(le16_to_cpu(addr), dn_ascbuf);
+ printk(KERN_INFO "DECnet: %s up [%s]", dev->name, dn_ascbuf);
+
/*
@@ -1256,2 +1277,3 @@
struct dn_ifaddr *ifa;
+ __le16 addr = decnet_address;
@@ -1266,2 +1288,14 @@
dn_dev_delete(dev);
+
+ if (dev->type == ARPHRD_ETHER) {
+ if (memcmp(dev->dev_addr, dn_hiord, 4) != 0)
+ return;
+ addr = dn_eth2dn(dev->dev_addr);
+ }
+
+ if (addr == 0)
+ return;
+
+ printk(KERN_INFO "DECnet: %s down", dev->name);
+
}
@@ -1432,2 +1466,6 @@
+static int debug = 0;
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "Debug level");
+
static int addr[2];
@@ -1438,2 +1476,4 @@
{
+ decnet_debug_level = debug;
+
if (addr[0] > 63 || addr[0] < 0) {
@@ -1450,11 +1490,4 @@
- dn_dev_devices_on();
-
- rtnl_register(PF_DECnet, RTM_NEWADDR, dn_nl_newaddr, NULL);
- rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL);
- rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr);
-
- proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops);
-
#ifdef CONFIG_SYSCTL
+ dn_conf_path = register_sysctl_paths(dn_conf, empty);
{
@@ -1465,2 +1498,10 @@
#endif /* CONFIG_SYSCTL */
+
+ dn_dev_devices_on();
+
+ rtnl_register(PF_DECnet, RTM_NEWADDR, dn_nl_newaddr, NULL);
+ rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL);
+ rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr);
+
+ proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops);
}
@@ -1469,2 +1510,6 @@
{
+ proc_net_remove(&init_net, "decnet_dev");
+
+ dn_dev_devices_off();
+
#ifdef CONFIG_SYSCTL
@@ -1475,7 +1520,4 @@
}
+ unregister_sysctl_table(dn_conf_path);
#endif /* CONFIG_SYSCTL */
-
- proc_net_remove(&init_net, "decnet_dev");
-
- dn_dev_devices_off();
}
--- original/net/decnet/dn_route.c
+++ patched/net/decnet/dn_route.c
@@ -100,4 +100,3 @@
-
-static unsigned char dn_hiord_addr[6] = {0xAA,0x00,0x04,0x00,0x00,0x00};
+extern unsigned char dn_hiord[ETH_ALEN];
@@ -504,3 +504,3 @@
cb->dst = dn_eth2dn(ptr);
- if (memcmp(ptr, dn_hiord_addr, 4) != 0)
+ if (memcmp(ptr, dn_hiord, 4) != 0)
goto drop_it;
@@ -512,3 +512,3 @@
cb->src = dn_eth2dn(ptr);
- if (memcmp(ptr, dn_hiord_addr, 4) != 0)
+ if (memcmp(ptr, dn_hiord, 4) != 0)
goto drop_it;
[-- Attachment #3: linux-2.6.33-decnet-sysctl.patch --]
[-- Type: application/octet-stream, Size: 7704 bytes --]
Title
linux-2.6.33-decnet-sysctl.patch
decnet kernel module patches for Linux 2.6.33 through 3.4.x
Author
Larry Baker
US Geological Survey
baker@usgs.gov
Description
The decnet kernel module is configured using entries under /proc/sys/net/decnet.
There are executor settings in /proc/sys/net/decnet, template device settings
in /proc/sys/net/decnet/conf/{ddcmp,ethernet,ipgre,loopback}, and active device
settings for DECnet devices in /proc/sys/net/decnet/conf/{lo,eth0,...}. All
Ethernet interfaces and the loopback interface are configured as DECnet devices
when the decnet kernel module is loaded.
The executor settings and template device settings are static; active device
settings are dynamic. The active device settings for a network device are
copied from the appropriate template device settings when the network device is
configured as a DECnet device. The active device settings are discarded when a
DECnet device is unconfigured (e.g., when the DECnet node address is set).
When the DECnet node address is set (e.g., by writing the new address to
/proc/sys/net/decnet/node_address) all DECnet devices are unconfigured, the new
DECnet node address is saved, and all Ethernet interfaces and the loopback
interface are reconfigured as DECnet devices.
When a DECnet device is unconfigured, its active device settings entries are
unregistered from the sysctl network namespace (/proc/sys/net). When a DECnet
device is reconfigured, its active device settings entries are reregistered.
In kernel 2.6.27 the sysctl data structures were changed from a list to a tree.
The registration/unregistration behavior also changed. As a result, when any
active device settings entries are unregistered, all the decnet kernel module
configuration settings entries in the sysctl network namespace are no longer
visible. The only entries that are visible are the active device settings
entries that are reregistered when the DECnet devices are reconfigured.
The fix is to register an empty static /proc/sys/net/decnet/conf entry (ala
mkdir) before any of the (static or dynamic) entries beneath it are registered.
This workaround is not needed in 3.4 and later kernels.
After this patch, the registration order for sysctl entries is:
. Static executor entries in /proc/sys/net/decnet
. Static empty path entry /proc/sys/net/decnet/conf
. Static template device entries in /proc/sys/net/decnet/conf/<type>
. Dynamic active device entries in /proc/sys/net/decnet/conf/<dev-name>
Unregistration order is the reverse.
Other changes are:
. Updated banner
. DECnet device up/down KERN_INFO messages
. debug module parameter
. NETDEV_UP/DOWN KERN_DEBUG messages if (debug & 8)
. dn_route.c uses dn_hiord[ETH_ALEN] in dn_dev.c
--- original/net/decnet/af_decnet.c
+++ patched/net/decnet/af_decnet.c
@@ -1,2 +1 @@
-
/*
@@ -42,2 +41,5 @@
* prepare for sendpage etc.
+ * Larry Baker : Register static /proc/sys/net/decnet entries before
+ * dynamic /proc/sys/net/decnet/conf entries in
+ * dn_dev_init().
*/
@@ -2091,2 +2093,4 @@
case NETDEV_UP:
+ if (decnet_debug_level & 8)
+ printk(KERN_DEBUG "DECnet: %s NETDEV_UP", dev->name);
dn_dev_up(dev);
@@ -2094,2 +2098,4 @@
case NETDEV_DOWN:
+ if (decnet_debug_level & 8)
+ printk(KERN_DEBUG "DECnet: %s NETDEV_DOWN", dev->name);
dn_dev_down(dev);
@@ -2364,3 +2370,3 @@
-static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n";
+static char banner[] __initdata = KERN_INFO "DECnet: DECnet for Linux: V.2.6.33 (C) 1995-2013 Linux DECnet Project Team\n";
@@ -2376,2 +2382,4 @@
+ dn_register_sysctl();
+
dn_neigh_init();
@@ -2386,3 +2394,2 @@
proc_net_fops_create(&init_net, "decnet", S_IRUGO, &dn_socket_seq_fops);
- dn_register_sysctl();
out:
@@ -2405,4 +2412,2 @@
- dn_unregister_sysctl();
-
unregister_netdevice_notifier(&dn_dev_notifier);
@@ -2414,2 +2419,4 @@
+ dn_unregister_sysctl();
+
proc_net_remove(&init_net, "decnet");
--- original/net/decnet/dn_dev.c
+++ patched/net/decnet/dn_dev.c
@@ -24,2 +24,6 @@
* devices. All mtu based now.
+ * Larry Baker : Register empty static /proc/sys/net/decnet/conf
+ * before registering any entries beneath it due to
+ * tree-based sysctl tables since kernel 2.6.27.
+ * Workaround not needed in 3.4 and later kernels.
*/
@@ -61,3 +65,3 @@
static char dn_rt_all_rt_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x03,0x00,0x00};
-static char dn_hiord[ETH_ALEN] = {0xAA,0x00,0x04,0x00,0x00,0x00};
+unsigned char dn_hiord[ETH_ALEN] = {0xAA,0x00,0x04,0x00,0x00,0x00};
static unsigned char dn_eco_version[3] = {0x02,0x00,0x00};
@@ -163,2 +167,5 @@
void __user *, size_t *, loff_t *);
+
+static struct ctl_table_header *dn_conf_path = NULL;
+
static struct dn_dev_sysctl_table {
@@ -207,2 +214,13 @@
+static ctl_table empty[] = {
+ { }
+};
+
+static struct ctl_path dn_conf[] = {
+ { .procname = "net", },
+ { .procname = "decnet", },
+ { .procname = "conf", },
+ { },
+};
+
static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms)
@@ -1143,2 +1161,3 @@
struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
+ char dn_ascbuf[DN_ASCBUF_LEN];
@@ -1180,2 +1199,5 @@
+ dn_addr2asc(le16_to_cpu(addr), dn_ascbuf);
+ printk(KERN_INFO "DECnet: %s up [%s]", dev->name, dn_ascbuf);
+
/*
@@ -1223,2 +1245,3 @@
struct dn_ifaddr *ifa;
+ __le16 addr = decnet_address;
@@ -1233,2 +1256,14 @@
dn_dev_delete(dev);
+
+ if (dev->type == ARPHRD_ETHER) {
+ if (memcmp(dev->dev_addr, dn_hiord, 4) != 0)
+ return;
+ addr = dn_eth2dn(dev->dev_addr);
+ }
+
+ if (addr == 0)
+ return;
+
+ printk(KERN_INFO "DECnet: %s down", dev->name);
+
}
@@ -1396,2 +1431,6 @@
+static int debug = 0;
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "Debug level");
+
static int addr[2];
@@ -1402,2 +1441,4 @@
{
+ decnet_debug_level = debug;
+
if (addr[0] > 63 || addr[0] < 0) {
@@ -1414,11 +1455,4 @@
- dn_dev_devices_on();
-
- rtnl_register(PF_DECnet, RTM_NEWADDR, dn_nl_newaddr, NULL, NULL);
- rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL, NULL);
- rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr, NULL);
-
- proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops);
-
#ifdef CONFIG_SYSCTL
+ dn_conf_path = register_sysctl_paths(dn_conf, empty);
{
@@ -1429,2 +1463,10 @@
#endif /* CONFIG_SYSCTL */
+
+ dn_dev_devices_on();
+
+ rtnl_register(PF_DECnet, RTM_NEWADDR, dn_nl_newaddr, NULL, NULL);
+ rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL, NULL);
+ rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr, NULL);
+
+ proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops);
}
@@ -1433,2 +1475,6 @@
{
+ proc_net_remove(&init_net, "decnet_dev");
+
+ dn_dev_devices_off();
+
#ifdef CONFIG_SYSCTL
@@ -1439,7 +1485,4 @@
}
+ unregister_sysctl_table(dn_conf_path);
#endif /* CONFIG_SYSCTL */
-
- proc_net_remove(&init_net, "decnet_dev");
-
- dn_dev_devices_off();
}
--- original/net/decnet/dn_route.c
+++ patched/net/decnet/dn_route.c
@@ -101,4 +101,3 @@
-
-static unsigned char dn_hiord_addr[6] = {0xAA,0x00,0x04,0x00,0x00,0x00};
+extern unsigned char dn_hiord[ETH_ALEN];
@@ -527,3 +526,3 @@
cb->dst = dn_eth2dn(ptr);
- if (memcmp(ptr, dn_hiord_addr, 4) != 0)
+ if (memcmp(ptr, dn_hiord, 4) != 0)
goto drop_it;
@@ -535,3 +534,3 @@
cb->src = dn_eth2dn(ptr);
- if (memcmp(ptr, dn_hiord_addr, 4) != 0)
+ if (memcmp(ptr, dn_hiord, 4) != 0)
goto drop_it;
[-- Attachment #4: linux-3.5-decnet-sysctl.patch --]
[-- Type: application/octet-stream, Size: 8165 bytes --]
Title
linux-3.5-decnet-sysctl.patch
decnet kernel module patches for Linux 3.5 and later
Author
Larry Baker
US Geological Survey
baker@usgs.gov
Description
The decnet kernel module is configured using entries under /proc/sys/net/decnet.
There are executor settings in /proc/sys/net/decnet, template device settings
in /proc/sys/net/decnet/conf/{ddcmp,ethernet,ipgre,loopback}, and active device
settings for DECnet devices in /proc/sys/net/decnet/conf/{lo,eth0,...}. All
Ethernet interfaces and the loopback interface are configured as DECnet devices
when the decnet kernel module is loaded.
The executor settings and template device settings are static; active device
settings are dynamic. The active device settings for a network device are
copied from the appropriate template device settings when the network device is
configured as a DECnet device. The active device settings are discarded when a
DECnet device is unconfigured (e.g., when the DECnet node address is set).
When the DECnet node address is set (e.g., by writing the new address to
/proc/sys/net/decnet/node_address) all DECnet devices are unconfigured, the new
DECnet node address is saved, and all Ethernet interfaces and the loopback
interface are reconfigured as DECnet devices.
When a DECnet device is unconfigured, its active device settings entries are
unregistered from the sysctl network namespace (/proc/sys/net). When a DECnet
device is reconfigured, its active device settings entries are reregistered.
In kernel 2.6.27 the sysctl data structures were changed from a list to a tree.
The registration/unregistration behavior also changed. As a result, when any
active device settings entries are unregistered, all the decnet kernel module
configuration settings entries in the sysctl network namespace are no longer
visible. The only entries that are visible are the active device settings
entries that are reregistered when the DECnet devices are reconfigured.
The fix is to register an empty static /proc/sys/net/decnet/conf entry (ala
mkdir) before any of the (static or dynamic) entries beneath it are registered.
This workaround is not needed in 3.4 and later kernels.
After this patch, the registration order for sysctl entries is:
. Static executor entries in /proc/sys/net/decnet
. Static empty path entry /proc/sys/net/decnet/conf
. Static template device entries in /proc/sys/net/decnet/conf/<type>
. Dynamic active device entries in /proc/sys/net/decnet/conf/<dev-name>
Unregistration order is the reverse.
Other changes are:
. Updated banner
. DECnet device up/down KERN_INFO messages
. debug module parameter
. NETDEV_UP/DOWN KERN_DEBUG messages if (debug & 8)
. dn_route.c uses dn_hiord[ETH_ALEN] in dn_dev.c
--- original/net/decnet/af_decnet.c
+++ patched/net/decnet/af_decnet.c
@@ -1,2 +1 @@
-
/*
@@ -42,2 +41,5 @@
* prepare for sendpage etc.
+ * Larry Baker : Register static /proc/sys/net/decnet entries before
+ * dynamic /proc/sys/net/decnet/conf entries in
+ * dn_dev_init().
*/
@@ -2090,2 +2092,4 @@
case NETDEV_UP:
+ if (decnet_debug_level & 8)
+ printk(KERN_DEBUG "DECnet: %s NETDEV_UP", dev->name);
dn_dev_up(dev);
@@ -2093,2 +2097,4 @@
case NETDEV_DOWN:
+ if (decnet_debug_level & 8)
+ printk(KERN_DEBUG "DECnet: %s NETDEV_DOWN", dev->name);
dn_dev_down(dev);
@@ -2363,3 +2369,3 @@
-static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n";
+static char banner[] __initdata = KERN_INFO "DECnet: DECnet for Linux: V.3.5 (C) 1995-2013 Linux DECnet Project Team\n";
@@ -2375,2 +2381,4 @@
+ dn_register_sysctl();
+
dn_neigh_init();
@@ -2385,3 +2393,2 @@
proc_net_fops_create(&init_net, "decnet", S_IRUGO, &dn_socket_seq_fops);
- dn_register_sysctl();
out:
@@ -2404,4 +2411,2 @@
- dn_unregister_sysctl();
-
unregister_netdevice_notifier(&dn_dev_notifier);
@@ -2413,2 +2418,4 @@
+ dn_unregister_sysctl();
+
proc_net_remove(&init_net, "decnet");
--- original/net/decnet/dn_dev.c
+++ patched/net/decnet/dn_dev.c
@@ -24,2 +24,6 @@
* devices. All mtu based now.
+ * Larry Baker : Register empty static /proc/sys/net/decnet/conf
+ * before registering any entries beneath it due to
+ * tree-based sysctl tables since kernel 2.6.27.
+ * Workaround not needed in 3.4 and later kernels.
*/
@@ -60,3 +64,3 @@
static char dn_rt_all_rt_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x03,0x00,0x00};
-static char dn_hiord[ETH_ALEN] = {0xAA,0x00,0x04,0x00,0x00,0x00};
+unsigned char dn_hiord[ETH_ALEN] = {0xAA,0x00,0x04,0x00,0x00,0x00};
static unsigned char dn_eco_version[3] = {0x02,0x00,0x00};
@@ -162,2 +166,5 @@
void __user *, size_t *, loff_t *);
+
+static struct ctl_table_header *dn_conf_path = NULL;
+
static struct dn_dev_sysctl_table {
@@ -206,2 +213,8 @@
+static ctl_table empty[] = {
+ { }
+};
+
+static const char dn_conf[] = "net/decnet/conf";
+
static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms)
@@ -211,3 +224,3 @@
- char path[sizeof("net/decnet/conf/") + IFNAMSIZ];
+ char dn_ctl_path[sizeof(dn_conf) + 1 + IFNAMSIZ];
@@ -222,4 +235,4 @@
- snprintf(path, sizeof(path), "net/decnet/conf/%s",
- dev? dev->name : parms->name);
+ snprintf(dn_ctl_path, sizeof(dn_ctl_path), "%s/%s", dn_conf,
+ dev ? dev->name : parms->name);
@@ -227,3 +240,3 @@
- t->sysctl_header = register_net_sysctl(&init_net, path, t->dn_dev_vars);
+ t->sysctl_header = register_net_sysctl(&init_net, dn_ctl_path, t->dn_dev_vars);
if (t->sysctl_header == NULL)
@@ -1131,2 +1144,3 @@
struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr);
+ char dn_ascbuf[DN_ASCBUF_LEN];
@@ -1168,2 +1182,5 @@
+ dn_addr2asc(le16_to_cpu(addr), dn_ascbuf);
+ printk(KERN_INFO "DECnet: %s up [%s]", dev->name, dn_ascbuf);
+
/*
@@ -1211,2 +1228,3 @@
struct dn_ifaddr *ifa;
+ __le16 addr = decnet_address;
@@ -1221,2 +1239,14 @@
dn_dev_delete(dev);
+
+ if (dev->type == ARPHRD_ETHER) {
+ if (memcmp(dev->dev_addr, dn_hiord, 4) != 0)
+ return;
+ addr = dn_eth2dn(dev->dev_addr);
+ }
+
+ if (addr == 0)
+ return;
+
+ printk(KERN_INFO "DECnet: %s down", dev->name);
+
}
@@ -1384,2 +1414,6 @@
+static int debug = 0;
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "Debug level");
+
static int addr[2];
@@ -1390,2 +1424,4 @@
{
+ decnet_debug_level = debug;
+
if (addr[0] > 63 || addr[0] < 0) {
@@ -1402,11 +1438,4 @@
- dn_dev_devices_on();
-
- rtnl_register(PF_DECnet, RTM_NEWADDR, dn_nl_newaddr, NULL, NULL);
- rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL, NULL);
- rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr, NULL);
-
- proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops);
-
#ifdef CONFIG_SYSCTL
+ dn_conf_path = register_net_sysctl(&init_net, dn_conf, empty);
{
@@ -1417,2 +1446,10 @@
#endif /* CONFIG_SYSCTL */
+
+ dn_dev_devices_on();
+
+ rtnl_register(PF_DECnet, RTM_NEWADDR, dn_nl_newaddr, NULL, NULL);
+ rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL, NULL);
+ rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr, NULL);
+
+ proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops);
}
@@ -1421,2 +1458,6 @@
{
+ proc_net_remove(&init_net, "decnet_dev");
+
+ dn_dev_devices_off();
+
#ifdef CONFIG_SYSCTL
@@ -1427,7 +1468,4 @@
}
+ unregister_net_sysctl_table(dn_conf_path);
#endif /* CONFIG_SYSCTL */
-
- proc_net_remove(&init_net, "decnet_dev");
-
- dn_dev_devices_off();
}
--- original/net/decnet/dn_route.c
+++ patched/net/decnet/dn_route.c
@@ -102,4 +102,3 @@
-
-static unsigned char dn_hiord_addr[6] = {0xAA,0x00,0x04,0x00,0x00,0x00};
+extern unsigned char dn_hiord[ETH_ALEN];
@@ -528,3 +527,3 @@
cb->dst = dn_eth2dn(ptr);
- if (memcmp(ptr, dn_hiord_addr, 4) != 0)
+ if (memcmp(ptr, dn_hiord, 4) != 0)
goto drop_it;
@@ -536,3 +535,3 @@
cb->src = dn_eth2dn(ptr);
- if (memcmp(ptr, dn_hiord_addr, 4) != 0)
+ if (memcmp(ptr, dn_hiord, 4) != 0)
goto drop_it;
[-- Attachment #5: Type: text/plain, Size: 3815 bytes --]
. linux-2.6.27-decnet-sysctl.patch
decnet kernel module patches for Linux 2.6.27 through 2.6.32 (tree-structured sysctl, struct ctl_path includes .ctl_name)
. linux-2.6.33-decnet-sysctl.patch
decnet kernel module patches for Linux 2.6.33 through 3.4.x (struct ctl_path no longer includes .ctl_name, rtnl_register() adds rtnl_calcit_func calcit)
. linux-3.5-decnet-sysctl.patch
decnet kernel module patches for Linux 3.5 and later (register_net_sysctl()/unregister_net_sysctl_table() in place of register_sysctl_paths()/unregister_sysctl_table())
I am running linux-2.6.27-decnet-sysctl.patch on a CentOS 6.3 x86_64 system (Linux atompc.wr.usgs.gov 2.6.32-279.19.1.el6.x86_64 #1 SMP Wed Dec 19 07:05:20 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux).
I am running linux-2.6.33-decnet-sysctl.patch on an Arch Linux ARM 3.1.10 system (Linux sheeva 3.1.10-15-ARCH #1 PREEMPT Wed Dec 12 15:25:18 UTC 2012 armv5tel GNU/Linux).
I do not have the ability to test linux-3.5-decnet-sysctl.patch. I compared linux-2.6.33-decnet-sysctl.patch to linux-3.5-decnet-sysctl.patch, and inspected the patched files visually.
Description
The decnet kernel module is configured using entries under /proc/sys/net/decnet. There are executor settings in /proc/sys/net/decnet, template device settings in /proc/sys/net/decnet/conf/{ddcmp,ethernet,ipgre,loopback}, and active device settings for DECnet devices in /proc/sys/net/decnet/conf/{lo,eth0,...}. All Ethernet interfaces and the loopback interface are configured as DECnet devices when the decnet kernel module is loaded.
The executor settings and template device settings are static; active device settings are dynamic. The active device settings for a network device are copied from the appropriate template device settings when the network device is configured as a DECnet device. The active device settings are discarded when a DECnet device is unconfigured (e.g., when the DECnet node address is set).
When the DECnet node address is set (e.g., by writing the new address to /proc/sys/net/decnet/node_address) all DECnet devices are unconfigured, the new DECnet node address is saved, and all Ethernet interfaces and the loopback interface are reconfigured as DECnet devices.
When a DECnet device is unconfigured, its active device settings entries are unregistered from the sysctl network namespace (/proc/sys/net). When a DECnet device is reconfigured, its active device settings entries are reregistered.
In kernel 2.6.27 the sysctl data structures were changed from a list to a tree. The registration/unregistration behavior also changed. As a result, when any active device settings entries are unregistered, all the decnet kernel module configuration settings entries in the sysctl network namespace are no longer visible. The only entries that are visible are the active device settings entries that are reregistered when the DECnet devices are reconfigured.
The fix is to register an empty static /proc/sys/net/decnet/conf entry (ala mkdir) before any of the (static or dynamic) entries beneath it are registered. This workaround is not needed in 3.4 and later kernels.
After this patch, the registration order for sysctl entries is:
. Static executor entries in /proc/sys/net/decnet
. Static empty path entry /proc/sys/net/decnet/conf
. Static template device entries in /proc/sys/net/decnet/conf/<type>
. Dynamic active device entries in /proc/sys/net/decnet/conf/<dev-name>
Unregistration order is the reverse.
Other changes are:
. Updated banner
. DECnet device up/down KERN_INFO messages
. debug module parameter
. NETDEV_UP/DOWN KERN_DEBUG messages if (debug & 8)
. dn_route.c uses dn_hiord[ETH_ALEN] in dn_dev.c
Larry Baker
US Geological Survey
650-329-5608
baker@usgs.gov
^ permalink raw reply
* Re: [PATCH v2 2/2] netpoll: cleanup sparse warnings
From: David Miller @ 2013-02-12 0:19 UTC (permalink / raw)
To: nhorman; +Cc: netdev, fengguang.wu, eric.dumazet
In-Reply-To: <1360614331-29247-3-git-send-email-nhorman@tuxdriver.com>
From: Neil Horman <nhorman@tuxdriver.com>
Date: Mon, 11 Feb 2013 15:25:31 -0500
> With my recent commit I introduced two sparse warnings. Looking closer there
> were a few more in the same file, so I fixed them all up. Basic rcu pointer
> dereferencing suff.
>
> I've validated these changes using CONFIG_PROVE_RCU while starting and stopping
> netconsole repeatedly in bonded and non-bonded configurations
>
> Signed-offy-by: Neil Horman <nhorman@tuxdriver.com>
Applied.
^ permalink raw reply
* Re: [PATCH v2 1/2] netpoll: Fix __netpoll_rcu_free so that it can hold the rtnl lock
From: David Miller @ 2013-02-12 0:19 UTC (permalink / raw)
To: nhorman; +Cc: netdev, amwang, eric.dumazet
In-Reply-To: <1360614331-29247-2-git-send-email-nhorman@tuxdriver.com>
From: Neil Horman <nhorman@tuxdriver.com>
Date: Mon, 11 Feb 2013 15:25:30 -0500
> __netpoll_rcu_free is used to free netpoll structures when the rtnl_lock is
> already held. The mechanism is used to asynchronously call __netpoll_cleanup
> outside of the holding of the rtnl_lock, so as to avoid deadlock.
> Unfortunately, __netpoll_cleanup modifies pointers (dev->np), which means the
> rtnl_lock must be held while calling it. Further, it cannot be held, because
> rcu callbacks may be issued in softirq contexts, which cannot sleep.
>
> Fix this by converting the rcu callback to a work queue that is guaranteed to
> get scheduled in process context, so that we can hold the rtnl properly while
> calling __netpoll_cleanup
>
> Tested successfully by myself.
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Applied.
^ permalink raw reply
* Re: soft lockup at __skb_recv_datagram() when fuzzing with trinity as root in VM
From: Eric Dumazet @ 2013-02-12 0:19 UTC (permalink / raw)
To: Tommi Rantala; +Cc: netdev, Dave Jones, Pavel Emelyanov
In-Reply-To: <CA+ydwtphWsC-B9Y2WwWOPEWtPPj62Wf6Pt2iZ+tAGaTvg_7gCg@mail.gmail.com>
On Mon, 2013-02-11 at 21:25 +0200, Tommi Rantala wrote:
> Hello,
>
> I am quite easily reproducing this lockup when fuzzing with Trinity as
> the root user in a virtual machine. It seems to be busy-looping in the
> do-while loop in __skb_recv_datagram().
>
> [ 83.541011] INFO: rcu_sched detected stalls on CPUs/tasks: {}
> (detected by 0, t=26002 jiffies, g=27673, c=27672, q=75)
> [ 83.541011] INFO: Stall ended before state dump start
> [ 108.067010] BUG: soft lockup - CPU#0 stuck for 22s! [trinity-child31:2847]
> [ 108.067010] irq event stamp: 244034822
> [ 108.067010] hardirqs last enabled at (244034821):
> [<ffffffff81ca2da5>] _raw_spin_unlock_irqrestore+0x55/0x70
> [ 108.067010] hardirqs last disabled at (244034822):
> [<ffffffff81ca4fad>] apic_timer_interrupt+0x6d/0x80
> [ 108.067010] softirqs last enabled at (244030010):
> [<ffffffff810a086a>] __do_softirq+0x1ca/0x240
> [ 108.067010] softirqs last disabled at (244030005):
> [<ffffffff81ca56fc>] call_softirq+0x1c/0x30
> [ 108.067010] CPU 0
> [ 108.067010] Pid: 2847, comm: trinity-child31 Tainted: G W
> 3.8.0-rc7+ #73 Bochs Bochs
> [ 108.067010] RIP: 0010:[<ffffffff81ca2daa>] [<ffffffff81ca2daa>]
> _raw_spin_unlock_irqrestore+0x5a/0x70
> [ 108.067010] RSP: 0018:ffff88002fb5db38 EFLAGS: 00000286
> [ 108.067010] RAX: ffff8800201ec520 RBX: ffffffff810d54fa RCX: 0000000000005220
> [ 108.067010] RDX: ffff8800201ec520 RSI: 0000000000000001 RDI: 0000000000000286
> [ 108.067010] RBP: ffff88002fb5db48 R08: 0000000000000068 R09: 0000000000000001
> [ 108.067010] R10: 0000000000000001 R11: 0000000000000000 R12: ffffffff810f5b9d
> [ 108.067010] R13: ffff88002fb5daa8 R14: 00000019294ba499 R15: 0000000000000086
> [ 108.067010] FS: 00007f6aabc57700(0000) GS:ffff88003e000000(0000)
> knlGS:0000000000000000
> [ 108.067010] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 108.067010] CR2: 0000000000000009 CR3: 000000002fb08000 CR4: 00000000000006f0
> [ 108.067010] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [ 108.067010] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [ 108.067010] Process trinity-child31 (pid: 2847, threadinfo
> ffff88002fb5c000, task ffff8800201ec520)
> [ 108.067010] Stack:
> [ 108.067010] ffff88002fb5dc10 ffff88002fb5dc14 ffff88002fb5dbf8
> ffffffff818cc103
> [ 108.067010] ffff8800391a7d80 ffff8800201ec520 ffff88002fb5dbb8
> 7fffffffffffffff
> [ 108.067010] ffff88002fb5dc54 40001202810d54fa ffff8800201ec520
> ffff8800277f87e8
> [ 108.067010] Call Trace:
> [ 108.067010] [<ffffffff818cc103>] __skb_recv_datagram+0x1a3/0x3b0
> [ 108.067010] [<ffffffff818cbbe0>] ?
> csum_partial_copy_fromiovecend+0x220/0x220
> [ 108.067010] [<ffffffff818cc33d>] skb_recv_datagram+0x2d/0x30
> [ 108.067010] [<ffffffff813029a0>] ? selinux_syslog+0x70/0x70
> [ 108.067010] [<ffffffff819ed43d>] rawv6_recvmsg+0xad/0x240
> [ 108.067010] [<ffffffff818c4b04>] sock_common_recvmsg+0x34/0x50
> [ 108.067010] [<ffffffff818bc8ec>] sock_recvmsg+0xbc/0xf0
> [ 108.067010] [<ffffffff81084adf>] ? kvm_clock_read+0x1f/0x30
> [ 108.067010] [<ffffffff810612d9>] ? sched_clock+0x9/0x10
> [ 108.067010] [<ffffffff818bf31e>] sys_recvfrom+0xde/0x150
> [ 108.067010] [<ffffffff810f5abd>] ? trace_hardirqs_on+0xd/0x10
> [ 108.067010] [<ffffffff81ca2deb>] ? _raw_spin_unlock_irq+0x2b/0x40
> [ 108.067010] [<ffffffff81ca4355>] ? sysret_check+0x22/0x5d
> [ 108.067010] [<ffffffff810f5a15>] ? trace_hardirqs_on_caller+0x155/0x1f0
> [ 108.067010] [<ffffffff8135718e>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> [ 108.067010] [<ffffffff81ca4329>] system_call_fastpath+0x16/0x1b
> [ 108.067010] Code: ff f6 c7 02 75 1b 48 89 df 57 9d 0f 1f 44 00 00
> e8 fc 2d 45 ff eb 19 66 2e 0f 1f 84 00 00 00 00 00 e8 0b 2d 45 ff 48
> 89 df 57 9d <0f> 1f 44 00 00 48 8b 5d f0 4c 8b 65 f8 c9 c3 0f 1f 80 00
> 00 00
>
> Tommi
Seems MSG_PEEK issue
wait_for_packet() is unable to wait if one packet is in receive_queue.
So yes, we basically loop forever.
Bug added in commit 3f518bf745cbd6007d8069100fb9cb09e960c872
(datagram: Add offset argument to __skb_recv_datagram)
CC Pavel Emelyanov
^ permalink raw reply
* Re: [PATCH v3 net-next] skbuff: create skb_panic() function and its wrappers
From: David Miller @ 2013-02-12 0:15 UTC (permalink / raw)
To: sakiwit; +Cc: netdev, jiri
In-Reply-To: <1360625438-13072-1-git-send-email-sakiwit@gmail.com>
From: Jean Sacren <sakiwit@gmail.com>
Date: Mon, 11 Feb 2013 16:30:38 -0700
> Create skb_panic() function in lieu of both skb_over_panic() and
> skb_under_panic() so that code duplication would be avoided. Update type
> and variable name where necessary.
>
> Jiri Pirko suggested using wrappers so that we would be able to keep the
> fruits of the original code.
>
> Signed-off-by: Jean Sacren <sakiwit@gmail.com>
Applied, thanks.
^ permalink raw reply
* RE: atl1c DMA-API mapping errors in 3.8-rc6+
From: Huang, Xiong @ 2013-02-11 23:55 UTC (permalink / raw)
To: Josh Boyer
Cc: Jay Cliburn, Chris Snook, David S. Miller, netdev@vger.kernel.org,
sgruszka@redhat.com, nic-devel
In-Reply-To: <20130211194810.GB21501@hansolo.jdub.homelinux.org>
>
> I'd be happy to build a kernel with a patch for the users to test with.
> However, I don't see a patch here or on netdev. Did you forget to include it
> or send it out, or did I miss it somewhere?
>
Thank you Josh, please allow me to do a rough test before send it out, I've borrowed one PC.
BR.
Xiong
^ permalink raw reply
* [PATCH v3 net-next] skbuff: create skb_panic() function and its wrappers
From: Jean Sacren @ 2013-02-11 23:30 UTC (permalink / raw)
To: netdev; +Cc: Jiri Pirko
Create skb_panic() function in lieu of both skb_over_panic() and
skb_under_panic() so that code duplication would be avoided. Update type
and variable name where necessary.
Jiri Pirko suggested using wrappers so that we would be able to keep the
fruits of the original code.
Signed-off-by: Jean Sacren <sakiwit@gmail.com>
Cc: Jiri Pirko <jiri@resnulli.us>
---
v3:
- Update commit header and log.
- Implement Jiri Pirko's contribution and cc him.
v2:
- Fix breaking into multiple lines as advised by Joe Perches.
net/core/skbuff.c | 48 +++++++++++++++++++-----------------------------
1 file changed, 19 insertions(+), 29 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6114c11..8731c39 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -104,47 +104,37 @@ static const struct pipe_buf_operations sock_pipe_buf_ops = {
.get = sock_pipe_buf_get,
};
-/*
- * Keep out-of-line to prevent kernel bloat.
- * __builtin_return_address is not used because it is not always
- * reliable.
- */
-
/**
- * skb_over_panic - private function
- * @skb: buffer
- * @sz: size
- * @here: address
- *
- * Out of line support code for skb_put(). Not user callable.
+ * skb_panic - private function for out-of-line support
+ * @skb: buffer
+ * @sz: size
+ * @addr: address
+ * @panic: skb_over_panic or skb_under_panic
+ *
+ * Out-of-line support for skb_put() and skb_push().
+ * Called via the wrapper skb_over_panic() or skb_under_panic().
+ * Keep out of line to prevent kernel bloat.
+ * __builtin_return_address is not used because it is not always reliable.
*/
-static void skb_over_panic(struct sk_buff *skb, int sz, void *here)
+static void skb_panic(struct sk_buff *skb, unsigned int sz, void *addr,
+ const char panic[])
{
pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n",
- __func__, here, skb->len, sz, skb->head, skb->data,
+ panic, addr, skb->len, sz, skb->head, skb->data,
(unsigned long)skb->tail, (unsigned long)skb->end,
skb->dev ? skb->dev->name : "<NULL>");
BUG();
}
-/**
- * skb_under_panic - private function
- * @skb: buffer
- * @sz: size
- * @here: address
- *
- * Out of line support code for skb_push(). Not user callable.
- */
-
-static void skb_under_panic(struct sk_buff *skb, int sz, void *here)
+static void skb_over_panic(struct sk_buff *skb, unsigned int sz, void *addr)
{
- pr_emerg("%s: text:%p len:%d put:%d head:%p data:%p tail:%#lx end:%#lx dev:%s\n",
- __func__, here, skb->len, sz, skb->head, skb->data,
- (unsigned long)skb->tail, (unsigned long)skb->end,
- skb->dev ? skb->dev->name : "<NULL>");
- BUG();
+ skb_panic(skb, sz, addr, __func__);
}
+static void skb_under_panic(struct sk_buff *skb, unsigned int sz, void *addr)
+{
+ skb_panic(skb, sz, addr, __func__);
+}
/*
* kmalloc_reserve is a wrapper around kmalloc_node_track_caller that tells
^ permalink raw reply related
* Re: [PATCH] bridge: set priority of STP packets
From: Eric Dumazet @ 2013-02-11 22:55 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20130211102222.37743b22@nehalam.linuxnetplumber.net>
On Mon, 2013-02-11 at 10:22 -0800, Stephen Hemminger wrote:
> Spanning Tree Protocol packets should have always been marked as
> control packets, this causes them to get queued in the high prirority
> FIFO. As Radia Perlman mentioned in her LCA talk, STP dies if bridge
> gets overloaded and can't communicate. This is a long-standing bug back
> to the first versions of Linux bridge.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>
> ---
> Please consider adding to stable as well.
>
> --- a/net/bridge/br_stp_bpdu.c 2013-01-16 09:47:00.599539375 -0800
> +++ b/net/bridge/br_stp_bpdu.c 2013-02-11 08:13:56.315979316 -0800
> @@ -16,6 +16,7 @@
> #include <linux/etherdevice.h>
> #include <linux/llc.h>
> #include <linux/slab.h>
> +#include <linux/pkt_sched.h>
> #include <net/net_namespace.h>
> #include <net/llc.h>
> #include <net/llc_pdu.h>
> @@ -40,6 +41,7 @@ static void br_send_bpdu(struct net_brid
>
> skb->dev = p->dev;
> skb->protocol = htons(ETH_P_802_2);
> + skb->priority = TC_PRIO_CONTROL;
>
> skb_reserve(skb, LLC_RESERVE);
> memcpy(__skb_put(skb, length), data, length);
> --
I wonder if we should not use the same for ARP packets, as some bonding
modes depend on them as well.
^ permalink raw reply
* Re: [PATCH] ipv6: don't accept multicast traffic with scop 0
From: Dan Williams @ 2013-02-11 22:49 UTC (permalink / raw)
To: Ben Hutchings; +Cc: David Miller, hannes, netdev, yoshfuji, erik.hugne
In-Reply-To: <1360621271.2701.20.camel@bwh-desktop.uk.solarflarecom.com>
On Mon, 2013-02-11 at 22:21 +0000, Ben Hutchings wrote:
> On Mon, 2013-02-11 at 14:52 -0500, David Miller wrote:
> > From: Hannes Frederic Sowa <hannes@stressinduktion.org>
> > Date: Mon, 11 Feb 2013 20:48:35 +0100
> >
> > > On Sun, Feb 10, 2013 at 01:48:51PM +0100, Hannes Frederic Sowa wrote:
> > >> + /*
> > >> + * RFC4291 2.7
> > >> + * Nodes must not originate a packet to a multicast address whose scop
> > >> + * field contains the reserved value 0; if such a packet is received, it
> > >> + * must be silently dropped.
> > >
> > > Just nit-picking: The field is actually called scop without e, as pointed out
> > > by three erratas to RFC4291. :)
> >
> > That's funny because I added the 'e' to your patches while applying
> > them, it just looks completely stupid to refer to this things as
> > 'scop'.
>
> It seems to be a long Unix tradition to creat names with trailing silent
> vowels removed; this is hardly uniq.
You had to buy vowels from Pat back then, and people were stingy with
their hard-earned money. And then if you got the vowel wrong it was no
longer your turn. So understandably people were reluctant to use vowels
much.
Dan
^ permalink raw reply
* Re: bridge interface initial carrier state
From: Dan Williams @ 2013-02-11 22:46 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20130211135930.4cdad83c@nehalam.linuxnetplumber.net>
On Mon, 2013-02-11 at 13:59 -0800, Stephen Hemminger wrote:
> On Mon, 11 Feb 2013 14:01:55 -0600
> Dan Williams <dcbw@redhat.com> wrote:
>
> > Hi,
> >
> > I'm wondering if the initial carrier state of 'on' is intentional for a
> > bridge without ports; immediately after adding ports, the carrier is
> > recalculated and depends on the combined state of each port's carrier
> > and STP forwarding state. So a userspace program attempting to decide
> > whether the bridge was usable or not has to look at both (a) how many
> > ports are available and (b) bridge carrier state, instead of just
> > looking at the bridge carrier state.
> >
> > Dan
>
> Perhaps a future enhancement of bridge would be to use operstate flags
> to indicate lower layer down if there are no ports.
While we're at it, it appears that if a bridge port is added when it has
no carrier, nothing directly triggers br_port_state_selection() to
ensure that the bridge's carrier state is correct:
if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
(br->dev->flags & IFF_UP))
br_stp_enable_port(p);
Any reason why we can't run br_port_state_selection() unconditionally
when adding a new port? When removing a port that gets run by
br_stp_disable_port(), which is somewhat asymmetrical.
When adding, we don't necessarily want to enable STP operation on the
port until it's ready, so that hunk above for br_stp_enable_port() is
probably just fine, but we should still probably be recalculating the
bridge's carrier when it gets its first port even if that port isn't yet
usable? Or not?
Dan
^ permalink raw reply
* Re: [PATCH] ipv6: don't accept multicast traffic with scop 0
From: Stephen Hemminger @ 2013-02-11 22:42 UTC (permalink / raw)
To: Ben Hutchings; +Cc: David Miller, hannes, netdev, yoshfuji, erik.hugne
In-Reply-To: <1360621271.2701.20.camel@bwh-desktop.uk.solarflarecom.com>
On Mon, 11 Feb 2013 22:21:11 +0000
Ben Hutchings <bhutchings@solarflare.com> wrote:
> On Mon, 2013-02-11 at 14:52 -0500, David Miller wrote:
> > From: Hannes Frederic Sowa <hannes@stressinduktion.org>
> > Date: Mon, 11 Feb 2013 20:48:35 +0100
> >
> > > On Sun, Feb 10, 2013 at 01:48:51PM +0100, Hannes Frederic Sowa wrote:
> > >> + /*
> > >> + * RFC4291 2.7
> > >> + * Nodes must not originate a packet to a multicast address whose scop
> > >> + * field contains the reserved value 0; if such a packet is received, it
> > >> + * must be silently dropped.
> > >
> > > Just nit-picking: The field is actually called scop without e, as pointed out
> > > by three erratas to RFC4291. :)
> >
> > That's funny because I added the 'e' to your patches while applying
> > them, it just looks completely stupid to refer to this things as
> > 'scop'.
>
> It seems to be a long Unix tradition to creat names with trailing silent
> vowels removed; this is hardly uniq.
>
> Ben.
>
Aussie's would call it scopie
^ permalink raw reply
* Re: [PATCH] ipv6: don't accept multicast traffic with scop 0
From: Ben Hutchings @ 2013-02-11 22:21 UTC (permalink / raw)
To: David Miller; +Cc: hannes, netdev, yoshfuji, erik.hugne
In-Reply-To: <20130211.145252.603354702530166412.davem@davemloft.net>
On Mon, 2013-02-11 at 14:52 -0500, David Miller wrote:
> From: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Date: Mon, 11 Feb 2013 20:48:35 +0100
>
> > On Sun, Feb 10, 2013 at 01:48:51PM +0100, Hannes Frederic Sowa wrote:
> >> + /*
> >> + * RFC4291 2.7
> >> + * Nodes must not originate a packet to a multicast address whose scop
> >> + * field contains the reserved value 0; if such a packet is received, it
> >> + * must be silently dropped.
> >
> > Just nit-picking: The field is actually called scop without e, as pointed out
> > by three erratas to RFC4291. :)
>
> That's funny because I added the 'e' to your patches while applying
> them, it just looks completely stupid to refer to this things as
> 'scop'.
It seems to be a long Unix tradition to creat names with trailing silent
vowels removed; this is hardly uniq.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: bridge interface initial carrier state
From: Stephen Hemminger @ 2013-02-11 21:59 UTC (permalink / raw)
To: Dan Williams; +Cc: netdev
In-Reply-To: <1360612915.8633.6.camel@dcbw.foobar.com>
On Mon, 11 Feb 2013 14:01:55 -0600
Dan Williams <dcbw@redhat.com> wrote:
> Hi,
>
> I'm wondering if the initial carrier state of 'on' is intentional for a
> bridge without ports; immediately after adding ports, the carrier is
> recalculated and depends on the combined state of each port's carrier
> and STP forwarding state. So a userspace program attempting to decide
> whether the bridge was usable or not has to look at both (a) how many
> ports are available and (b) bridge carrier state, instead of just
> looking at the bridge carrier state.
>
> Dan
Perhaps a future enhancement of bridge would be to use operstate flags
to indicate lower layer down if there are no ports.
^ permalink raw reply
* Re: bridge interface initial carrier state
From: Stephen Hemminger @ 2013-02-11 21:58 UTC (permalink / raw)
To: Dan Williams; +Cc: netdev
In-Reply-To: <1360612915.8633.6.camel@dcbw.foobar.com>
On Mon, 11 Feb 2013 14:01:55 -0600
Dan Williams <dcbw@redhat.com> wrote:
> Hi,
>
> I'm wondering if the initial carrier state of 'on' is intentional for a
> bridge without ports; immediately after adding ports, the carrier is
> recalculated and depends on the combined state of each port's carrier
> and STP forwarding state. So a userspace program attempting to decide
> whether the bridge was usable or not has to look at both (a) how many
> ports are available and (b) bridge carrier state, instead of just
> looking at the bridge carrier state.
>
> Dan
It really should be off when no ports are present, but some initial startup
scripts broke when it was that way.
^ permalink raw reply
* Re: [PATCH v2 0/2] netpoll: Cleanup netpoll locking and sparse warnings
From: Neil Horman @ 2013-02-11 21:51 UTC (permalink / raw)
To: David Miller; +Cc: netdev, fengguang.wu, eric.dumazet, amwang
In-Reply-To: <20130211.161135.580650334150981029.davem@davemloft.net>
On Mon, Feb 11, 2013 at 04:11:35PM -0500, David Miller wrote:
> From: Neil Horman <nhorman@tuxdriver.com>
> Date: Mon, 11 Feb 2013 15:25:29 -0500
>
> > I was fixing some sparse warnings in netpoll from a previous commit, and it was
> > pointed out to me that one of the rcu_dereferences that I fixed up in
> > __netpoll_cleanup might not have been correct. On investigation I found that
> > rtnl_dereference should have been the correct macro to use, but we had a path in
> > which we weren't properly holding the rtnl lock. This patch series fixes up the
> > locking in the __netpoll_free_rcu path, and then properly corrects the sparse
> > warnings in the netpoll.c file that I previously introduced.
> >
> > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>
> I happen to know that this is meant for net-next, but you really need
> to state that clearly in your patch submissions.
>
Understood, sorry Dave.
Neil
^ permalink raw reply
* Re: [PATCH v2 0/2] netpoll: Cleanup netpoll locking and sparse warnings
From: David Miller @ 2013-02-11 21:11 UTC (permalink / raw)
To: nhorman; +Cc: netdev, fengguang.wu, eric.dumazet, amwang
In-Reply-To: <1360614331-29247-1-git-send-email-nhorman@tuxdriver.com>
From: Neil Horman <nhorman@tuxdriver.com>
Date: Mon, 11 Feb 2013 15:25:29 -0500
> I was fixing some sparse warnings in netpoll from a previous commit, and it was
> pointed out to me that one of the rcu_dereferences that I fixed up in
> __netpoll_cleanup might not have been correct. On investigation I found that
> rtnl_dereference should have been the correct macro to use, but we had a path in
> which we weren't properly holding the rtnl lock. This patch series fixes up the
> locking in the __netpoll_free_rcu path, and then properly corrects the sparse
> warnings in the netpoll.c file that I previously introduced.
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
I happen to know that this is meant for net-next, but you really need
to state that clearly in your patch submissions.
^ permalink raw reply
* Re: [patch net-next v4 07/11] tbf: ignore max_size check for gso skbs
From: David Miller @ 2013-02-11 21:11 UTC (permalink / raw)
To: jiri; +Cc: netdev, edumazet, jhs, kuznet, j.vimal
In-Reply-To: <20130211210220.GA1560@minipsycho.orion>
From: Jiri Pirko <jiri@resnulli.us>
Date: Mon, 11 Feb 2013 22:02:20 +0100
> Hmm. I think that this approach might not be correct after all. This
> might break existing setups when user is taking gso into account and
> adjust mtu and burst accordingly. After more thorough study, I'm under
> impression that gso skbs should not be handled in any different way.
>
> Thoughts?
I really think userspace should be ignorant of GSO to the maximum
extent to which that is possible.
^ permalink raw reply
* Re: [patch net-next v4 07/11] tbf: ignore max_size check for gso skbs
From: Jiri Pirko @ 2013-02-11 21:02 UTC (permalink / raw)
To: netdev; +Cc: davem, edumazet, jhs, kuznet, j.vimal
In-Reply-To: <1360493539-14868-8-git-send-email-jiri@resnulli.us>
Hmm. I think that this approach might not be correct after all. This
might break existing setups when user is taking gso into account and
adjust mtu and burst accordingly. After more thorough study, I'm under
impression that gso skbs should not be handled in any different way.
Thoughts?
Sun, Feb 10, 2013 at 11:52:15AM CET, jiri@resnulli.us wrote:
>This check made bigger packets incorrectly dropped. Remove this
>limitation for gso skbs.
>
>Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>Acked-by: Eric Dumazet <edumazet@google.com>
>---
> net/sched/sch_tbf.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
>index e05710a..dc562a8 100644
>--- a/net/sched/sch_tbf.c
>+++ b/net/sched/sch_tbf.c
>@@ -121,7 +121,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
> struct tbf_sched_data *q = qdisc_priv(sch);
> int ret;
>
>- if (qdisc_pkt_len(skb) > q->max_size)
>+ if (qdisc_pkt_len(skb) > q->max_size && !skb_is_gso(skb))
> return qdisc_reshape_fail(skb, sch);
>
> ret = qdisc_enqueue(skb, q->qdisc);
>--
>1.8.1.2
>
^ permalink raw reply
* [PATCH v2 2/2] netpoll: cleanup sparse warnings
From: Neil Horman @ 2013-02-11 20:25 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, fengguang.wu, David Miller, eric.dumazet
In-Reply-To: <1360614331-29247-1-git-send-email-nhorman@tuxdriver.com>
With my recent commit I introduced two sparse warnings. Looking closer there
were a few more in the same file, so I fixed them all up. Basic rcu pointer
dereferencing suff.
I've validated these changes using CONFIG_PROVE_RCU while starting and stopping
netconsole repeatedly in bonded and non-bonded configurations
Signed-offy-by: Neil Horman <nhorman@tuxdriver.com>
CC: fengguang.wu@intel.com
CC: David Miller <davem@davemloft.net>
CC: eric.dumazet@gmail.com
---
net/core/netpoll.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index c536474..bcfd4f4 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -206,7 +206,7 @@ static void netpoll_poll_dev(struct net_device *dev)
* the dev_open/close paths use this to block netpoll activity
* while changing device state
*/
- if (!mutex_trylock(&dev->npinfo->dev_lock))
+ if (!mutex_trylock(&ni->dev_lock))
return;
if (!dev || !netif_running(dev))
@@ -221,7 +221,7 @@ static void netpoll_poll_dev(struct net_device *dev)
poll_napi(dev);
- mutex_unlock(&dev->npinfo->dev_lock);
+ mutex_unlock(&ni->dev_lock);
if (dev->flags & IFF_SLAVE) {
if (ni) {
@@ -1056,7 +1056,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp)
goto free_npinfo;
}
} else {
- npinfo = ndev->npinfo;
+ npinfo = rtnl_dereference(ndev->npinfo);
atomic_inc(&npinfo->refcnt);
}
@@ -1236,7 +1236,11 @@ void __netpoll_cleanup(struct netpoll *np)
struct netpoll_info *npinfo;
unsigned long flags;
- npinfo = np->dev->npinfo;
+ /* rtnl_dereference would be preferable here but
+ * rcu_cleanup_netpoll path can put us in here safely without
+ * holding the rtnl, so plain rcu_dereference it is
+ */
+ npinfo = rtnl_dereference(np->dev->npinfo);
if (!npinfo)
return;
--
1.7.11.7
^ permalink raw reply related
* [PATCH v2 0/2] netpoll: Cleanup netpoll locking and sparse warnings
From: Neil Horman @ 2013-02-11 20:25 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, David Miller, fengguang.wu, eric.dumazet, Cong Wang
In-Reply-To: <1360248961-30721-1-git-send-email-nhorman@tuxdriver.com>
I was fixing some sparse warnings in netpoll from a previous commit, and it was
pointed out to me that one of the rcu_dereferences that I fixed up in
__netpoll_cleanup might not have been correct. On investigation I found that
rtnl_dereference should have been the correct macro to use, but we had a path in
which we weren't properly holding the rtnl lock. This patch series fixes up the
locking in the __netpoll_free_rcu path, and then properly corrects the sparse
warnings in the netpoll.c file that I previously introduced.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: David Miller <davem@davemloft.net>
CC: fengguang.wu@intel.com
CC: eric.dumazet@gmail.com
CC: Cong Wang <amwang@redhat.com>
^ permalink raw reply
* [PATCH v2 1/2] netpoll: Fix __netpoll_rcu_free so that it can hold the rtnl lock
From: Neil Horman @ 2013-02-11 20:25 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, David S. Miller, Cong Wang, Eric Dumazet
In-Reply-To: <1360614331-29247-1-git-send-email-nhorman@tuxdriver.com>
__netpoll_rcu_free is used to free netpoll structures when the rtnl_lock is
already held. The mechanism is used to asynchronously call __netpoll_cleanup
outside of the holding of the rtnl_lock, so as to avoid deadlock.
Unfortunately, __netpoll_cleanup modifies pointers (dev->np), which means the
rtnl_lock must be held while calling it. Further, it cannot be held, because
rcu callbacks may be issued in softirq contexts, which cannot sleep.
Fix this by converting the rcu callback to a work queue that is guaranteed to
get scheduled in process context, so that we can hold the rtnl properly while
calling __netpoll_cleanup
Tested successfully by myself.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: Cong Wang <amwang@redhat.com>
CC: Eric Dumazet <eric.dumazet@gmail.com>
---
drivers/net/bonding/bond_main.c | 2 +-
include/linux/netpoll.h | 4 ++--
net/8021q/vlan_dev.c | 2 +-
net/bridge/br_device.c | 2 +-
net/core/netpoll.c | 16 ++++++++++------
5 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2239937..94c1534 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1249,7 +1249,7 @@ static inline void slave_disable_netpoll(struct slave *slave)
return;
slave->np = NULL;
- __netpoll_free_rcu(np);
+ __netpoll_free_async(np);
}
static inline bool slave_dev_support_netpoll(struct net_device *slave_dev)
{
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index ab856d5..9d7d8c6 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -32,7 +32,7 @@ struct netpoll {
u8 remote_mac[ETH_ALEN];
struct list_head rx; /* rx_np list element */
- struct rcu_head rcu;
+ struct work_struct cleanup_work;
};
struct netpoll_info {
@@ -68,7 +68,7 @@ int netpoll_setup(struct netpoll *np);
int netpoll_trap(void);
void netpoll_set_trap(int trap);
void __netpoll_cleanup(struct netpoll *np);
-void __netpoll_free_rcu(struct netpoll *np);
+void __netpoll_free_async(struct netpoll *np);
void netpoll_cleanup(struct netpoll *np);
int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo);
void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 09f9108..b29fba0 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -723,7 +723,7 @@ static void vlan_dev_netpoll_cleanup(struct net_device *dev)
vlan->netpoll = NULL;
- __netpoll_free_rcu(netpoll);
+ __netpoll_free_async(netpoll);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index e1bc090..bd03084 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -266,7 +266,7 @@ void br_netpoll_disable(struct net_bridge_port *p)
p->np = NULL;
- __netpoll_free_rcu(np);
+ __netpoll_free_async(np);
}
#endif
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index edcd9ad..c536474 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -61,6 +61,7 @@ static struct srcu_struct netpoll_srcu;
static void zap_completion_queue(void);
static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo);
+static void netpoll_async_cleanup(struct work_struct *work);
static unsigned int carrier_timeout = 4;
module_param(carrier_timeout, uint, 0644);
@@ -1020,6 +1021,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp)
np->dev = ndev;
strlcpy(np->dev_name, ndev->name, IFNAMSIZ);
+ INIT_WORK(&np->cleanup_work, netpoll_async_cleanup);
if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) ||
!ndev->netdev_ops->ndo_poll_controller) {
@@ -1255,25 +1257,27 @@ void __netpoll_cleanup(struct netpoll *np)
if (ops->ndo_netpoll_cleanup)
ops->ndo_netpoll_cleanup(np->dev);
- RCU_INIT_POINTER(np->dev->npinfo, NULL);
+ rcu_assign_pointer(np->dev->npinfo, NULL);
call_rcu_bh(&npinfo->rcu, rcu_cleanup_netpoll_info);
}
}
EXPORT_SYMBOL_GPL(__netpoll_cleanup);
-static void rcu_cleanup_netpoll(struct rcu_head *rcu_head)
+static void netpoll_async_cleanup(struct work_struct *work)
{
- struct netpoll *np = container_of(rcu_head, struct netpoll, rcu);
+ struct netpoll *np = container_of(work, struct netpoll, cleanup_work);
+ rtnl_lock();
__netpoll_cleanup(np);
+ rtnl_unlock();
kfree(np);
}
-void __netpoll_free_rcu(struct netpoll *np)
+void __netpoll_free_async(struct netpoll *np)
{
- call_rcu_bh(&np->rcu, rcu_cleanup_netpoll);
+ schedule_work(&np->cleanup_work);
}
-EXPORT_SYMBOL_GPL(__netpoll_free_rcu);
+EXPORT_SYMBOL_GPL(__netpoll_free_async);
void netpoll_cleanup(struct netpoll *np)
{
--
1.7.11.7
^ permalink raw reply related
* bridge interface initial carrier state
From: Dan Williams @ 2013-02-11 20:01 UTC (permalink / raw)
To: netdev
Hi,
I'm wondering if the initial carrier state of 'on' is intentional for a
bridge without ports; immediately after adding ports, the carrier is
recalculated and depends on the combined state of each port's carrier
and STP forwarding state. So a userspace program attempting to decide
whether the bridge was usable or not has to look at both (a) how many
ports are available and (b) bridge carrier state, instead of just
looking at the bridge carrier state.
Dan
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox