* Re: [PATCH 01/12] usbnet: introduce usbnet 3 command helpers
From: Ming Lei @ 2012-10-10 3:19 UTC (permalink / raw)
To: Oliver Neukum; +Cc: David S. Miller, Greg Kroah-Hartman, netdev, linux-usb
In-Reply-To: <1765908.3QOFSVW2eC@linux-lqwf.site>
On Tue, Oct 9, 2012 at 4:47 PM, Oliver Neukum <oneukum@suse.de> wrote:
>
> Using GFP_KERNEL you preclude using those in resume() and error handling.
> Please pass a gfp_t parameter.
IMO, it is not a big deal because generally only several bytes are to be
allocated inside these helpers.
If you still think the problem should be considered, another candidate fix
is to take GFP_NOIO during system suspend/resume, and take GFP_KERNEL
in other situations.
Thanks,
--
Ming Lei
^ permalink raw reply
* Re: [PATCH V1 3/3] net/mlx4_en: Add HW timestamping (TS) support
From: Richard Cochran @ 2012-10-10 3:37 UTC (permalink / raw)
To: Or Gerlitz; +Cc: davem, netdev, Eugenia Emantayev
In-Reply-To: <1349796013-31106-4-git-send-email-ogerlitz@mellanox.com>
On Tue, Oct 09, 2012 at 05:20:13PM +0200, Or Gerlitz wrote:
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index edd9cb8..ac78127 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
...
> @@ -1542,6 +1611,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
> .ndo_set_mac_address = mlx4_en_set_mac,
> .ndo_validate_addr = eth_validate_addr,
> .ndo_change_mtu = mlx4_en_change_mtu,
> + .ndo_do_ioctl = mlx4_en_ioctl,
> .ndo_tx_timeout = mlx4_en_tx_timeout,
> .ndo_vlan_rx_add_vid = mlx4_en_vlan_rx_add_vid,
> .ndo_vlan_rx_kill_vid = mlx4_en_vlan_rx_kill_vid,
You should also provide a get_ts_info function to let the users know
about the device's time stamping capabilities.
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_timestamp.c b/drivers/net/ethernet/mellanox/mlx4/en_timestamp.c
> new file mode 100644
> index 0000000..783d493
> --- /dev/null
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_timestamp.c
...
> +void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
> +{
> + struct mlx4_dev *dev = mdev->dev;
> + u64 temp_mult;
> +
> + memset(&mdev->cycles, 0, sizeof(mdev->cycles));
> + mdev->cycles.read = mlx4_en_read_clock;
> + mdev->cycles.mask = CLOCKSOURCE_MASK(48);
> +
> + /* we have hca_core_clock in MHz, so to translate cycles to nsecs
> + * we need to divide cycles by freq and multiply by 1000;
> + * in order to get precise result we shift left the value,
> + * since we don't have floating point there;
> + * at the end shift result back
> + */
> + temp_mult = ((1ull * 1000) << 29) / dev->caps.hca_core_clock;
> + mdev->cycles.mult = (u32)temp_mult;
> + mdev->cycles.shift = 29;
> +
> + timecounter_init(&mdev->clock, &mdev->cycles,
> + ktime_to_ns(ktime_get_real()));
I didn't see any watchdog code to read this clock periodically, in
order to catch overflows.
Thanks,
Richard
^ permalink raw reply
* [Patch v2 1/5] pktgen: fix crash when generating IPv6 packets
From: Cong Wang @ 2012-10-10 3:48 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang, stable, David S. Miller
For IPv6, sizeof(struct ipv6hdr) = 40, thus the following
expression will result negative:
datalen = pkt_dev->cur_pkt_size - 14 -
sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
pkt_dev->pkt_overhead;
And, the check "if (datalen < sizeof(struct pktgen_hdr))" will be
passed as "datalen" is promoted to unsigned, therefore will cause
a crash later.
This is a quick fix by checking if "datalen" is negative. The following
patch will increase the default value of 'min_pkt_size' for IPv6.
This bug should exist for a long time, so Cc -stable too.
Cc: <stable@vger.kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
net/core/pktgen.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 148e73d..e356b8d 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2927,7 +2927,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
pkt_dev->pkt_overhead;
- if (datalen < sizeof(struct pktgen_hdr)) {
+ if (datalen < 0 || datalen < sizeof(struct pktgen_hdr)) {
datalen = sizeof(struct pktgen_hdr);
net_info_ratelimited("increased datalen to %d\n", datalen);
}
--
1.7.7.6
^ permalink raw reply related
* [Patch v2 2/5] pktgen: set different default min_pkt_size for different protocols
From: Cong Wang @ 2012-10-10 3:48 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang, David S. Miller
In-Reply-To: <1349840900-24138-1-git-send-email-amwang@redhat.com>
ETH_ZLEN is too small for IPv6, so this default value is not
suitable.
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
net/core/pktgen.c | 27 ++++++++++++++++++++-------
1 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index e356b8d..98ee549 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -248,8 +248,8 @@ struct pktgen_dev {
int removal_mark; /* non-zero => the device is marked for
* removal by worker thread */
- int min_pkt_size; /* = ETH_ZLEN; */
- int max_pkt_size; /* = ETH_ZLEN; */
+ int min_pkt_size;
+ int max_pkt_size;
int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */
int nfrags;
struct page *page;
@@ -2036,10 +2036,14 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
/* Set up Dest MAC */
memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
- /* Set up pkt size */
- pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
-
if (pkt_dev->flags & F_IPV6) {
+ if (pkt_dev->min_pkt_size == 0) {
+ pkt_dev->min_pkt_size = 14 + sizeof(struct ipv6hdr)
+ + sizeof(struct udphdr)
+ + sizeof(struct pktgen_hdr)
+ + pkt_dev->pkt_overhead;
+ }
+
/*
* Skip this automatic address setting until locks or functions
* gets exported
@@ -2086,6 +2090,13 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
}
#endif
} else {
+ if (pkt_dev->min_pkt_size == 0) {
+ pkt_dev->min_pkt_size = 14 + sizeof(struct iphdr)
+ + sizeof(struct udphdr)
+ + sizeof(struct pktgen_hdr)
+ + pkt_dev->pkt_overhead;
+ }
+
pkt_dev->saddr_min = 0;
pkt_dev->saddr_max = 0;
if (strlen(pkt_dev->src_min) == 0) {
@@ -2111,6 +2122,10 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
}
/* Initialize current values. */
+ pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
+ if (pkt_dev->min_pkt_size > pkt_dev->max_pkt_size)
+ pkt_dev->max_pkt_size = pkt_dev->min_pkt_size;
+
pkt_dev->cur_dst_mac_offset = 0;
pkt_dev->cur_src_mac_offset = 0;
pkt_dev->cur_saddr = pkt_dev->saddr_min;
@@ -3548,8 +3563,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
}
pkt_dev->removal_mark = 0;
- pkt_dev->min_pkt_size = ETH_ZLEN;
- pkt_dev->max_pkt_size = ETH_ZLEN;
pkt_dev->nfrags = 0;
pkt_dev->delay = pg_delay_d;
pkt_dev->count = pg_count_d;
--
1.7.7.6
^ permalink raw reply related
* [Patch v2 3/5] pktgen: display IPv4 address in human-readable format
From: Cong Wang @ 2012-10-10 3:48 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang, David S. Miller
In-Reply-To: <1349840900-24138-1-git-send-email-amwang@redhat.com>
It is weird to display IPv4 address in %x format, what's more,
IPv6 address is disaplayed in human-readable format too. So,
make it human-readable.
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
net/core/pktgen.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 98ee549..f9b4637 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -702,8 +702,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
&pkt_dev->cur_in6_saddr,
&pkt_dev->cur_in6_daddr);
} else
- seq_printf(seq, " cur_saddr: 0x%x cur_daddr: 0x%x\n",
- pkt_dev->cur_saddr, pkt_dev->cur_daddr);
+ seq_printf(seq, " cur_saddr: %pI4 cur_daddr: %pI4\n",
+ &pkt_dev->cur_saddr, &pkt_dev->cur_daddr);
seq_printf(seq, " cur_udp_dst: %d cur_udp_src: %d\n",
pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
--
1.7.7.6
^ permalink raw reply related
* [Patch v2 4/5] pktgen: enable automatic IPv6 address setting
From: Cong Wang @ 2012-10-10 3:48 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang, David S. Miller
In-Reply-To: <1349840900-24138-1-git-send-email-amwang@redhat.com>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
net/core/pktgen.c | 18 +++++-------------
1 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index f9b4637..47fe18e 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2037,6 +2037,9 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, ETH_ALEN);
if (pkt_dev->flags & F_IPV6) {
+ int i, set = 0, err = 1;
+ struct inet6_dev *idev;
+
if (pkt_dev->min_pkt_size == 0) {
pkt_dev->min_pkt_size = 14 + sizeof(struct ipv6hdr)
+ sizeof(struct udphdr)
@@ -2044,15 +2047,6 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
+ pkt_dev->pkt_overhead;
}
- /*
- * Skip this automatic address setting until locks or functions
- * gets exported
- */
-
-#ifdef NOTNOW
- int i, set = 0, err = 1;
- struct inet6_dev *idev;
-
for (i = 0; i < IN6_ADDR_HSIZE; i++)
if (pkt_dev->cur_in6_saddr.s6_addr[i]) {
set = 1;
@@ -2073,9 +2067,8 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
struct inet6_ifaddr *ifp;
read_lock_bh(&idev->lock);
- for (ifp = idev->addr_list; ifp;
- ifp = ifp->if_next) {
- if (ifp->scope == IFA_LINK &&
+ list_for_each_entry(ifp, &idev->addr_list, if_list) {
+ if ((ifp->scope & IFA_LINK) &&
!(ifp->flags & IFA_F_TENTATIVE)) {
pkt_dev->cur_in6_saddr = ifp->addr;
err = 0;
@@ -2088,7 +2081,6 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
if (err)
pr_err("ERROR: IPv6 link address not available\n");
}
-#endif
} else {
if (pkt_dev->min_pkt_size == 0) {
pkt_dev->min_pkt_size = 14 + sizeof(struct iphdr)
--
1.7.7.6
^ permalink raw reply related
* [Patch v2 5/5] pktgen: replace scan_ip6() with in6_pton()
From: Cong Wang @ 2012-10-10 3:48 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang, David S. Miller
In-Reply-To: <1349840900-24138-1-git-send-email-amwang@redhat.com>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
net/core/pktgen.c | 101 ++--------------------------------------------------
1 files changed, 4 insertions(+), 97 deletions(-)
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 47fe18e..d1dc14c 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -449,8 +449,6 @@ static void pktgen_stop_all_threads_ifs(void);
static void pktgen_stop(struct pktgen_thread *t);
static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
-static unsigned int scan_ip6(const char *s, char ip[16]);
-
/* Module parameters, defaults. */
static int pg_count_d __read_mostly = 1000;
static int pg_delay_d __read_mostly;
@@ -1299,7 +1297,7 @@ static ssize_t pktgen_if_write(struct file *file,
return -EFAULT;
buf[len] = 0;
- scan_ip6(buf, pkt_dev->in6_daddr.s6_addr);
+ in6_pton(buf, -1, pkt_dev->in6_daddr.s6_addr, -1, NULL);
snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr);
pkt_dev->cur_in6_daddr = pkt_dev->in6_daddr;
@@ -1322,7 +1320,7 @@ static ssize_t pktgen_if_write(struct file *file,
return -EFAULT;
buf[len] = 0;
- scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
+ in6_pton(buf, -1, pkt_dev->min_in6_daddr.s6_addr, -1, NULL);
snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr);
pkt_dev->cur_in6_daddr = pkt_dev->min_in6_daddr;
@@ -1344,7 +1342,7 @@ static ssize_t pktgen_if_write(struct file *file,
return -EFAULT;
buf[len] = 0;
- scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
+ in6_pton(buf, -1, pkt_dev->max_in6_daddr.s6_addr, -1, NULL);
snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->max_in6_daddr);
if (debug)
@@ -1365,7 +1363,7 @@ static ssize_t pktgen_if_write(struct file *file,
return -EFAULT;
buf[len] = 0;
- scan_ip6(buf, pkt_dev->in6_saddr.s6_addr);
+ in6_pton(buf, -1, pkt_dev->in6_saddr.s6_addr, -1, NULL);
snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr);
pkt_dev->cur_in6_saddr = pkt_dev->in6_saddr;
@@ -2765,97 +2763,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
return skb;
}
-/*
- * scan_ip6, fmt_ip taken from dietlibc-0.21
- * Author Felix von Leitner <felix-dietlibc@fefe.de>
- *
- * Slightly modified for kernel.
- * Should be candidate for net/ipv4/utils.c
- * --ro
- */
-
-static unsigned int scan_ip6(const char *s, char ip[16])
-{
- unsigned int i;
- unsigned int len = 0;
- unsigned long u;
- char suffix[16];
- unsigned int prefixlen = 0;
- unsigned int suffixlen = 0;
- __be32 tmp;
- char *pos;
-
- for (i = 0; i < 16; i++)
- ip[i] = 0;
-
- for (;;) {
- if (*s == ':') {
- len++;
- if (s[1] == ':') { /* Found "::", skip to part 2 */
- s += 2;
- len++;
- break;
- }
- s++;
- }
-
- u = simple_strtoul(s, &pos, 16);
- i = pos - s;
- if (!i)
- return 0;
- if (prefixlen == 12 && s[i] == '.') {
-
- /* the last 4 bytes may be written as IPv4 address */
-
- tmp = in_aton(s);
- memcpy((struct in_addr *)(ip + 12), &tmp, sizeof(tmp));
- return i + len;
- }
- ip[prefixlen++] = (u >> 8);
- ip[prefixlen++] = (u & 255);
- s += i;
- len += i;
- if (prefixlen == 16)
- return len;
- }
-
-/* part 2, after "::" */
- for (;;) {
- if (*s == ':') {
- if (suffixlen == 0)
- break;
- s++;
- len++;
- } else if (suffixlen != 0)
- break;
-
- u = simple_strtol(s, &pos, 16);
- i = pos - s;
- if (!i) {
- if (*s)
- len--;
- break;
- }
- if (suffixlen + prefixlen <= 12 && s[i] == '.') {
- tmp = in_aton(s);
- memcpy((struct in_addr *)(suffix + suffixlen), &tmp,
- sizeof(tmp));
- suffixlen += 4;
- len += strlen(s);
- break;
- }
- suffix[suffixlen++] = (u >> 8);
- suffix[suffixlen++] = (u & 255);
- s += i;
- len += i;
- if (prefixlen + suffixlen == 16)
- break;
- }
- for (i = 0; i < suffixlen; i++)
- ip[16 - suffixlen + i] = suffix[i];
- return len;
-}
-
static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
struct pktgen_dev *pkt_dev)
{
--
1.7.7.6
^ permalink raw reply related
* [PATCH] of/mdio: Staticise !CONFIG_OF stubs
From: Mark Brown @ 2012-10-10 4:33 UTC (permalink / raw)
To: Srinivas Kandagatla, David S. Miller; +Cc: Fengguang Wu, netdev, Mark Brown
The !CONFIG_OF stubs aren't static so if multiple files include the
header with this configuration then the linker will see multiple
definitions of the stubs.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
include/linux/of_mdio.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
index 6ef49b8..00f336f 100644
--- a/include/linux/of_mdio.h
+++ b/include/linux/of_mdio.h
@@ -26,17 +26,17 @@ extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
#else /* CONFIG_OF */
-int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
+static int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
{
return -ENOSYS;
}
-struct phy_device *of_phy_find_device(struct device_node *phy_np)
+static struct phy_device *of_phy_find_device(struct device_node *phy_np)
{
return NULL;
}
-struct phy_device *of_phy_connect(struct net_device *dev,
+static struct phy_device *of_phy_connect(struct net_device *dev,
struct device_node *phy_np,
void (*hndlr)(struct net_device *),
u32 flags, phy_interface_t iface)
@@ -44,14 +44,14 @@ struct phy_device *of_phy_connect(struct net_device *dev,
return NULL;
}
-struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
+static struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
void (*hndlr)(struct net_device *),
phy_interface_t iface)
{
return NULL;
}
-struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np)
+static struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np)
{
return NULL;
}
--
1.7.10.4
^ permalink raw reply related
* Re: 3.4.1 and 3.5-rc1 Packet lost at 250Mb/s
From: Jeff Kirsher @ 2012-10-10 4:59 UTC (permalink / raw)
To: adam.niescierowicz; +Cc: Andre Tomt, Eric Dumazet, Netdev, Jesse Brandeburg
In-Reply-To: <d29932d70fa2025a8b87b053d9d99953@justnet.pl>
On 10/09/2012 12:56 PM, Nieścierowicz Adam wrote:
> W dniu 08.10.2012 14:59, Andre Tomt napisał(a):
>
>> On 08. okt. 2012 14:32, Andre Tomt wrote:
>>
>>> On 08. okt. 2012 14:13, Eric Dumazet wrote:
>>>
>>>> On Mon, 2012-10-08 at 14:00 +0200, Andre Tomt wrote:
>>>>
>>>>> On 08. okt. 2012 12:49, Nieścierowicz Adam wrote:
>>>>>
>>>>>> W dniu 08.10.2012 11:47, Eric Dumazet napisał(a):
>>>>>>
>>>>>>> Anyway you dont say where are drops, (ifconfig give us very few
>>>>>>> drops)
>>>>>> you can see no losses(drop), but a temporary decline in traffic
>>>>>> on the interface to 0kb/s
>>>>> This sounds very familiar, could it be something similar to:
>>>>> http://marc.info/?l=linux-netdev&m=134594936016796&w=3 [1] The chip
>>>>> seems to be of the same family (though not model)
>>>> Yes, but Adam says 3.4.1 already has a problem, while commit
>>>> 2cb7a9cc008c25dc03314de563c00c107b3e5432 is in 3.5 only. Since Adam
>>>> uses Intel e1000e, it could be the BQL related problem.
>>> The other chips have had DMA burst flag enabled for longer, so that he
>>> sees the same problem in 3.4 while I'm not makes sense. Hmm, as 3.4 is
>>> when BQL went in (IIRC) it seems very likely that this BQL issue is the
>>> problem for both of us.
>>
>> To clarify; I think the DMA burst flag in the driver triggers the BQL
>> related issue. Judging by the patchwork link for wthresh=1 this seems
>> very related indeed.
>>
>> Removing the FLAG2_DMA_BURST flag for 82574 in the driver works for me.
>> Adam, it might be worth testing out a build on your system too with the
>> flag removed. If you try the attached patch (for 3.6, probably OK for
>> 3.5) and the problem dissapears, we are probably at least talking about
>> the same bug.
>
> after applying the patch everything looks good, no visible loss
>
> Do you expect to correct the bug in mainline?
Jesse Brandenburg is working on a patch for upstream currently to fix
the issue.
^ permalink raw reply
* Re: [PATCH 12/12] usbnet: make device out of suspend before calling usbnet_read/write_cmd
From: Oliver Neukum @ 2012-10-10 5:34 UTC (permalink / raw)
To: Ming Lei
Cc: David S. Miller, Greg Kroah-Hartman,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CACVXFVNb-APsJG=ejW+2jqxTfAFsGhHovpgpsyvk6wUoKn5TzA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wednesday 10 October 2012 10:33:17 Ming Lei wrote:
> On Tue, Oct 9, 2012 at 4:50 PM, Oliver Neukum <oneukum-l3A5Bk7waGM@public.gmane.org> wrote:
> > This is awkward to use in suspend()/resume()
> > Could you make both versions available?
>
> Good catch, thanks for your review.
>
> As far as I can think of, the mutex_is_locked() trick can solve the problem.
No, you cannot do this. It introduces a race. The check for mutex_is_locked()
can be positive because the device is being suspended and the IO would
be done when it is too late.
Please don't try to be fancy here, just export two versions of each call.
Regards
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 01/12] usbnet: introduce usbnet 3 command helpers
From: Oliver Neukum @ 2012-10-10 5:51 UTC (permalink / raw)
To: Ming Lei
Cc: David S. Miller, Greg Kroah-Hartman,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CACVXFVOPc0gG3UdWqJ0E+6wiwdPv5EoEgbJ0cvJ4oD4602Yp3A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wednesday 10 October 2012 11:19:09 Ming Lei wrote:
> On Tue, Oct 9, 2012 at 4:47 PM, Oliver Neukum <oneukum-l3A5Bk7waGM@public.gmane.org> wrote:
> >
> > Using GFP_KERNEL you preclude using those in resume() and error handling.
> > Please pass a gfp_t parameter.
>
> IMO, it is not a big deal because generally only several bytes are to be
> allocated inside these helpers.
Any allocation can do it, if the VM layer decides to block.
> If you still think the problem should be considered, another candidate fix
> is to take GFP_NOIO during system suspend/resume, and take GFP_KERNEL
> in other situations.
No, the problem is autoresume.
Suppose we have a device with two interface. Interface A be usbnet; interface B
something you page on. Now consider that you can only resume both interfaces
and this is (and needs to be) done synchronously.
Now we can have this code path:
autoresume of device -> resume() -> kmalloc(..., GFP_KERNEL) ->
VM layer decides to start paging out -> IO to interface B -> autoresume of device
--> DEADLOCK
We need to use GFP_NOIO in situations the helper cannot know about.
Please add a gfp_t parameter. Then the caller will solve that.
Regards
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 01/12] usbnet: introduce usbnet 3 command helpers
From: Ming Lei @ 2012-10-10 5:56 UTC (permalink / raw)
To: Oliver Neukum; +Cc: David S. Miller, Greg Kroah-Hartman, netdev, linux-usb
In-Reply-To: <CACVXFVOPc0gG3UdWqJ0E+6wiwdPv5EoEgbJ0cvJ4oD4602Yp3A@mail.gmail.com>
On Wed, Oct 10, 2012 at 11:19 AM, Ming Lei <ming.lei@canonical.com> wrote:
> On Tue, Oct 9, 2012 at 4:47 PM, Oliver Neukum <oneukum@suse.de> wrote:
>>
>> Using GFP_KERNEL you preclude using those in resume() and error handling.
>> Please pass a gfp_t parameter.
>
> IMO, it is not a big deal because generally only several bytes are to be
> allocated inside these helpers.
Also pm_restrict_gfp_mask()/pm_restore_gfp_mask() have been introduced
to address the problem for 2 years, looks the gfp_t isn't needed, doesn't it?
Thanks,
--
Ming Lei
^ permalink raw reply
* Re: [PATCH 12/12] usbnet: make device out of suspend before calling usbnet_read/write_cmd
From: Ming Lei @ 2012-10-10 6:00 UTC (permalink / raw)
To: Oliver Neukum
Cc: David S. Miller, Greg Kroah-Hartman,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CACVXFVNb-APsJG=ejW+2jqxTfAFsGhHovpgpsyvk6wUoKn5TzA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wed, Oct 10, 2012 at 10:33 AM, Ming Lei <ming.lei-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org> wrote:
> Good catch, thanks for your review.
>
> As far as I can think of, the mutex_is_locked() trick can solve the problem.
>
> How about the attached patch?
This one is still not good.
After further thought, it may be better to fix the problem in net
core(dev_ioctl)
because the problem happens on other net devices too.
Thanks,
--
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCHv2 3/8] vxlan: use ip_route_output
From: Stephen Hemminger @ 2012-10-10 6:35 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20121010063545.453368147@vyatta.com>
[-- Attachment #1: vxlan-route-output.patch --]
[-- Type: text/plain, Size: 1120 bytes --]
Select source address for VXLAN packet based on route destination
and don't lie to route code. VXLAN is not GRE.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
v2 - zero flow structure
--- a/drivers/net/vxlan.c 2012-10-09 18:08:32.630456072 -0700
+++ b/drivers/net/vxlan.c 2012-10-09 18:08:33.466447793 -0700
@@ -680,9 +680,13 @@ static netdev_tx_t vxlan_xmit(struct sk_
hash = skb_get_rxhash(skb);
- rt = ip_route_output_gre(dev_net(dev), &fl4, dst,
- vxlan->saddr, vxlan->vni,
- RT_TOS(tos), vxlan->link);
+ memset(&fl4, 0, sizeof(fl4));
+ fl4.flowi4_oif = vxlan->link;
+ fl4.flowi4_tos = RT_TOS(tos);
+ fl4.daddr = dst;
+ fl4.saddr = vxlan->saddr;
+
+ rt = ip_route_output_key(dev_net(dev), &fl4);
if (IS_ERR(rt)) {
netdev_dbg(dev, "no route to %pI4\n", &dst);
dev->stats.tx_carrier_errors++;
@@ -724,7 +728,7 @@ static netdev_tx_t vxlan_xmit(struct sk_
iph->frag_off = df;
iph->protocol = IPPROTO_UDP;
iph->tos = vxlan_ecn_encap(tos, old_iph, skb);
- iph->daddr = fl4.daddr;
+ iph->daddr = dst;
iph->saddr = fl4.saddr;
iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
^ permalink raw reply
* [PATCHv2 0/8] vxlan: bug fixes
From: Stephen Hemminger @ 2012-10-10 6:35 UTC (permalink / raw)
To: davem; +Cc: netdev
Revision to earlier patch set for vxlan, includes a couple
more issues.
^ permalink raw reply
* [PATCHv2 1/8] vxlan: minor output refactoring
From: Stephen Hemminger @ 2012-10-10 6:35 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20121010063545.453368147@vyatta.com>
[-- Attachment #1: vxlan-dst.patch --]
[-- Type: text/plain, Size: 1781 bytes --]
Move code to find destination to a small function.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
v2 - breakup compound if()
--- a/drivers/net/vxlan.c 2012-10-09 18:08:28.594496129 -0700
+++ b/drivers/net/vxlan.c 2012-10-09 18:08:31.722465071 -0700
@@ -621,6 +621,22 @@ static inline u8 vxlan_ecn_encap(u8 tos,
return INET_ECN_encapsulate(tos, inner);
}
+static __be32 vxlan_find_dst(struct vxlan_dev *vxlan, struct sk_buff *skb)
+{
+ const struct ethhdr *eth = (struct ethhdr *) skb->data;
+ const struct vxlan_fdb *f;
+
+ if (is_multicast_ether_addr(eth->h_dest))
+ return vxlan->gaddr;
+
+ f = vxlan_find_mac(vxlan, eth->h_dest);
+ if (f)
+ return f->remote_ip;
+ else
+ return vxlan->gaddr;
+
+}
+
/* Transmit local packets over Vxlan
*
* Outer IP header inherits ECN and DF from inner header.
@@ -632,13 +648,11 @@ static netdev_tx_t vxlan_xmit(struct sk_
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct rtable *rt;
- const struct ethhdr *eth;
const struct iphdr *old_iph;
struct iphdr *iph;
struct vxlanhdr *vxh;
struct udphdr *uh;
struct flowi4 fl4;
- struct vxlan_fdb *f;
unsigned int pkt_len = skb->len;
u32 hash;
__be32 dst;
@@ -646,21 +660,16 @@ static netdev_tx_t vxlan_xmit(struct sk_
__u8 tos, ttl;
int err;
+ dst = vxlan_find_dst(vxlan, skb);
+ if (!dst)
+ goto drop;
+
/* Need space for new headers (invalidates iph ptr) */
if (skb_cow_head(skb, VXLAN_HEADROOM))
goto drop;
- eth = (void *)skb->data;
old_iph = ip_hdr(skb);
- if (!is_multicast_ether_addr(eth->h_dest) &&
- (f = vxlan_find_mac(vxlan, eth->h_dest)))
- dst = f->remote_ip;
- else if (vxlan->gaddr) {
- dst = vxlan->gaddr;
- } else
- goto drop;
-
ttl = vxlan->ttl;
if (!ttl && IN_MULTICAST(ntohl(dst)))
ttl = 1;
^ permalink raw reply
* [PATCHv2 4/8] vxlan: associate with tunnel socket on transmit
From: Stephen Hemminger @ 2012-10-10 6:35 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20121010063545.453368147@vyatta.com>
[-- Attachment #1: vxlan-owner.patch --]
[-- Type: text/plain, Size: 1192 bytes --]
When tunnelling a skb, associate it with the tunnel socket.
This allows parameters set on tunnel socket (like multicast loop
flag), to be picked up by ip_output.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/vxlan.c 2012-10-09 18:08:33.466447793 -0700
+++ b/drivers/net/vxlan.c 2012-10-09 18:08:34.066441861 -0700
@@ -637,6 +637,23 @@ static __be32 vxlan_find_dst(struct vxla
}
+static void vxlan_sock_free(struct sk_buff *skb)
+{
+ sock_put(skb->sk);
+}
+
+/* On transmit, associate with the tunnel socket */
+static void vxlan_set_owner(struct net_device *dev, struct sk_buff *skb)
+{
+ struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+ struct sock *sk = vn->sock->sk;
+
+ skb_orphan(skb);
+ sock_hold(sk);
+ skb->sk = sk;
+ skb->destructor = vxlan_sock_free;
+}
+
/* Transmit local packets over Vxlan
*
* Outer IP header inherits ECN and DF from inner header.
@@ -732,6 +749,8 @@ static netdev_tx_t vxlan_xmit(struct sk_
iph->saddr = fl4.saddr;
iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+ vxlan_set_owner(dev, skb);
+
/* See __IPTUNNEL_XMIT */
skb->ip_summed = CHECKSUM_NONE;
ip_select_ident(iph, &rt->dst, NULL);
^ permalink raw reply
* [PATCHv2 2/8] vxlan: fix byte order in hash function
From: Stephen Hemminger @ 2012-10-10 6:35 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20121010063545.453368147@vyatta.com>
[-- Attachment #1: vxlan-byte-order.patch --]
[-- Type: text/plain, Size: 518 bytes --]
Shift was wrong direction causing packets to hash based on
other parts of the ethernet header, not the address.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/vxlan.c 2012-10-09 18:08:31.722465071 -0700
+++ b/drivers/net/vxlan.c 2012-10-09 18:08:32.630456072 -0700
@@ -228,9 +228,9 @@ static u32 eth_hash(const unsigned char
/* only want 6 bytes */
#ifdef __BIG_ENDIAN
- value <<= 16;
-#else
value >>= 16;
+#else
+ value <<= 16;
#endif
return hash_64(value, FDB_HASH_BITS);
}
^ permalink raw reply
* [PATCHv2 5/8] vxlan: allow configuring port range
From: Stephen Hemminger @ 2012-10-10 6:35 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20121010063545.453368147@vyatta.com>
[-- Attachment #1: vxlan-port-range.patch --]
[-- Type: text/plain, Size: 5917 bytes --]
VXLAN bases source UDP port based on flow to help the
receiver to be able to load balance based on outer header flow.
This patch restricts the port range to the normal UDP local
ports, and allows overriding via configuration.
It also uses jhash of Ethernet header when looking at flows
with out know L3 header.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
v2 - min/max are non-inclusive so allow min == max
drivers/net/vxlan.c | 62 ++++++++++++++++++++++++++++++++++++++++++++----
include/linux/if_link.h | 6 ++++
2 files changed, 63 insertions(+), 5 deletions(-)
--- a/drivers/net/vxlan.c 2012-10-09 18:08:34.066441861 -0700
+++ b/drivers/net/vxlan.c 2012-10-09 18:08:35.086431755 -0700
@@ -106,6 +106,8 @@ struct vxlan_dev {
__be32 gaddr; /* multicast group */
__be32 saddr; /* source address */
unsigned int link; /* link to multicast over */
+ __u16 port_min; /* source port range */
+ __u16 port_max;
__u8 tos; /* TOS override */
__u8 ttl;
bool learn;
@@ -654,12 +656,29 @@ static void vxlan_set_owner(struct net_d
skb->destructor = vxlan_sock_free;
}
+/* Compute source port for outgoing packet
+ * first choice to use L4 flow hash since it will spread
+ * better and maybe available from hardware
+ * secondary choice is to use jhash on the Ethernet header
+ */
+static u16 vxlan_src_port(const struct vxlan_dev *vxlan, struct sk_buff *skb)
+{
+ unsigned int range = (vxlan->port_max - vxlan->port_min) + 1;
+ u32 hash;
+
+ hash = skb_get_rxhash(skb);
+ if (!hash)
+ hash = jhash(skb->data, 2 * ETH_ALEN,
+ (__force u32) skb->protocol);
+
+ return (((u64) hash * range) >> 32) + vxlan->port_min;
+}
+
/* Transmit local packets over Vxlan
*
* Outer IP header inherits ECN and DF from inner header.
* Outer UDP destination is the VXLAN assigned port.
- * source port is based on hash of flow if available
- * otherwise use a random value
+ * source port is based on hash of flow
*/
static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
{
@@ -671,8 +690,8 @@ static netdev_tx_t vxlan_xmit(struct sk_
struct udphdr *uh;
struct flowi4 fl4;
unsigned int pkt_len = skb->len;
- u32 hash;
__be32 dst;
+ __u16 src_port;
__be16 df = 0;
__u8 tos, ttl;
int err;
@@ -695,7 +714,7 @@ static netdev_tx_t vxlan_xmit(struct sk_
if (tos == 1)
tos = vxlan_get_dsfield(old_iph, skb);
- hash = skb_get_rxhash(skb);
+ src_port = vxlan_src_port(vxlan, skb);
memset(&fl4, 0, sizeof(fl4));
fl4.flowi4_oif = vxlan->link;
@@ -732,7 +751,7 @@ static netdev_tx_t vxlan_xmit(struct sk_
uh = udp_hdr(skb);
uh->dest = htons(vxlan_port);
- uh->source = hash ? :random32();
+ uh->source = htons(src_port);
uh->len = htons(skb->len);
uh->check = 0;
@@ -960,6 +979,7 @@ static void vxlan_setup(struct net_devic
{
struct vxlan_dev *vxlan = netdev_priv(dev);
unsigned h;
+ int low, high;
eth_hw_addr_random(dev);
ether_setup(dev);
@@ -979,6 +999,10 @@ static void vxlan_setup(struct net_devic
vxlan->age_timer.function = vxlan_cleanup;
vxlan->age_timer.data = (unsigned long) vxlan;
+ inet_get_local_port_range(&low, &high);
+ vxlan->port_min = low;
+ vxlan->port_max = high;
+
vxlan->dev = dev;
for (h = 0; h < FDB_HASH_SIZE; ++h)
@@ -995,6 +1019,7 @@ static const struct nla_policy vxlan_pol
[IFLA_VXLAN_LEARNING] = { .type = NLA_U8 },
[IFLA_VXLAN_AGEING] = { .type = NLA_U32 },
[IFLA_VXLAN_LIMIT] = { .type = NLA_U32 },
+ [IFLA_VXLAN_PORT_RANGE] = { .len = sizeof(struct ifla_vxlan_port_range) },
};
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -1027,6 +1052,18 @@ static int vxlan_validate(struct nlattr
return -EADDRNOTAVAIL;
}
}
+
+ if (data[IFLA_VXLAN_PORT_RANGE]) {
+ const struct ifla_vxlan_port_range *p
+ = nla_data(data[IFLA_VXLAN_PORT_RANGE]);
+
+ if (ntohs(p->high) < ntohs(p->low)) {
+ pr_debug("port range %u .. %u not valid\n",
+ ntohs(p->low), ntohs(p->high));
+ return -EINVAL;
+ }
+ }
+
return 0;
}
@@ -1077,6 +1114,13 @@ static int vxlan_newlink(struct net *net
if (data[IFLA_VXLAN_LIMIT])
vxlan->addrmax = nla_get_u32(data[IFLA_VXLAN_LIMIT]);
+ if (data[IFLA_VXLAN_PORT_RANGE]) {
+ const struct ifla_vxlan_port_range *p
+ = nla_data(data[IFLA_VXLAN_PORT_RANGE]);
+ vxlan->port_min = ntohs(p->low);
+ vxlan->port_max = ntohs(p->high);
+ }
+
err = register_netdevice(dev);
if (!err)
hlist_add_head_rcu(&vxlan->hlist, vni_head(net, vxlan->vni));
@@ -1105,12 +1149,17 @@ static size_t vxlan_get_size(const struc
nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_LEARNING */
nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_AGEING */
nla_total_size(sizeof(__u32)) + /* IFLA_VXLAN_LIMIT */
+ nla_total_size(sizeof(struct ifla_vxlan_port_range)) +
0;
}
static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
const struct vxlan_dev *vxlan = netdev_priv(dev);
+ struct ifla_vxlan_port_range ports = {
+ .low = htons(vxlan->port_min),
+ .high = htons(vxlan->port_max),
+ };
if (nla_put_u32(skb, IFLA_VXLAN_ID, vxlan->vni))
goto nla_put_failure;
@@ -1131,6 +1180,9 @@ static int vxlan_fill_info(struct sk_buf
nla_put_u32(skb, IFLA_VXLAN_LIMIT, vxlan->addrmax))
goto nla_put_failure;
+ if (nla_put(skb, IFLA_VXLAN_PORT_RANGE, sizeof(ports), &ports))
+ goto nla_put_failure;
+
return 0;
nla_put_failure:
--- a/include/linux/if_link.h 2012-10-09 18:08:22.126560329 -0700
+++ b/include/linux/if_link.h 2012-10-09 18:08:35.086431755 -0700
@@ -284,10 +284,16 @@ enum {
IFLA_VXLAN_LEARNING,
IFLA_VXLAN_AGEING,
IFLA_VXLAN_LIMIT,
+ IFLA_VXLAN_PORT_RANGE,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
+struct ifla_vxlan_port_range {
+ __be16 low;
+ __be16 high;
+};
+
/* SR-IOV virtual function management section */
enum {
^ permalink raw reply
* [PATCHv2 6/8] vxlan: add additional headroom
From: Stephen Hemminger @ 2012-10-10 6:35 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20121010063545.453368147@vyatta.com>
[-- Attachment #1: vxlan-more-headroom.patch --]
[-- Type: text/plain, Size: 543 bytes --]
Tell upper layer protocols to allocate skb with additional headroom.
This avoids allocation and copy in local packet sends.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/vxlan.c 2012-10-09 18:08:35.086431755 -0700
+++ b/drivers/net/vxlan.c 2012-10-09 18:08:36.862414133 -0700
@@ -983,6 +983,7 @@ static void vxlan_setup(struct net_devic
eth_hw_addr_random(dev);
ether_setup(dev);
+ dev->hard_header_len = ETH_HLEN + VXLAN_HEADROOM;
dev->netdev_ops = &vxlan_netdev_ops;
dev->destructor = vxlan_free;
^ permalink raw reply
* [PATCHv2 7/8] vxlan: fix receive checksum handling
From: Stephen Hemminger @ 2012-10-10 6:35 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20121010063545.453368147@vyatta.com>
[-- Attachment #1: vxlan-checksum.patch --]
[-- Type: text/plain, Size: 1189 bytes --]
Vxlan was trying to use postpull_rcsum to allow receive checksum
offload to work on drivers using CHECKSUM_COMPLETE method. But this
doesn't work correctly. Just force full receive checksum on received
packet.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/vxlan.c 2012-10-09 18:08:36.862414133 -0700
+++ b/drivers/net/vxlan.c 2012-10-09 18:08:38.686396042 -0700
@@ -537,7 +537,6 @@ static int vxlan_udp_encap_recv(struct s
}
__skb_pull(skb, sizeof(struct vxlanhdr));
- skb_postpull_rcsum(skb, eth_hdr(skb), sizeof(struct vxlanhdr));
/* Is this VNI defined? */
vni = ntohl(vxh->vx_vni) >> 8;
@@ -556,7 +555,6 @@ static int vxlan_udp_encap_recv(struct s
/* Re-examine inner Ethernet packet */
oip = ip_hdr(skb);
skb->protocol = eth_type_trans(skb, vxlan->dev);
- skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
/* Ignore packet loops (and multicast echo) */
if (compare_ether_addr(eth_hdr(skb)->h_source,
@@ -568,6 +566,7 @@ static int vxlan_udp_encap_recv(struct s
__skb_tunnel_rx(skb, vxlan->dev);
skb_reset_network_header(skb);
+ skb->ip_summed = CHECKSUM_NONE;
err = IP_ECN_decapsulate(oip, skb);
if (unlikely(err)) {
^ permalink raw reply
* [PATCHv2 8/8] vxlan: fix oops when give unknown ifindex
From: Stephen Hemminger @ 2012-10-10 6:35 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <20121010063545.453368147@vyatta.com>
[-- Attachment #1: vxlan-baddev.patch --]
[-- Type: text/plain, Size: 1163 bytes --]
If vxlan is created and the ifindex is passed; there are two cases which
are incorrectly handled by the existing code. The ifindex could be zero
(i.e. no device) or there could be no device with that ifindex.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/vxlan.c 2012-10-09 22:07:41.417308505 -0700
+++ b/drivers/net/vxlan.c 2012-10-09 22:09:56.715949703 -0700
@@ -1090,14 +1090,18 @@ static int vxlan_newlink(struct net *net
if (data[IFLA_VXLAN_LOCAL])
vxlan->saddr = nla_get_be32(data[IFLA_VXLAN_LOCAL]);
- if (data[IFLA_VXLAN_LINK]) {
- vxlan->link = nla_get_u32(data[IFLA_VXLAN_LINK]);
+ if (data[IFLA_VXLAN_LINK] &&
+ (vxlan->link = nla_get_u32(data[IFLA_VXLAN_LINK]))) {
+ struct net_device *lowerdev
+ = __dev_get_by_index(net, vxlan->link);
- if (!tb[IFLA_MTU]) {
- struct net_device *lowerdev;
- lowerdev = __dev_get_by_index(net, vxlan->link);
- dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
+ if (!lowerdev) {
+ pr_info("ifindex %d does not exist\n", vxlan->link);
+ return -ENODEV;
}
+
+ if (!tb[IFLA_MTU])
+ dev->mtu = lowerdev->mtu - VXLAN_HEADROOM;
}
if (data[IFLA_VXLAN_TOS])
^ permalink raw reply
* [PATCH] iproute2: allow configuring vxlan port range
From: Stephen Hemminger @ 2012-10-10 6:41 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: davem, netdev
In-Reply-To: <20121010063623.694192145@vyatta.com>
New options to ip link to allow setting vxlan port range.
Also, don't print everything that is defaulted when showing device.
---
include/linux/if_link.h | 6 ++++++
ip/iplink_vxlan.c | 51 ++++++++++++++++++++++++++++++++---------------
2 files changed, 41 insertions(+), 16 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 1cf79fa..563e8fb 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -282,10 +282,16 @@ enum {
IFLA_VXLAN_LEARNING,
IFLA_VXLAN_AGEING,
IFLA_VXLAN_LIMIT,
+ IFLA_VXLAN_PORT_RANGE,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
+struct ifla_vxlan_port_range {
+ __be16 low;
+ __be16 high;
+};
+
/* SR-IOV virtual function management section */
enum {
diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c
index f52eb18..7957781 100644
--- a/ip/iplink_vxlan.c
+++ b/ip/iplink_vxlan.c
@@ -24,7 +24,8 @@
static void explain(void)
{
fprintf(stderr, "Usage: ... vxlan id VNI [ group ADDR ] [ local ADDR ]\n");
- fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ [no]learning ] [ dev PHYS_DEV ]\n");
+ fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ dev PHYS_DEV ]\n");
+ fprintf(stderr, " [ port MIN MAX ] [ [no]learning ]\n");
fprintf(stderr, "\n");
fprintf(stderr, "Where: VNI := 0-16777215\n");
fprintf(stderr, " ADDR := { IP_ADDRESS | any }\n");
@@ -46,6 +47,7 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
__u8 noage = 0;
__u32 age = 0;
__u32 maxaddr = 0;
+ struct ifla_vxlan_port_range range = { 0, 0 };
while (argc > 0) {
if (!matches(*argv, "id") ||
@@ -79,9 +81,9 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
NEXT_ARG();
if (strcmp(*argv, "inherit") != 0) {
if (get_unsigned(&uval, *argv, 0))
- invarg("invalid TTL\n", *argv);
+ invarg("invalid TTL", *argv);
if (uval > 255)
- invarg("TTL must be <= 255\n", *argv);
+ invarg("TTL must be <= 255", *argv);
ttl = uval;
}
} else if (!matches(*argv, "tos") ||
@@ -100,13 +102,23 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
if (strcmp(*argv, "none") == 0)
noage = 1;
else if (get_u32(&age, *argv, 0))
- invarg("ageing timer\n", *argv);
+ invarg("ageing timer", *argv);
} else if (!matches(*argv, "maxaddress")) {
NEXT_ARG();
if (strcmp(*argv, "unlimited") == 0)
maxaddr = 0;
else if (get_u32(&maxaddr, *argv, 0))
- invarg("max addresses\n", *argv);
+ invarg("max addresses", *argv);
+ } else if (!matches(*argv, "port")) {
+ __u16 minport, maxport;
+ NEXT_ARG();
+ if (get_u16(&minport, *argv, 0))
+ invarg("min port", *argv);
+ NEXT_ARG();
+ if (get_u16(&maxport, *argv, 0))
+ invarg("max port", *argv);
+ range.low = htons(minport);
+ range.high = htons(maxport);
} else if (!matches(*argv, "nolearning")) {
learning = 0;
} else if (!matches(*argv, "learning")) {
@@ -140,6 +152,9 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
addattr32(n, 1024, IFLA_VXLAN_AGEING, age);
if (maxaddr)
addattr32(n, 1024, IFLA_VXLAN_LIMIT, maxaddr);
+ if (range.low || range.high)
+ addattr_l(n, 1024, IFLA_VXLAN_PORT_RANGE,
+ &range, sizeof(range));
return 0;
}
@@ -148,6 +163,8 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
{
__u32 vni;
unsigned link;
+ __u8 tos;
+ __u32 maxaddr;
char s1[1024];
char s2[64];
@@ -187,13 +204,18 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
fprintf(f, "dev %u ", link);
}
+ if (tb[IFLA_VXLAN_PORT_RANGE]) {
+ const struct ifla_vxlan_port_range *r
+ = RTA_DATA(tb[IFLA_VXLAN_PORT_RANGE]);
+ fprintf(f, "port %u %u ", ntohs(r->low), ntohs(r->high));
+ }
+
if (tb[IFLA_VXLAN_LEARNING] &&
!rta_getattr_u8(tb[IFLA_VXLAN_LEARNING]))
fputs("nolearning ", f);
-
- if (tb[IFLA_VXLAN_TOS]) {
- __u8 tos = rta_getattr_u8(tb[IFLA_VXLAN_TOS]);
-
+
+ if (tb[IFLA_VXLAN_TOS] &&
+ (tos = rta_getattr_u8(tb[IFLA_VXLAN_TOS]))) {
if (tos == 1)
fprintf(f, "tos inherit ");
else
@@ -213,13 +235,10 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
else
fprintf(f, "ageing %u ", age);
}
- if (tb[IFLA_VXLAN_LIMIT]) {
- __u32 maxaddr = rta_getattr_u32(tb[IFLA_VXLAN_LIMIT]);
- if (maxaddr == 0)
- fprintf(f, "maxaddr unlimited ");
- else
- fprintf(f, "maxaddr %u ", maxaddr);
- }
+
+ if (tb[IFLA_VXLAN_LIMIT] &&
+ (maxaddr = rta_getattr_u32(tb[IFLA_VXLAN_LIMIT]) != 0))
+ fprintf(f, "maxaddr %u ", maxaddr);
}
struct link_util vxlan_link_util = {
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH] of/mdio: Staticise !CONFIG_OF stubs
From: Thomas Petazzoni @ 2012-10-10 8:02 UTC (permalink / raw)
To: Mark Brown; +Cc: Srinivas Kandagatla, David S. Miller, Fengguang Wu, netdev
In-Reply-To: <1349843618-11209-1-git-send-email-broonie@opensource.wolfsonmicro.com>
On Wed, 10 Oct 2012 13:33:38 +0900, Mark Brown wrote:
> The !CONFIG_OF stubs aren't static so if multiple files include the
> header with this configuration then the linker will see multiple
> definitions of the stubs.
>
> Reported-by: Fengguang Wu <fengguang.wu@intel.com>
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH 01/12] usbnet: introduce usbnet 3 command helpers
From: Ming Lei @ 2012-10-10 8:17 UTC (permalink / raw)
To: Oliver Neukum
Cc: David S. Miller, Greg Kroah-Hartman,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4085386.s0fOKMaRDP-ugxBuEnWX9yG/4A2pS7c2Q@public.gmane.org>
On Wed, Oct 10, 2012 at 1:51 PM, Oliver Neukum <oneukum-l3A5Bk7waGM@public.gmane.org> wrote:
>
> No, the problem is autoresume.
>
> Suppose we have a device with two interface. Interface A be usbnet; interface B
> something you page on. Now consider that you can only resume both interfaces
> and this is (and needs to be) done synchronously.
>
> Now we can have this code path:
>
> autoresume of device -> resume() -> kmalloc(..., GFP_KERNEL) ->
> VM layer decides to start paging out -> IO to interface B -> autoresume of device
> --> DEADLOCK
OK, thanks for your detailed explanation.
> We need to use GFP_NOIO in situations the helper cannot know about.
> Please add a gfp_t parameter. Then the caller will solve that.
Considered that most of drivers call the helpers in different context, I think
it is better to switch the gpf_t flag runtime inside helpers, like below:
if (dev->power.runtime_status == RPM_RESUMING)
gfp = GFP_NOIO;
else
gfp = GFP_KERNEL;
Thanks,
--
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ 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