* [PATCH net] gro: fix aggregation for skb using frag_list
From: Eric Dumazet @ 2014-09-29 17:34 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Erez Shitrit
From: Eric Dumazet <edumazet@google.com>
In commit 8a29111c7ca6 ("net: gro: allow to build full sized skb")
I added a regression for linear skb that traditionally force GRO
to use the frag_list fallback.
Erez Shitrit found that at most two segments were aggregated and
the "if (skb_gro_len(p) != pinfo->gso_size)" test was failing.
This is because pinfo at this spot still points to the last skb in the
chain, instead of the first one, where we find the correct gso_size
information.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Fixes: 8a29111c7ca6 ("net: gro: allow to build full sized skb")
Reported-by: Erez Shitrit <erezsh@mellanox.com>
---
net/core/skbuff.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index da1378a3e2c7..8d289697cc7a 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3152,6 +3152,9 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE_STOLEN_HEAD;
goto done;
}
+ /* switch back to head shinfo */
+ pinfo = skb_shinfo(p);
+
if (pinfo->frag_list)
goto merge;
if (skb_gro_len(p) != pinfo->gso_size)
^ permalink raw reply related
* Re: [PATCH net-next] net: cleanup and document skb fclone layout
From: Eric Dumazet @ 2014-09-29 17:23 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <1411860341.15768.55.camel@edumazet-glaptop2.roam.corp.google.com>
On Sat, 2014-09-27 at 16:25 -0700, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Lets use a proper structure to clearly document and implement
> skb fast clones.
>
> Then, we might experiment more easily alternative layouts.
>
> This patch adds a new skb_fclone_busy() helper, used by tcp and xfrm.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> include/linux/skbuff.h | 25 ++++++++++++++++++++++
> net/core/skbuff.c | 44 +++++++++++++++++++--------------------
> net/ipv4/tcp_output.c | 5 ----
> net/xfrm/xfrm_policy.c | 4 ---
> 4 files changed, 49 insertions(+), 29 deletions(-)
I'll rebase this patch and send a v2.
^ permalink raw reply
* [PATCH net-next 4/4] sunvnet: generate ICMP PTMUD messages for smaller port MTUs
From: David L Stevens @ 2014-09-29 17:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sowmini Varadhan, Raghuram Kothakota
This patch sends ICMP and ICMPv6 messages for Path MTU Discovery when a remote
port MTU is smaller than the device MTU. This allows mixing newer VIO protocol
devices that support MTU negotiation with older devices that do not on the
same vswitch. It also allows Linux-Linux LDOMs to use 64K-1 data packets even
though Solaris vswitch is limited to <16K MTU.
Signed-off-by: David L Stevens <david.stevens@oracle.com>
---
drivers/net/ethernet/sun/sunvnet.c | 37 +++++++++++++++++++++++++++++++++++-
1 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 1a7dce0..cb2d2b7 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -17,6 +17,13 @@
#include <linux/mutex.h>
#include <linux/if_vlan.h>
+#if IS_ENABLED(CONFIG_IPV6)
+#include <linux/icmpv6.h>
+#endif
+
+#include <net/icmp.h>
+#include <net/route.h>
+
#include <asm/vio.h>
#include <asm/ldc.h>
@@ -884,8 +891,36 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb = vnet_skb_shape(skb, &start, &nlen);
- if (skb->len > port->rmtu)
+ if (skb->len > port->rmtu) {
+ unsigned long localmtu = port->rmtu - ETH_HLEN;
+
+ if (vio_version_after_eq(&port->vio, 1, 3))
+ localmtu -= VLAN_HLEN;
+
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct flowi4 fl4;
+ struct rtable *rt = NULL;
+
+ memset(&fl4, 0, sizeof(fl4));
+ fl4.flowi4_oif = dev->ifindex;
+ fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
+ fl4.daddr = ip_hdr(skb)->daddr;
+ fl4.saddr = ip_hdr(skb)->saddr;
+
+ rt = ip_route_output_key(dev_net(dev), &fl4);
+ if (!IS_ERR(rt)) {
+ skb_dst_set(skb, &rt->dst);
+ icmp_send(skb, ICMP_DEST_UNREACH,
+ ICMP_FRAG_NEEDED,
+ htonl(localmtu));
+ }
+ }
+#if IS_ENABLED(CONFIG_IPV6)
+ else if (skb->protocol == htons(ETH_P_IPV6))
+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu);
+#endif
goto out_dropped;
+ }
spin_lock_irqsave(&port->vio.lock, flags);
-- 1.7.1
^ permalink raw reply related
* [PATCH net-next 3/4] sunvnet: allow admin to set sunvnet MTU
From: David L Stevens @ 2014-09-29 17:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sowmini Varadhan, Raghuram Kothakota
This patch allows an admin to set the MTU on a sunvnet device to arbitrary
values between the minimum (68) and maximum (65535) IPv4 packet sizes.
Signed-off-by: David L Stevens <david.stevens@oracle.com>
---
arch/sparc/kernel/ldc.c | 2 +-
drivers/net/ethernet/sun/sunvnet.c | 7 +++++--
drivers/net/ethernet/sun/sunvnet.h | 6 ++++--
3 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
index 66dacd5..0af28b9 100644
--- a/arch/sparc/kernel/ldc.c
+++ b/arch/sparc/kernel/ldc.c
@@ -2159,7 +2159,7 @@ int ldc_map_single(struct ldc_channel *lp,
state.pte_idx = (base - iommu->page_table);
state.nc = 0;
fill_cookies(&state, (pa & PAGE_MASK), (pa & ~PAGE_MASK), len);
- BUG_ON(state.nc != 1);
+ BUG_ON(state.nc > ncookies);
return state.nc;
}
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index f3a3fc1..1a7dce0 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -884,6 +884,9 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb = vnet_skb_shape(skb, &start, &nlen);
+ if (skb->len > port->rmtu)
+ goto out_dropped;
+
spin_lock_irqsave(&port->vio.lock, flags);
dr = &port->vio.drings[VIO_DRIVER_TX_RING];
@@ -914,7 +917,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
port->tx_bufs[txi].skb = skb;
err = ldc_map_single(port->vio.lp, start, nlen,
- port->tx_bufs[txi].cookies, 2,
+ port->tx_bufs[txi].cookies, VNET_MAXCOOKIES,
(LDC_MAP_SHADOW | LDC_MAP_DIRECT | LDC_MAP_RW));
if (err < 0) {
netdev_info(dev, "tx buffer map error %d\n", err);
@@ -1143,7 +1146,7 @@ static void vnet_set_rx_mode(struct net_device *dev)
static int vnet_change_mtu(struct net_device *dev, int new_mtu)
{
- if (new_mtu != ETH_DATA_LEN)
+ if (new_mtu < 68 || new_mtu > 65535)
return -EINVAL;
dev->mtu = new_mtu;
diff --git a/drivers/net/ethernet/sun/sunvnet.h b/drivers/net/ethernet/sun/sunvnet.h
index f18409b..ead9001 100644
--- a/drivers/net/ethernet/sun/sunvnet.h
+++ b/drivers/net/ethernet/sun/sunvnet.h
@@ -11,7 +11,7 @@
*/
#define VNET_TX_TIMEOUT (5 * HZ)
-#define VNET_MAXPACKET 1518ULL /* ETH_FRAMELEN + VLAN_HDR */
+#define VNET_MAXPACKET (65535ULL + ETH_HLEN + VLAN_HLEN)
#define VNET_TX_RING_SIZE 512
#define VNET_TX_WAKEUP_THRESH(dr) ((dr)->pending / 4)
@@ -21,10 +21,12 @@
*/
#define VNET_PACKET_SKIP 6
+#define VNET_MAXCOOKIES (VNET_MAXPACKET/PAGE_SIZE + 1)
+
struct vnet_tx_entry {
struct sk_buff *skb;
unsigned int ncookies;
- struct ldc_trans_cookie cookies[2];
+ struct ldc_trans_cookie cookies[VNET_MAXCOOKIES];
};
struct vnet;
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 2/4] sunvnet: make transmit path zero-copy in the kernel
From: David L Stevens @ 2014-09-29 17:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sowmini Varadhan, Raghuram Kothakota
This patch removes pre-allocated transmit buffers and instead directly maps
pending packets on demand. This saves O(n^2) maximum-sized transmit buffers,
for n hosts on a vswitch, as well as a copy to those buffers.
Single-stream TCP throughput linux-solaris dropped ~5% for 1500-byte MTU,
but linux-linux at 1500-bytes increased ~20%.
Signed-off-by: David L Stevens <david.stevens@oracle.com>
---
drivers/net/ethernet/sun/sunvnet.c | 173 +++++++++++++++++++++++++++---------
drivers/net/ethernet/sun/sunvnet.h | 2 +-
2 files changed, 131 insertions(+), 44 deletions(-)
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index b1abcad..f3a3fc1 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -780,6 +780,92 @@ struct vnet_port *tx_port_find(struct vnet *vp, struct sk_buff *skb)
return ret;
}
+static struct sk_buff *vnet_clean_tx_ring(struct vnet_port *port)
+{
+ struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
+ struct sk_buff *skb = NULL;
+ int i, txi;
+
+ txi = dr->prod-1;
+ if (txi < 0)
+ txi = VNET_TX_RING_SIZE-1;
+
+ for (i = 0; i < VNET_TX_RING_SIZE; ++i) {
+ struct vio_net_desc *d;
+
+ d = vio_dring_entry(dr, txi);
+
+ if (d->hdr.state == VIO_DESC_DONE) {
+ if (port->tx_bufs[txi].skb) {
+ BUG_ON(port->tx_bufs[txi].skb->next);
+
+ port->tx_bufs[txi].skb->next = skb;
+ skb = port->tx_bufs[txi].skb;
+ port->tx_bufs[txi].skb = NULL;
+
+ ldc_unmap(port->vio.lp,
+ port->tx_bufs[txi].cookies,
+ port->tx_bufs[txi].ncookies);
+ }
+ d->hdr.state = VIO_DESC_FREE;
+ } else if (d->hdr.state == VIO_DESC_FREE) {
+ break;
+ }
+ --txi;
+ if (txi < 0)
+ txi = VNET_TX_RING_SIZE-1;
+ }
+ return skb;
+}
+
+static inline void vnet_free_skbs(struct sk_buff *skb)
+{
+ struct sk_buff *next;
+
+ while (skb) {
+ next = skb->next;
+ skb->next = NULL;
+ dev_kfree_skb(skb);
+ skb = next;
+ }
+}
+
+static inline struct sk_buff *vnet_skb_shape(struct sk_buff *skb, void **pstart,
+ int *plen)
+{
+ struct sk_buff *nskb;
+ int len, pad;
+
+ len = skb->len;
+ pad = 0;
+ if (len < ETH_ZLEN) {
+ pad += ETH_ZLEN - skb->len;
+ len += pad;
+ }
+ len += VNET_PACKET_SKIP;
+ pad += 8 - (len & 7);
+ len += 8 - (len & 7);
+
+ if (((unsigned long)skb->data & 7) != VNET_PACKET_SKIP ||
+ skb_tailroom(skb) < pad ||
+ skb_headroom(skb) < VNET_PACKET_SKIP) {
+ nskb = alloc_and_align_skb(skb->dev, skb->len);
+ skb_reserve(nskb, VNET_PACKET_SKIP);
+ if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
+ dev_kfree_skb(nskb);
+ dev_kfree_skb(skb);
+ return NULL;
+ }
+ (void)skb_put(nskb, skb->len);
+ dev_kfree_skb(skb);
+ skb = nskb;
+ }
+
+ *pstart = skb->data - VNET_PACKET_SKIP;
+ *plen = len;
+ return skb;
+}
+
static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct vnet *vp = netdev_priv(dev);
@@ -788,12 +874,16 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct vio_net_desc *d;
unsigned long flags;
unsigned int len;
- void *tx_buf;
- int i, err;
+ struct sk_buff *freeskbs = NULL;
+ int i, err, txi;
+ void *start = NULL;
+ int nlen = 0;
if (unlikely(!port))
goto out_dropped;
+ skb = vnet_skb_shape(skb, &start, &nlen);
+
spin_lock_irqsave(&port->vio.lock, flags);
dr = &port->vio.drings[VIO_DRIVER_TX_RING];
@@ -811,14 +901,26 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
d = vio_dring_cur(dr);
- tx_buf = port->tx_bufs[dr->prod].buf;
- skb_copy_from_linear_data(skb, tx_buf + VNET_PACKET_SKIP, skb->len);
+ txi = dr->prod;
+
+ freeskbs = vnet_clean_tx_ring(port);
+
+ BUG_ON(port->tx_bufs[txi].skb);
len = skb->len;
- if (len < ETH_ZLEN) {
+ if (len < ETH_ZLEN)
len = ETH_ZLEN;
- memset(tx_buf+VNET_PACKET_SKIP+skb->len, 0, len - skb->len);
+
+ port->tx_bufs[txi].skb = skb;
+
+ err = ldc_map_single(port->vio.lp, start, nlen,
+ port->tx_bufs[txi].cookies, 2,
+ (LDC_MAP_SHADOW | LDC_MAP_DIRECT | LDC_MAP_RW));
+ if (err < 0) {
+ netdev_info(dev, "tx buffer map error %d\n", err);
+ goto out_dropped_unlock;
}
+ port->tx_bufs[txi].ncookies = err;
/* We don't rely on the ACKs to free the skb in vnet_start_xmit(),
* thus it is safe to not set VIO_ACK_ENABLE for each transmission:
@@ -830,9 +932,9 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
d->hdr.ack = VIO_ACK_DISABLE;
d->size = len;
- d->ncookies = port->tx_bufs[dr->prod].ncookies;
+ d->ncookies = port->tx_bufs[txi].ncookies;
for (i = 0; i < d->ncookies; i++)
- d->cookies[i] = port->tx_bufs[dr->prod].cookies[i];
+ d->cookies[i] = port->tx_bufs[txi].cookies[i];
/* This has to be a non-SMP write barrier because we are writing
* to memory which is shared with the peer LDOM.
@@ -887,7 +989,7 @@ ldc_start_done:
spin_unlock_irqrestore(&port->vio.lock, flags);
- dev_kfree_skb(skb);
+ vnet_free_skbs(freeskbs);
return NETDEV_TX_OK;
@@ -895,7 +997,7 @@ out_dropped_unlock:
spin_unlock_irqrestore(&port->vio.lock, flags);
out_dropped:
- dev_kfree_skb(skb);
+ vnet_free_skbs(freeskbs);
dev->stats.tx_dropped++;
return NETDEV_TX_OK;
}
@@ -1097,17 +1199,22 @@ static void vnet_port_free_tx_bufs(struct vnet_port *port)
}
for (i = 0; i < VNET_TX_RING_SIZE; i++) {
- void *buf = port->tx_bufs[i].buf;
+ struct vio_net_desc *d;
+ void *skb = port->tx_bufs[i].skb;
- if (!buf)
+ if (!skb)
continue;
+ d = vio_dring_entry(dr, i);
+ if (d->hdr.state == VIO_DESC_READY)
+ pr_warn("active transmit buffers freed\n");
+
ldc_unmap(port->vio.lp,
port->tx_bufs[i].cookies,
port->tx_bufs[i].ncookies);
-
- kfree(buf);
- port->tx_bufs[i].buf = NULL;
+ dev_kfree_skb(skb);
+ port->tx_bufs[i].skb = NULL;
+ d->hdr.state = VIO_DESC_FREE;
}
}
@@ -1118,34 +1225,6 @@ static int vnet_port_alloc_tx_bufs(struct vnet_port *port)
int i, err, ncookies;
void *dring;
- for (i = 0; i < VNET_TX_RING_SIZE; i++) {
- void *buf = kzalloc(VNET_MAXPACKET + 8, GFP_KERNEL);
- int map_len = (VNET_MAXPACKET + 7) & ~7;
-
- err = -ENOMEM;
- if (!buf)
- goto err_out;
-
- err = -EFAULT;
- if ((unsigned long)buf & (8UL - 1)) {
- pr_err("TX buffer misaligned\n");
- kfree(buf);
- goto err_out;
- }
-
- err = ldc_map_single(port->vio.lp, buf, map_len,
- port->tx_bufs[i].cookies, 2,
- (LDC_MAP_SHADOW |
- LDC_MAP_DIRECT |
- LDC_MAP_RW));
- if (err < 0) {
- kfree(buf);
- goto err_out;
- }
- port->tx_bufs[i].buf = buf;
- port->tx_bufs[i].ncookies = err;
- }
-
dr = &port->vio.drings[VIO_DRIVER_TX_RING];
len = (VNET_TX_RING_SIZE *
@@ -1172,6 +1251,12 @@ static int vnet_port_alloc_tx_bufs(struct vnet_port *port)
dr->pending = VNET_TX_RING_SIZE;
dr->ncookies = ncookies;
+ for (i = 0; i < VNET_TX_RING_SIZE; ++i) {
+ struct vio_net_desc *d;
+
+ d = vio_dring_entry(dr, i);
+ d->hdr.state = VIO_DESC_FREE;
+ }
return 0;
err_out:
@@ -1203,6 +1288,8 @@ static struct vnet *vnet_new(const u64 *local_mac)
dev = alloc_etherdev(sizeof(*vp));
if (!dev)
return ERR_PTR(-ENOMEM);
+ dev->needed_headroom = VNET_PACKET_SKIP + 8;
+ dev->needed_tailroom = 8;
for (i = 0; i < ETH_ALEN; i++)
dev->dev_addr[i] = (*local_mac >> (5 - i) * 8) & 0xff;
diff --git a/drivers/net/ethernet/sun/sunvnet.h b/drivers/net/ethernet/sun/sunvnet.h
index 986e04b..f18409b 100644
--- a/drivers/net/ethernet/sun/sunvnet.h
+++ b/drivers/net/ethernet/sun/sunvnet.h
@@ -22,7 +22,7 @@
#define VNET_PACKET_SKIP 6
struct vnet_tx_entry {
- void *buf;
+ struct sk_buff *skb;
unsigned int ncookies;
struct ldc_trans_cookie cookies[2];
};
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 1/4] sunvnet: upgrade to VIO protocol version 1.6
From: David L Stevens @ 2014-09-29 17:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sowmini Varadhan, Raghuram Kothakota
This patch upgrades the sunvnet driver to support VIO protocol version 1.6.
In particular, it adds per-port MTU negotiation, allowing MTUs other than
ETH_FRAMELEN with ports using newer VIO protocol versions.
Signed-off-by: David L Stevens <david.stevens@oracle.com>
---
arch/sparc/include/asm/vio.h | 44 ++++++++++++++-
arch/sparc/kernel/viohs.c | 14 ++++-
drivers/net/ethernet/sun/sunvnet.c | 104 +++++++++++++++++++++++++++++------
drivers/net/ethernet/sun/sunvnet.h | 3 +
4 files changed, 143 insertions(+), 22 deletions(-)
diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h
index 5c0ebe7..107d4a4 100644
--- a/arch/sparc/include/asm/vio.h
+++ b/arch/sparc/include/asm/vio.h
@@ -65,6 +65,7 @@ struct vio_dring_register {
u16 options;
#define VIO_TX_DRING 0x0001
#define VIO_RX_DRING 0x0002
+#define VIO_RX_DRING_DATA 0x0004
u16 resv;
u32 num_cookies;
struct ldc_trans_cookie cookies[0];
@@ -80,6 +81,8 @@ struct vio_dring_unregister {
#define VIO_PKT_MODE 0x01 /* Packet based transfer */
#define VIO_DESC_MODE 0x02 /* In-band descriptors */
#define VIO_DRING_MODE 0x03 /* Descriptor rings */
+/* in vers >= 1.2, VIO_DRING_MODE is 0x04 and transfer mode is a bitmask */
+#define VIO_NEW_DRING_MODE 0x04
struct vio_dring_data {
struct vio_msg_tag tag;
@@ -209,10 +212,20 @@ struct vio_net_attr_info {
u8 addr_type;
#define VNET_ADDR_ETHERMAC 0x01
u16 ack_freq;
- u32 resv1;
+ u8 plnk_updt;
+#define PHYSLINK_UPDATE_NONE 0x00
+#define PHYSLINK_UPDATE_STATE 0x01
+#define PHYSLINK_UPDATE_STATE_ACK 0x02
+#define PHYSLINK_UPDATE_STATE_NACK 0x03
+ u8 options;
+ u16 resv1;
u64 addr;
u64 mtu;
- u64 resv2[3];
+ u16 cflags;
+#define VNET_LSO_IPV4_CAPAB 0x0001
+ u16 ipv4_lso_maxlen;
+ u32 resv2;
+ u64 resv3[2];
};
#define VNET_NUM_MCAST 7
@@ -370,6 +383,33 @@ struct vio_driver_state {
struct vio_driver_ops *ops;
};
+static inline bool vio_version_before(struct vio_driver_state *vio,
+ u16 major, u16 minor)
+{
+ u32 have = (u32)vio->ver.major << 16 | vio->ver.minor;
+ u32 want = (u32)major << 16 | minor;
+
+ return have < want;
+}
+
+static inline bool vio_version_after(struct vio_driver_state *vio,
+ u16 major, u16 minor)
+{
+ u32 have = (u32)vio->ver.major << 16 | vio->ver.minor;
+ u32 want = (u32)major << 16 | minor;
+
+ return have > want;
+}
+
+static inline bool vio_version_after_eq(struct vio_driver_state *vio,
+ u16 major, u16 minor)
+{
+ u32 have = (u32)vio->ver.major << 16 | vio->ver.minor;
+ u32 want = (u32)major << 16 | minor;
+
+ return have >= want;
+}
+
#define viodbg(TYPE, f, a...) \
do { if (vio->debug & VIO_DEBUG_##TYPE) \
printk(KERN_INFO "vio: ID[%lu] " f, \
diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c
index f8e7dd5..7ef081a 100644
--- a/arch/sparc/kernel/viohs.c
+++ b/arch/sparc/kernel/viohs.c
@@ -426,6 +426,13 @@ static int process_dreg_info(struct vio_driver_state *vio,
if (vio->dr_state & VIO_DR_STATE_RXREG)
goto send_nack;
+ /* v1.6 and higher, ACK with desired, supported mode, or NACK */
+ if (vio_version_after_eq(vio, 1, 6)) {
+ if (!(pkt->options & VIO_TX_DRING))
+ goto send_nack;
+ pkt->options = VIO_TX_DRING;
+ }
+
BUG_ON(vio->desc_buf);
vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC);
@@ -453,8 +460,11 @@ static int process_dreg_info(struct vio_driver_state *vio,
pkt->tag.stype = VIO_SUBTYPE_ACK;
pkt->dring_ident = ++dr->ident;
- viodbg(HS, "SEND DRING_REG ACK ident[%llx]\n",
- (unsigned long long) pkt->dring_ident);
+ viodbg(HS, "SEND DRING_REG ACK ident[%llx] "
+ "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n",
+ (unsigned long long) pkt->dring_ident,
+ pkt->num_descr, pkt->descr_size, pkt->options,
+ pkt->num_cookies);
len = (sizeof(*pkt) +
(dr->ncookies * sizeof(struct ldc_trans_cookie)));
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index edb8609..b1abcad 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -15,6 +15,7 @@
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
#include <linux/mutex.h>
+#include <linux/if_vlan.h>
#include <asm/vio.h>
#include <asm/ldc.h>
@@ -41,6 +42,7 @@ static int __vnet_tx_trigger(struct vnet_port *port, u32 start);
/* Ordered from largest major to lowest */
static struct vio_version vnet_versions[] = {
+ { .major = 1, .minor = 6 },
{ .major = 1, .minor = 0 },
};
@@ -67,6 +69,7 @@ static int vnet_send_attr(struct vio_driver_state *vio)
struct vnet_port *port = to_vnet_port(vio);
struct net_device *dev = port->vp->dev;
struct vio_net_attr_info pkt;
+ int framelen = ETH_FRAME_LEN;
int i;
memset(&pkt, 0, sizeof(pkt));
@@ -74,19 +77,41 @@ static int vnet_send_attr(struct vio_driver_state *vio)
pkt.tag.stype = VIO_SUBTYPE_INFO;
pkt.tag.stype_env = VIO_ATTR_INFO;
pkt.tag.sid = vio_send_sid(vio);
- pkt.xfer_mode = VIO_DRING_MODE;
+ if (vio_version_before(vio, 1, 2))
+ pkt.xfer_mode = VIO_DRING_MODE;
+ else
+ pkt.xfer_mode = VIO_NEW_DRING_MODE;
pkt.addr_type = VNET_ADDR_ETHERMAC;
pkt.ack_freq = 0;
for (i = 0; i < 6; i++)
pkt.addr |= (u64)dev->dev_addr[i] << ((5 - i) * 8);
- pkt.mtu = ETH_FRAME_LEN;
+ if (vio_version_after(vio, 1, 3)) {
+ if (port->rmtu) {
+ port->rmtu = min(VNET_MAXPACKET, port->rmtu);
+ pkt.mtu = port->rmtu;
+ } else {
+ port->rmtu = VNET_MAXPACKET;
+ pkt.mtu = port->rmtu;
+ }
+ if (vio_version_after_eq(vio, 1, 6))
+ pkt.options = VIO_TX_DRING;
+ } else if (vio_version_before(vio, 1, 3)) {
+ pkt.mtu = framelen;
+ } else { /* v1.3 */
+ pkt.mtu = framelen + VLAN_HLEN;
+ }
+
+ pkt.plnk_updt = PHYSLINK_UPDATE_NONE;
+ pkt.cflags = 0;
viodbg(HS, "SEND NET ATTR xmode[0x%x] atype[0x%x] addr[%llx] "
- "ackfreq[%u] mtu[%llu]\n",
+ "ackfreq[%u] plnk_updt[0x%02x] opts[0x%02x] mtu[%llu] "
+ "cflags[0x%04x] lso_max[%u]\n",
pkt.xfer_mode, pkt.addr_type,
- (unsigned long long) pkt.addr,
- pkt.ack_freq,
- (unsigned long long) pkt.mtu);
+ (unsigned long long)pkt.addr,
+ pkt.ack_freq, pkt.plnk_updt, pkt.options,
+ (unsigned long long)pkt.mtu, pkt.cflags, pkt.ipv4_lso_maxlen);
+
return vio_ldc_send(vio, &pkt, sizeof(pkt));
}
@@ -94,18 +119,52 @@ static int vnet_send_attr(struct vio_driver_state *vio)
static int handle_attr_info(struct vio_driver_state *vio,
struct vio_net_attr_info *pkt)
{
- viodbg(HS, "GOT NET ATTR INFO xmode[0x%x] atype[0x%x] addr[%llx] "
- "ackfreq[%u] mtu[%llu]\n",
+ struct vnet_port *port = to_vnet_port(vio);
+ u64 localmtu;
+ u8 xfer_mode;
+
+ viodbg(HS, "GOT NET ATTR xmode[0x%x] atype[0x%x] addr[%llx] "
+ "ackfreq[%u] plnk_updt[0x%02x] opts[0x%02x] mtu[%llu] "
+ " (rmtu[%llu]) cflags[0x%04x] lso_max[%u]\n",
pkt->xfer_mode, pkt->addr_type,
- (unsigned long long) pkt->addr,
- pkt->ack_freq,
- (unsigned long long) pkt->mtu);
+ (unsigned long long)pkt->addr,
+ pkt->ack_freq, pkt->plnk_updt, pkt->options,
+ (unsigned long long)pkt->mtu, port->rmtu, pkt->cflags,
+ pkt->ipv4_lso_maxlen);
pkt->tag.sid = vio_send_sid(vio);
- if (pkt->xfer_mode != VIO_DRING_MODE ||
+ xfer_mode = pkt->xfer_mode;
+ /* for version < 1.2, VIO_DRING_MODE = 0x3 and no bitmask */
+ if (vio_version_before(vio, 1, 2) && xfer_mode == VIO_DRING_MODE)
+ xfer_mode = VIO_NEW_DRING_MODE;
+
+ /* MTU negotiation:
+ * < v1.3 - ETH_FRAME_LEN exactly
+ * > v1.3 - MIN(pkt.mtu, VNET_MAXPACKET, port->rmtu) and change
+ * pkt->mtu for ACK
+ * = v1.3 - ETH_FRAME_LEN + VLAN_HLEN exactly
+ */
+ if (vio_version_before(vio, 1, 3)) {
+ localmtu = ETH_FRAME_LEN;
+ } else if (vio_version_after(vio, 1, 3)) {
+ localmtu = port->rmtu ? port->rmtu : VNET_MAXPACKET;
+ localmtu = min(pkt->mtu, localmtu);
+ pkt->mtu = localmtu;
+ } else { /* v1.3 */
+ localmtu = ETH_FRAME_LEN + VLAN_HLEN;
+ }
+ port->rmtu = localmtu;
+
+ /* for version >= 1.6, ACK packet mode we support */
+ if (vio_version_after_eq(vio, 1, 6)) {
+ pkt->xfer_mode = VIO_NEW_DRING_MODE;
+ pkt->options = VIO_TX_DRING;
+ }
+
+ if (!(xfer_mode | VIO_NEW_DRING_MODE) ||
pkt->addr_type != VNET_ADDR_ETHERMAC ||
- pkt->mtu != ETH_FRAME_LEN) {
+ pkt->mtu != localmtu) {
viodbg(HS, "SEND NET ATTR NACK\n");
pkt->tag.stype = VIO_SUBTYPE_NACK;
@@ -114,7 +173,14 @@ static int handle_attr_info(struct vio_driver_state *vio,
return -ECONNRESET;
} else {
- viodbg(HS, "SEND NET ATTR ACK\n");
+ viodbg(HS, "SEND NET ATTR ACK xmode[0x%x] atype[0x%x] "
+ "addr[%llx] ackfreq[%u] plnk_updt[0x%02x] opts[0x%02x] "
+ "mtu[%llu] (rmtu[%llu]) cflags[0x%04x] lso_max[%u]\n",
+ pkt->xfer_mode, pkt->addr_type,
+ (unsigned long long)pkt->addr,
+ pkt->ack_freq, pkt->plnk_updt, pkt->options,
+ (unsigned long long)pkt->mtu, port->rmtu, pkt->cflags,
+ pkt->ipv4_lso_maxlen);
pkt->tag.stype = VIO_SUBTYPE_ACK;
@@ -210,7 +276,7 @@ static int vnet_rx_one(struct vnet_port *port, unsigned int len,
int err;
err = -EMSGSIZE;
- if (unlikely(len < ETH_ZLEN || len > ETH_FRAME_LEN)) {
+ if (unlikely(len < ETH_ZLEN || len > port->rmtu)) {
dev->stats.rx_length_errors++;
goto out_dropped;
}
@@ -558,8 +624,10 @@ static void vnet_event(void *arg, int event)
vio_link_state_change(vio, event);
spin_unlock_irqrestore(&vio->lock, flags);
- if (event == LDC_EVENT_RESET)
+ if (event == LDC_EVENT_RESET) {
+ port->rmtu = 0;
vio_port_up(vio);
+ }
return;
}
@@ -1051,8 +1119,8 @@ static int vnet_port_alloc_tx_bufs(struct vnet_port *port)
void *dring;
for (i = 0; i < VNET_TX_RING_SIZE; i++) {
- void *buf = kzalloc(ETH_FRAME_LEN + 8, GFP_KERNEL);
- int map_len = (ETH_FRAME_LEN + 7) & ~7;
+ void *buf = kzalloc(VNET_MAXPACKET + 8, GFP_KERNEL);
+ int map_len = (VNET_MAXPACKET + 7) & ~7;
err = -ENOMEM;
if (!buf)
diff --git a/drivers/net/ethernet/sun/sunvnet.h b/drivers/net/ethernet/sun/sunvnet.h
index da49337..986e04b 100644
--- a/drivers/net/ethernet/sun/sunvnet.h
+++ b/drivers/net/ethernet/sun/sunvnet.h
@@ -11,6 +11,7 @@
*/
#define VNET_TX_TIMEOUT (5 * HZ)
+#define VNET_MAXPACKET 1518ULL /* ETH_FRAMELEN + VLAN_HDR */
#define VNET_TX_RING_SIZE 512
#define VNET_TX_WAKEUP_THRESH(dr) ((dr)->pending / 4)
@@ -44,6 +45,8 @@ struct vnet_port {
u32 stop_rx_idx;
bool stop_rx;
bool start_cons;
+
+ u64 rmtu;
};
static inline struct vnet_port *to_vnet_port(struct vio_driver_state *vio)
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 0/4] sunvnet: add jumbo frames support
From: David L Stevens @ 2014-09-29 17:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sowmini Varadhan, Raghuram Kothakota
This patch set updates the sunvnet driver to version 1.6 of the VIO protocol
to support per-port exchange of MTU information and allow non-standard MTU
sizes, including jumbo frames.
Using large MTUs shows a nearly 5X throughput improvement Linux-Solaris
and > 10X throughput improvement Linux-Linux.
Changes from v6:
-made kernel transmit path zero-copy to remove memory n^2 scaling issue
raised by Raghuram Kothakota <Raghuram.Kothakota@oracle.com>
Changes from v5:
- fixed comment per Sowmini Varadhan <sowmini.varadhan@oracle.com>
Changes from v4:
- changed VNET_MAXPACKET per David Laight <David.Laight@ACULAB.COM>
- added cookies to support non-contiguous buffers of max size
Changes from v3:
- added version functions per Dave Miller <davem@davemloft.net>
- moved rmtu to vnet_port per Dave Miller <davem@davemloft.net>
- explicitly set options bits and capability flags to 0 per
Raghuram Kothakota <Raghuram.Kothakota@oracle.com>
Changes from v2:
- make checkpatch clean
Changes from v1:
- fix brace formatting per Dave Miller <davem@davemloft.net>
David L Stevens (4):
sunvnet: upgrade to VIO protocol version 1.6
sunvnet: make transmit path zero-copy in the kernel
sunvnet: allow admin to set sunvnet MTU
sunvnet: generate ICMP PTMUD messages for smaller port MTUs
arch/sparc/include/asm/vio.h | 44 +++++-
arch/sparc/kernel/ldc.c | 2 +-
arch/sparc/kernel/viohs.c | 14 ++-
drivers/net/ethernet/sun/sunvnet.c | 313 +++++++++++++++++++++++++++++-------
drivers/net/ethernet/sun/sunvnet.h | 9 +-
5 files changed, 315 insertions(+), 67 deletions(-)
^ permalink raw reply
* Re: [PATCH] xen/xenbus: Use 'void' instead of 'int' for the return of xenbus_switch_state()
From: David Vrabel @ 2014-09-29 17:14 UTC (permalink / raw)
To: Konrad Rzeszutek Wilk
Cc: Chen Gang, ian.campbell, wei.liu2, boris.ostrovsky, bhelgaas,
jgross, yongjun_wei, mukesh.rathor, xen-devel,
netdev@vger.kernel.org, linux-pci, linux-scsi,
linux-kernel@vger.kernel.org
In-Reply-To: <20140929154055.GA31952@laptop.dumpdata.com>
On 29/09/14 16:40, Konrad Rzeszutek Wilk wrote:
> On Mon, Sep 29, 2014 at 03:17:10PM +0100, David Vrabel wrote:
>> On 29/09/14 15:02, Konrad Rzeszutek Wilk wrote:
>>> On Sat, Sep 27, 2014 at 12:36:42AM +0800, Chen Gang wrote:
>>>> When xenbus_switch_state() fails, it will call xenbus_switch_fatal()
>>>
>>> Only on the first depth, not on the subsequent ones (as in if
>>> the first xenbus_switch_fail fails, it won't try to call
>>> xenbus_switch_state again and again).
>>>
>>>> internally, so need not return any status value, then use 'void' instead
>>>> of 'int' for xenbus_switch_state() and __xenbus_switch_state().
>>>
>>> When that switch occurs (to XenbusStateConnected) won't the watches
>>> fire - meaning we MUST make sure that the watch functions - if they
>>> use the xenbus_switch_state() they MUST not hold any locks - because
>>> they could be executed once more?
>>>
>>> Oh wait, we don't have to worry about that right now as the callbacks
>>> that pick up the messages from the XenBus are all gated on one mutex
>>> anyhow.
>>>
>>> Hm, anyhow, I would add this extra piece of information to the patch:
>>>
>>>
>>> diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c
>>> index c214daa..f7399fd 100644
>>> --- a/drivers/xen/xen-pciback/xenbus.c
>>> +++ b/drivers/xen/xen-pciback/xenbus.c
>>> @@ -661,6 +661,12 @@ static void xen_pcibk_be_watch(struct xenbus_watch *watch,
>>>
>>> switch (xenbus_read_driver_state(pdev->xdev->nodename)) {
>>> case XenbusStateInitWait:
>>> + /*
>>> + * xenbus_switch_state can call xenbus_switch_fatal which will
>>> + * immediately set the state to XenbusStateClosing which
>>> + * means if we were reading for it here we MUST drop any
>>> + * locks so that we don't dead-lock.
>>> + */
>>
>> Watches are asynchronous and serialised by the xenwatch thread. I can't
>> see what deadlock you're talking about here. Particularly since the
>> backend doesn't watch its own state node (it watches the frontend one).
>>
>>> xen_pcibk_setup_backend(pdev);
>>> break;
>>>
>>>>
>>>> Also need be sure that all callers which check the return value must let
>>>> 'err' be 0.
>>>
>>> I am bit uncomfortable with that, that is due to:
>>>
>>>
>>> .. snip..
>>>> diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
>>>> index 9c47b89..b5c3d47 100644
>>>> --- a/drivers/net/xen-netback/xenbus.c
>>>> +++ b/drivers/net/xen-netback/xenbus.c
>>>> @@ -337,10 +337,7 @@ static int netback_probe(struct xenbus_device *dev,
>>>> if (err)
>>>> pr_debug("Error writing multi-queue-max-queues\n");
>>>>
>>>> - err = xenbus_switch_state(dev, XenbusStateInitWait);
>>>> - if (err)
>>>> - goto fail;
>>>> -
>>>> + xenbus_switch_state(dev, XenbusStateInitWait);
>>>
>>> Which if it fails it won't call:
>>>
>>> 354 fail:
>>> 355 pr_debug("failed\n");
>>> 356 netback_remove(dev);
>>> 357 return err;
>>>
>>>
>>> And since there is no watch on the backend state to go in Closing it won't
>>> ever call those and we leak memory.
>>
>> It's not leaking the memory. All resources will be recovered when the
>> device is removed.
>
> I presume you mean when the XenBus entries are torn down? It does look
> like it would call the .remove functionality. That should take care of that.
>
> In which case we can just remove all of the 'netback_remove()' and also
> remove some of the labels.
No. If the final xenbus_switch_state() fails then at least the device
is in a consistent state, waiting for the other end to notice.
We don't want to return success from a probe with a half-setup device.
David
^ permalink raw reply
* Re: Silicom bypass driver promote from staging
From: gregkh @ 2014-09-29 17:07 UTC (permalink / raw)
To: David Hendel
Cc: Francois Romieu, netdev@vger.kernel.org, arnd@arndb.de,
Anna Lukin
In-Reply-To: <3BFAEADE799AF145974162DF00E013AF018F8C8A9F@exchange2010.silicom.local>
On Mon, Sep 29, 2014 at 07:18:35AM +0000, David Hendel wrote:
> Hi all,
> Sorry, for the late response, we had to go over all the code and update as requested and then test to verify, so here it is.
>
> See below with some responses and attached, hope we can move forward with that. getting the bypass driver into the kernel.
>
> On Thu, 7 Aug 2014 19:56 Stephen Hemminger <stephen@networkplumber.org> wrote:
> >The current driver uses a device specific /proc interface.
> >That API programming model will not likely be acceptable in a standard network driver.
> >Please consider doing something generic with netlink.
>
> Actually, this is not a network driver, many of the users use this
> interface to control the bypass/fail-to-wire to control this
> function. We can add netlink api as additional interface, but not
> having proc interface maybe a problem.
I'm not going to accept a proc interface for a network driver, sorry,
please use netlink. /proc is only for processes for any new
files/functionality.
> On Thu, 7 Aug 2014 23:20 gregkh@linuxfoundation.org wrote:
> >Making your patch an attachment in base64 mode, makes it impossible to
> >quote to review it :(
> >
> >Anyway, I stopped at the first header file. The kernel already has BIT definitions, no driver should ever have to redefine these and do it on their own.
> > That leads me to believe that this code really isn't all that "cleaned up" at all.
> >
> >Should I just look at what is in drivers/staging/silicom/ right now as code to review? Or have you changed it any by making this patch?
>
> OK, will do that,
> drivers/staging/silicom/ driver was created from silicom bypass driver released in December 2012.
> The driver we are providing now is based on this staging driver.
> We updated it to our Latest release (adding support for new adapters, some changes in functionality) and fixed bug (loading the driver from staging led to kernel panic).
>
>
> On Fri, 8 Aug 2014 00:51 Francois Romieu <romieu@fr.zoreil.com> wrote:
> >Location is the easy part. Getting things reviewed is a different story.
> >
> >You shouldn't expect reviewers to swallow 300k of code (600k / 2 due to removal). Please split the submitted patch into smaller, self-consistent, logical ones.
> >
> We will include the patches in the following emails inline each will have smaller size, hope this will be as you expect.
>
> >Notwithstanding Stephen and Jeff's remarks, you should also:
> >- remove the (out-)commented code
> >- reconsider the use of gorilla class macros vs plain functions
> >- stop casting ioremap return into long, then later into void *. It's
> > void __iomem * and should stay so.
> >- use a consistent locking style and remove BP_SYNC_FLAG
> >- fix the 80 cols limit problem(s) (hardly surprizing after 5 levels of
> > nested "if")
> >- avoid redefining stuff from include/uapi/linux/mii.h
> > I may be wrong but BPCTLI_MII_CR_POWER_DOWN smells of BMCR_PDOWN and
> > BPCTLI_PHY_CONTROL, well, MII_BMCR ?
> >- avoid returning with spinlock held (read_reg, wdt_pulse)
> >- start explaining what did change between two submissions
>
> This is what we changed in updated patch:
> 1. Avoid redefining BIT and MII .
> 2. Fixing returning with spinlock held
> 3. Remove BP_SYNC_FLAG
> 4. Use void __iomem * instead of long long in ioremap return
> 5. Cleanup with checkpatch.pl
>
> Hope that it is OK now, or at least better.
>
> Here is the code,
>
>
> Bp_ctl patch,
> --------------------------------------------------------------------------------------------------
> Signed-off-by: Anna Lukin <annal@silicom.co.il>
> diff -uprN -X linux-3.17-rc1-vanilla/Documentation/dontdiff linux-3.17-rc1-vanilla/drivers/bypass/Kconfig linux-3.17-rc1/drivers/bypass/Kconfig
> --- linux-3.17-rc1-vanilla/drivers/bypass/Kconfig 1970-01-01 02:00:00.000000000 +0200
> +++ linux-3.17-rc1/drivers/bypass/Kconfig 2014-08-03 13:48:27.000000000 +0300
This is in an odd format, please read Documentation/SubmittingPatches
for the proper format to send a patch in. There's nothing I can do with
this one, or your other one, sorry :(
greg k-h
^ permalink raw reply
* Re: [PATCH] staging: r8821ae: Remove driver from staging
From: Greg KH @ 2014-09-29 17:05 UTC (permalink / raw)
To: Larry Finger; +Cc: devel, netdev
In-Reply-To: <1411954791-23779-1-git-send-email-Larry.Finger@lwfinger.net>
On Sun, Sep 28, 2014 at 08:39:51PM -0500, Larry Finger wrote:
> A new version of this driver has been merged into the wireless-testing tree
> as commit 21e4b0726dc671c423e2dc9a85364716219c4502. It is both possible and
> desirable to delete the staging version to avoid build errors in linux-next.
>
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> ---
>
> Greg,
>
> This removal patch was generated after commit 368c75b98bdfdfad54e7f165016819ef344e3587.
> It should apply to your tree unless further modifications have been made to
> the staging driver.
Something is odd with this patch, it doesn't apply, even against that
commit id:
Applying: staging: r8821ae: Remove driver from staging
error: patch failed: drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c:1
error: drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c: patch does not apply
Patch failed at 0001 staging: r8821ae: Remove driver from staging
The copy of the patch that failed is found in:
/home/gregkh/linux/work/staging/.git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Can you refresh against the staging-next branch of staging.git and try it
again? Or I can just delete it "by hand" which is fine with me, and might be
easier fro you, just let me know.
thanks,
greg k-h
^ permalink raw reply
* Re: VRFs and the scalability of namespaces
From: Ben Greear @ 2014-09-29 17:00 UTC (permalink / raw)
To: Sowmini Varadhan
Cc: David Ahern, Hannes Frederic Sowa, Eric W. Biederman,
Nicolas Dichtel, netdev
In-Reply-To: <CACP96tR_c3-nVEGhswm1qt1WGXPNzyXA61FCxPutCTPNomjy+g@mail.gmail.com>
On 09/29/2014 09:50 AM, Sowmini Varadhan wrote:
> On Mon, Sep 29, 2014 at 12:40 PM, Ben Greear <greearb@candelatech.com> wrote:
>> On 09/29/2014 06:06 AM, David Ahern wrote:
>
>>
>> We have implemented support for at least most of this (excepting duplicate IPs)
>> using routing tables, rules, and (optionally, xorp as the router).
>>
>
> My undertanding of multiple routing-tables/rules was that they
> are closer in semantics to switch/router ACLs than to VRFs, eg.,
> one big difference is that an interface can belong to exactly one
> VRF at a time, which is not mandated by multiple routing-tables/rules.
>
> Was I mistaken?
You can effectively force an interface to belong to a particular virtual
router (table). It is not trivial to do, and possibly I have still not
covered every possible case. Some rules grow somewhat exponentially as
interfaces are added to virtual routers (ie, preference 10 rules).
Here is our setup for a system with a single virtual router, which uses
table 10001. vap0, vap1, and eth1 are in this virtual router. There are other
interfaces on this system outside of the virtual router, so you can ignore rules
related to those.
You have to add CT zones for each virtual router as well.
[root@ath10k-2220 ~]# ip ru show
10: from all to 5.1.1.1 iif eth1 lookup local
10: from all to 4.1.0.1 iif vap0 lookup local
10: from all to 4.2.0.1 iif vap0 lookup local
10: from all to 4.2.0.1 iif vap1 lookup local
10: from all to 5.1.1.1 iif vap0 lookup local
10: from all to 4.1.0.1 iif vap1 lookup local
10: from all to 4.1.0.1 iif vap1 lookup local
10: from all to 5.1.1.1 iif vap1 lookup local
10: from all to 4.1.0.1 iif eth1 lookup local
10: from all to 4.2.0.1 iif vap0 lookup local
10: from all to 4.2.0.1 iif eth1 lookup local
20: from all iif eth1 lookup 10001
20: from all iif vap0 lookup 10001
20: from all iif vap1 lookup 10001
30: from 5.1.1.1 lookup 10001
30: from 4.1.0.1 lookup 10001
30: from 4.2.0.1 lookup 10001
50: from all oif rddVR0 lookup 6
50: from all oif rddVR1 lookup 7
50: from all oif rddVR2 lookup 8
50: from all oif rddVR3 lookup 9
50: from all oif wlan0 lookup 4
50: from all oif wlan1 lookup 5
50: from all oif eth1 lookup 10001
50: from all oif vap0 lookup 10001
50: from all oif vap1 lookup 10001
512: from all lookup local
32766: from all lookup main
32767: from all lookup default
[root@ath10k-2220 ~]# ip -4 route show table all
unreachable default table 10001
4.1.0.0/16 via 4.1.0.1 dev vap0 table 10001
4.2.0.0/16 via 4.2.0.1 dev vap1 table 10001
5.1.1.0/24 dev eth1 table 10001 scope link
default via 192.168.100.1 dev eth0
4.1.0.0/16 dev vap0 proto kernel scope link src 4.1.0.1
4.2.0.0/16 dev vap1 proto kernel scope link src 4.2.0.1
5.1.1.0/24 dev eth1 proto kernel scope link src 5.1.1.1
169.254.0.0/16 dev eth0 scope link metric 1002
192.168.100.0/24 dev eth0 proto kernel scope link src 192.168.100.179
broadcast 4.1.0.0 dev vap0 table local proto kernel scope link src 4.1.0.1
local 4.1.0.1 dev vap0 table local proto kernel scope host src 4.1.0.1
broadcast 4.1.255.255 dev vap0 table local proto kernel scope link src 4.1.0.1
broadcast 4.2.0.0 dev vap1 table local proto kernel scope link src 4.2.0.1
local 4.2.0.1 dev vap1 table local proto kernel scope host src 4.2.0.1
broadcast 4.2.255.255 dev vap1 table local proto kernel scope link src 4.2.0.1
broadcast 5.1.1.0 dev eth1 table local proto kernel scope link src 5.1.1.1
local 5.1.1.1 dev eth1 table local proto kernel scope host src 5.1.1.1
broadcast 5.1.1.255 dev eth1 table local proto kernel scope link src 5.1.1.1
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
broadcast 192.168.100.0 dev eth0 table local proto kernel scope link src 192.168.100.179
local 192.168.100.179 dev eth0 table local proto kernel scope host src 192.168.100.179
broadcast 192.168.100.255 dev eth0 table local proto kernel scope link src 192.168.100.179
[root@ath10k-2220 ~]# ip route show table 10001
unreachable default
4.1.0.0/16 via 4.1.0.1 dev vap0
4.2.0.0/16 via 4.2.0.1 dev vap1
5.1.1.0/24 dev eth1 scope link
Thanks,
Ben
>
> --Sowmini
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: VRFs and the scalability of namespaces
From: Sowmini Varadhan @ 2014-09-29 16:50 UTC (permalink / raw)
To: Ben Greear
Cc: David Ahern, Hannes Frederic Sowa, Eric W. Biederman,
Nicolas Dichtel, netdev
In-Reply-To: <54298B66.8060807@candelatech.com>
On Mon, Sep 29, 2014 at 12:40 PM, Ben Greear <greearb@candelatech.com> wrote:
> On 09/29/2014 06:06 AM, David Ahern wrote:
>
> We have implemented support for at least most of this (excepting duplicate IPs)
> using routing tables, rules, and (optionally, xorp as the router).
>
My undertanding of multiple routing-tables/rules was that they
are closer in semantics to switch/router ACLs than to VRFs, eg.,
one big difference is that an interface can belong to exactly one
VRF at a time, which is not mandated by multiple routing-tables/rules.
Was I mistaken?
--Sowmini
^ permalink raw reply
* Re: [PATCH net] net/mlx4_en: mlx4_en_netpoll shouldn't call napi_schedule when port is down
From: Cong Wang @ 2014-09-29 16:47 UTC (permalink / raw)
To: Amir Vadai
Cc: David S. Miller, Ido Shamay, netdev, Yevgeny Petrilin, Or Gerlitz
In-Reply-To: <1411988695-30547-1-git-send-email-amirv@mellanox.com>
On Mon, Sep 29, 2014 at 4:04 AM, Amir Vadai <amirv@mellanox.com> wrote:
> From: Ido Shamay <idos@mellanox.com>
>
> mlx4_en_netpoll, which is mlx4_en ndo_poll_controller callback,
> might be called when port is down, causing a napi_schedule when
> napi->poll callback in NULL. mutex_trylock is needed to acquire
> the port_state lock, since other threads may grab it and stop
> the port while we are in napi scheduling. Using trylock since in atomic
> context.
Are you sure it's safe? Its comment says:
* This function must not be used in interrupt context. The
* mutex must be released by the same task that acquired it.
Did you test it with LOCKDEP enabled?
^ permalink raw reply
* Re: VRFs and the scalability of namespaces
From: Ben Greear @ 2014-09-29 16:40 UTC (permalink / raw)
To: David Ahern
Cc: Hannes Frederic Sowa, Eric W. Biederman, nicolas.dichtel, netdev
In-Reply-To: <54295971.2040402@gmail.com>
On 09/29/2014 06:06 AM, David Ahern wrote:
> The features of note:
> - resource efficiency -- not having to create a proces/thread/socket per VRF to have a "presence" in all VRFs. e.g., a VRF any context that allows 1 socket to
> work across VRFs (L3 raw socket, TCP listen socket, unconnected UDP socket). Daemons run a 'vrf any' context; connected clients run a specific vrf context. For
> non-connected sockets VRF context can be passed via cmsg.
>
> - same IP address on different interfaces in different vrfs. i.e., VRF specific routing and neighbor tables
>
> - cross VRF routing. ability to receive message on 1 vrf and send it on another. Can be handled by the process itself (e.g., L3 vpns).
We have implemented support for at least most of this (excepting duplicate IPs)
using routing tables, rules, and (optionally, xorp as the router).
It works ok for our purposes (network simulator), but peformance is not great because
you end up with a large number of ip rules and they are effectively evaluated linearly
it seems.
A quick way to improve performance in our scenario would be to bind rules to
specific interfaces, so that packets process a smaller number of rules when
they enter an interface, I think...but I have not looked into it closely.
It is hard to show you an example of this without you installing our
software to visualize what we are trying to do, but it our software
will work on standard kernels, and we auto-generate a perl script
that sets up all of the rules and such. You could compare the network
diagram in our GUI with the perl script and I think understand the
basics of what we are doing fairly quickly. If you want to take a detailed
look, let me know and I'll set you up with a demo license.
Thanks,
Ben
>
> Thanks,
> David
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH] tcp: remove unnecessary assignment.
From: David Miller @ 2014-09-29 16:31 UTC (permalink / raw)
To: roy.qing.li; +Cc: netdev
In-Reply-To: <1411974277-7236-1-git-send-email-roy.qing.li@gmail.com>
From: roy.qing.li@gmail.com
Date: Mon, 29 Sep 2014 15:04:37 +0800
> From: Li RongQing <roy.qing.li@gmail.com>
>
> This variable i is overwritten to 0 by following code
>
> Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
Applied, thank you.
^ permalink raw reply
* Re: bna alloc_pages() order 2 failure in bnad.c bnad_rxq_refill_page()
From: Stephen Hemminger @ 2014-09-29 16:28 UTC (permalink / raw)
To: Eric Wheeler; +Cc: netdev, rmody
In-Reply-To: <alpine.DEB.2.00.1409271631530.26069@ware.dreamhost.com>
On Sat, 27 Sep 2014 16:44:22 -0700 (PDT)
Eric Wheeler <nevdev@lists.ewheeler.net> wrote:
> Hello all,
>
> We're using the 10gbe bna card and sometimes we get pages and pages of
> alloc_pages() failure backtraces like below. (The maintainer
> rmody@brocade.com does not appear to have an active email at brocade, but
> cc'ing again just in case.)
>
> It looks like bnad_rxq_refill_page() in bnad.c is allocating for the
> receive queue but fails. We've already tried bumping vm.min_free_kbytes
> and vm.zone_reclaim_mode but it doesn't appear to help.
>
> Suggestions?
>
> Would it be appropriate to convert alloc_pages() to a mempool
> implementation?
>
> -Eric
Brocade sold the NIC hardware business off to Qlogic.
I told them to update MAINTAINERS but they haven't submitted a patch yet.
^ permalink raw reply
* Re: [PATCH v2 net-next] net: reorganize sk_buff for faster __copy_skb_header()
From: David Miller @ 2014-09-29 16:27 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, amirv, john.r.fastabend, brouer
In-Reply-To: <1411967927.30721.10.camel@edumazet-glaptop2.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 28 Sep 2014 22:18:47 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> With proliferation of bit fields in sk_buff, __copy_skb_header() became
> quite expensive, showing as the most expensive function in a GSO
> workload.
>
> __copy_skb_header() performance is also critical for non GSO TCP
> operations, as it is used from skb_clone()
>
> This patch carefully moves all the fields that were not copied in a
> separate zone : cloned, nohdr, fclone, peeked, head_frag, xmit_more
>
> Then I moved all other fields and all other copied fields in a section
> delimited by headers_start[0]/headers_end[0] section so that we
> can use a single memcpy() call, inlined by compiler using long
> word load/stores.
>
> I also tried to make all copies in the natural orders of sk_buff,
> to help hardware prefetching.
>
> I made sure sk_buff size did not change.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> v2 : added back ipvs_property, oops ;)
Applied :-)
^ permalink raw reply
* Re: [PATCH 18/34] ipvs: prevent mixing heterogeneous pools and synchronization
From: Sergei Shtylyov @ 2014-09-29 16:17 UTC (permalink / raw)
To: Pablo Neira Ayuso, netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1411994363-8451-19-git-send-email-pablo@netfilter.org>
On 09/29/2014 04:39 PM, Pablo Neira Ayuso wrote:
> From: Alex Gartrell <agartrell@fb.com>
> The synchronization protocol is not compatible with heterogeneous pools, so
> we need to verify that we're not turning both on at the same time.
> Signed-off-by: Alex Gartrell <agartrell@fb.com>
> Acked-by: Julian Anastasov <ja@ssi.bg>
> Signed-off-by: Simon Horman <horms@verge.net.au>
> ---
> include/net/ip_vs.h | 4 ++++
> net/netfilter/ipvs/ip_vs_ctl.c | 15 +++++++++++++++
> 2 files changed, 19 insertions(+)
> diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
> index 7600dbe..576d7f0 100644
> --- a/include/net/ip_vs.h
> +++ b/include/net/ip_vs.h
> @@ -990,6 +990,10 @@ struct netns_ipvs {
> char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
> /* net name space ptr */
> struct net *net; /* Needed by timer routines */
> + /* Number of heterogeneous destinations, needed because
> + * heterogeneous are not supported when synchronization is
> + * enabled */
Multi-line comment style in the networking code is:
/* bla
* bla
*/
> diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
> index 6bd2cc6..462760e 100644
> --- a/net/netfilter/ipvs/ip_vs_ctl.c
> +++ b/net/netfilter/ipvs/ip_vs_ctl.c
[...]
> @@ -3256,6 +3265,12 @@ static int ip_vs_genl_new_daemon(struct net *net, struct nlattr **attrs)
> attrs[IPVS_DAEMON_ATTR_SYNC_ID]))
> return -EINVAL;
>
> + /* The synchronization protocol is incompatible with mixed family
> + * services
> + */
Here you got it right. :-)
> + if (net_ipvs(net)->mixed_address_family_dests > 0)
> + return -EINVAL;
> +
WBR, Sergei
^ permalink raw reply
* Re: [PATCH 33/34] netfilter: nf_tables: store and dump set policy
From: Sergei Shtylyov @ 2014-09-29 16:14 UTC (permalink / raw)
To: Pablo Neira Ayuso, netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1411994363-8451-34-git-send-email-pablo@netfilter.org>
On 09/29/2014 04:39 PM, Pablo Neira Ayuso wrote:
> From: Arturo Borrero <arturo.borrero.glez@gmail.com>
> We want to know in which cases the user explicitly sets the policy
> options. In that case, we also want to dump back the info.
> Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> include/net/netfilter/nf_tables.h | 2 ++
> net/netfilter/nf_tables_api.c | 6 ++++++
> 2 files changed, 8 insertions(+)
> diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
> index c4d8619..3d72923 100644
> --- a/include/net/netfilter/nf_tables.h
> +++ b/include/net/netfilter/nf_tables.h
[...]
> index a476b99..19e79f0 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -2344,6 +2344,11 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
> goto nla_put_failure;
> }
>
> + if (set->policy != NFT_SET_POL_PERFORMANCE) {
> + if (nla_put_be32(skb, NFTA_SET_POLICY, htonl(set->policy)))
> + goto nla_put_failure;
Why not fold these two *if* stetement into a single one?
WBR, Sergei
^ permalink raw reply
* Re: [PATCH 30/34] net/netfilter/x_tables.c: use __seq_open_private()
From: Sergei Shtylyov @ 2014-09-29 16:07 UTC (permalink / raw)
To: Pablo Neira Ayuso, netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1411994363-8451-31-git-send-email-pablo@netfilter.org>
Hello.
On 09/29/2014 04:39 PM, Pablo Neira Ayuso wrote:
> From: Rob Jones <rob.jones@codethink.co.uk>
> Reduce boilerplate code by using __seq_open_private() instead of seq_open()
> in xt_match_open() and xt_target_open().
> Signed-off-by: Rob Jones <rob.jones@codethink.co.uk>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> net/netfilter/x_tables.c | 30 ++++--------------------------
> 1 file changed, 4 insertions(+), 26 deletions(-)
> diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
> index 272ae4d..133eb47 100644
> --- a/net/netfilter/x_tables.c
> +++ b/net/netfilter/x_tables.c
> @@ -1101,22 +1101,11 @@ static const struct seq_operations xt_match_seq_ops = {
>
> static int xt_match_open(struct inode *inode, struct file *file)
> {
> - struct seq_file *seq;
> struct nf_mttg_trav *trav;
> - int ret;
> -
Please don't remove this empty line after declaration.
> - trav = kmalloc(sizeof(*trav), GFP_KERNEL);
> - if (trav == NULL)
> + trav = __seq_open_private(file, &xt_match_seq_ops, sizeof(*trav));
> + if (!trav)
> return -ENOMEM;
>
> - ret = seq_open(file, &xt_match_seq_ops);
> - if (ret < 0) {
> - kfree(trav);
> - return ret;
> - }
> -
> - seq = file->private_data;
> - seq->private = trav;
> trav->nfproto = (unsigned long)PDE_DATA(inode);
> return 0;
> }
> @@ -1165,22 +1154,11 @@ static const struct seq_operations xt_target_seq_ops = {
>
> static int xt_target_open(struct inode *inode, struct file *file)
> {
> - struct seq_file *seq;
> struct nf_mttg_trav *trav;
> - int ret;
> -
Likewise.
> - trav = kmalloc(sizeof(*trav), GFP_KERNEL);
> - if (trav == NULL)
> + trav = __seq_open_private(file, &xt_target_seq_ops, sizeof(*trav));
> + if (!trav)
> return -ENOMEM;
WBR, Sergei
^ permalink raw reply
* Re: [PATCH] team: add rescheduling jiffy delay on !rtnl_trylock
From: Tejun Heo @ 2014-09-29 16:06 UTC (permalink / raw)
To: Joe Lawrence; +Cc: netdev, Jiri Pirko, Paul E. McKenney
In-Reply-To: <20140929115445.40221d8e@jlaw-desktop.mno.stratus.com>
(cc'ing Paul and quoting the whole body)
Paul, this is a fix for RCU sched stall observed w/ a work item
requeueing itself waiting for the RCU grace period. As the self
requeueing work item ends up being executed by the same kworker, the
worker task never stops running in the absence of a higher priority
task and it seems to delay RCU grace period for a very long time on
!PREEMPT kernels. As each work item denotes a boundary which no
synchronization construct stretches across, I wonder whether it'd be a
good idea to add a notification for the end of RCU critical section
between executions of work items.
Thanks.
On Mon, Sep 29, 2014 at 11:54:45AM -0400, Joe Lawrence wrote:
> Hello Jiri,
>
> I've been debugging a hang on RHEL7 that seems to originate in the
> teaming driver and the team_notify_peers_work/team_mcast_rejoin_work
> rtnl_trylock rescheduling logic. Running a stand-alone minimal driver
> mimicing the same schedule_delayed_work(.., 0) reproduces the problem on
> RHEL7 and upstream kernels [1].
>
> A quick summary of the hang:
>
> 1 - systemd-udevd issues an ioctl that heads down dev_ioctl (grabs the
> rtnl_mutex), dev_ifsioc, dev_change_name and finally
> synchronize_sched. In every vmcore I've taken of the hang, this
> thread is waiting on the RCU.
>
> 2 - A kworker thread goes to 100% CPU.
>
> 3 - Inspecting the running thread on the CPU that rcusched reported as
> holding up the RCU grace period usually shows it in either
> team_notify_peers_work, team_mcast_rejoin_work, or somewhere in the
> workqueue code (process_one_work). This is the same CPU/thread as
> #2.
>
> 4 - team_notify_peers_work and team_mcast_rejoin_work want the rtnl_lock
> that systemd-udevd in #1 has, so they try to play nice by calling
> rtnl_trylock and rescheduling on failure. Unfortunately with 0
> jiffy delay, process_one_work will "execute immediately" (ie, after
> others already in queue, but before the next tick). With the stock
> RHEL7 !CONFIG_PREEMPT at least, this creates a tight loop on
> process_one_work + rtnl_trylock that spins the CPU in #2.
>
> 5 - Sometime minutes later, RCU seems to be kicked by a side effect of
> a smp_apic_timer_interrupt. (This was the only other interesting
> function reported by ftrace function tracer).
>
> See the patch below for a potential workaround. Giving at least 1 jiffy
> should give process_one_work some breathing room before calling back
> into team_notify_peers_work/team_mcast_rejoin_work and attempting to
> acquire the rtnl_lock mutex.
>
> Regards,
>
> -- Joe
>
> [1] http://marc.info/?l=linux-kernel&m=141192244232345&w=2
>
> -->8--- -->8--- -->8--- -->8---
>
> From fc5bbf5771b5732f7479ac6e84bbfdde05710023 Mon Sep 17 00:00:00 2001
> From: Joe Lawrence <joe.lawrence@stratus.com>
> Date: Mon, 29 Sep 2014 11:09:05 -0400
> Subject: [PATCH] team: add rescheduling jiffy delay on !rtnl_trylock
>
> Give the CPU running the kworker handling team_notify_peers_work and
> team_mcast_rejoin_work functions some scheduling air by specifying a
> non-zero delay.
>
> Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com>
> ---
> drivers/net/team/team.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
> index ef10302..d46df38 100644
> --- a/drivers/net/team/team.c
> +++ b/drivers/net/team/team.c
> @@ -633,7 +633,7 @@ static void team_notify_peers_work(struct work_struct *work)
> team = container_of(work, struct team, notify_peers.dw.work);
>
> if (!rtnl_trylock()) {
> - schedule_delayed_work(&team->notify_peers.dw, 0);
> + schedule_delayed_work(&team->notify_peers.dw, 1);
> return;
> }
> call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, team->dev);
> @@ -673,7 +673,7 @@ static void team_mcast_rejoin_work(struct work_struct *work)
> team = container_of(work, struct team, mcast_rejoin.dw.work);
>
> if (!rtnl_trylock()) {
> - schedule_delayed_work(&team->mcast_rejoin.dw, 0);
> + schedule_delayed_work(&team->mcast_rejoin.dw, 1);
> return;
> }
> call_netdevice_notifiers(NETDEV_RESEND_IGMP, team->dev);
> --
> 1.7.10.4
>
--
tejun
^ permalink raw reply
* Re: [PATCH] usb: gadget: f_rndis: fix usb_interface_descriptor for rndis
From: Lars Melin @ 2014-09-29 16:05 UTC (permalink / raw)
To: hs
Cc: linux-usb, Felipe Balbi, Greg Kroah-Hartman, linux-kernel, netdev,
linux-api, Andrzej Pietrasiewicz, Michal Nazarewicz,
Kyungmin Park, Dan Carpenter, Macpaul Lin, Meier, Roger
In-Reply-To: <54294C78.6050006@denx.de>
On 2014-09-29 19:11, Heiko Schocher wrote:
> Hello Lars,
>
> sorry for my late answer ...
>
> Am 24.09.2014 16:22, schrieb Lars Melin:
>> On 2014-09-24 20:12, Heiko Schocher wrote:
>>> Hello Lars,
>>>
>>> Am 24.09.2014 14:25, schrieb Lars Melin:
>>>> On 2014-09-24 13:48, Heiko Schocher wrote:
>>>>> use the values for RNDIS over Ethernet as defined in
>>>>> http://www.usb.org/developers/defined_class
>>>>> (search for RDNIS):
>>>>>
>>>>> - baseclass: 0xef (miscellaneous)
>>>>> - subclass: 0x04
>>>>> - protocol: 0x01
>>>>>
>>>> That is usb class, it is not the same thing as communication device
>>>> class.
>>>>> --- a/include/uapi/linux/usb/cdc.h
>>>>> +++ b/include/uapi/linux/usb/cdc.h
>>>>> @@ -12,6 +12,7 @@
>>>>> #include <linux/types.h>
>>>>> #define USB_CDC_SUBCLASS_ACM 0x02
>>>>> +#define USB_CDC_SUBCLASS_RNDIS 0x04
>>>> No, no, no.
>>>> There is no CDC_SUBCLASS_RNDIS and you can not define one over an
>>>> already used cdc subclass number, 0x04 is Multi-Channel Control Model
>>>
>>> Ah, ok, so I have to define this values in a new header file, as there
>>> is no current file for the USB_CLASS_MISC defines? Or is there a proper
>>> place for them?
>>>
>>> BTW: where do I find the "cdc subclass number, 0x04 is Multi-Channel
>>> Control Model" define?
>>>
>>> bye,
>>> Heiko
>>
>> You can still find the original specification usbcdc11.pdf on the net
>> if you google for it, it has been pulled from usb.org where you could
>> download it until a few years ago.
>> It is old but covers a lot of what you need to know.
>
> Hmm.. maybe I am to dummy for finding this docment...
>
> http://www.usb.org/results?q=usbcdc11.pdf&submit=Search
>
> does not find this document ... could you send me a direct link?
>
> I found with the above search:
>
> http://www.usb.org/developers/defined_class
I don't know if it is a good idea to provide a link here to a document
which usb.org has made unavailable, I told you to google for the file
name , not to search for it on usb.org
> and this site, exactly describes the values for RNDIS over ethernet,
> as my patch changes [1]
>
>> Linux has afaik only the cdc.h definition file, everything else is
>> coded by class/subclass in respectively drivers when needed.
>
> why not in header files? I thought, magical values are not welcome
> in source code ...
>
I was wrong, usb class definitions are included in
../include/uapi/linux/usb/ch9.h
> As for the is_rndis() function case, this function is defined in
> 2 places:
>
> - drivers/net/usb/cdc_ether.c
> - drivers/usb/core/generic.c
>
> Has this a special reason? This seems suboptimal to me ...
Yes it has, but the core driver is not an interface driver so it is not
of relevance in this case.
cdc_ether handles interfaces of device connected to the usb bus, not
interfaces of gadget devices
created by linux.
> I got from a customer this patch (in a similiar version) and
> he did tests with [3] and saw, that a board which runs linux,
> is seen in [3] with the values [2] ... so he changed the
> values in drivers/usb/gadget/function/f_rndis.c to the
> values [1], which are documented in [4] and with them
> the test [3] is happy ... and the file
> "Documentation/usb/linux.inf" is not longer needed on the
> windows pc!
>
The patch from your customer removed the most common rndis interface
attributes and substituted them
with one of many other interface attributes which Microsoft uses, this
is not the right way of doing it.
Why did he patch ../core/generic.c and ../net/usb/cdc_ether.c if he
wants to change the interface attributes of g_rndis?
Lars
^ permalink raw reply
* [PATCH] team: add rescheduling jiffy delay on !rtnl_trylock
From: Joe Lawrence @ 2014-09-29 15:54 UTC (permalink / raw)
To: netdev; +Cc: Jiri Pirko, Tejun Heo
Hello Jiri,
I've been debugging a hang on RHEL7 that seems to originate in the
teaming driver and the team_notify_peers_work/team_mcast_rejoin_work
rtnl_trylock rescheduling logic. Running a stand-alone minimal driver
mimicing the same schedule_delayed_work(.., 0) reproduces the problem on
RHEL7 and upstream kernels [1].
A quick summary of the hang:
1 - systemd-udevd issues an ioctl that heads down dev_ioctl (grabs the
rtnl_mutex), dev_ifsioc, dev_change_name and finally
synchronize_sched. In every vmcore I've taken of the hang, this
thread is waiting on the RCU.
2 - A kworker thread goes to 100% CPU.
3 - Inspecting the running thread on the CPU that rcusched reported as
holding up the RCU grace period usually shows it in either
team_notify_peers_work, team_mcast_rejoin_work, or somewhere in the
workqueue code (process_one_work). This is the same CPU/thread as
#2.
4 - team_notify_peers_work and team_mcast_rejoin_work want the rtnl_lock
that systemd-udevd in #1 has, so they try to play nice by calling
rtnl_trylock and rescheduling on failure. Unfortunately with 0
jiffy delay, process_one_work will "execute immediately" (ie, after
others already in queue, but before the next tick). With the stock
RHEL7 !CONFIG_PREEMPT at least, this creates a tight loop on
process_one_work + rtnl_trylock that spins the CPU in #2.
5 - Sometime minutes later, RCU seems to be kicked by a side effect of
a smp_apic_timer_interrupt. (This was the only other interesting
function reported by ftrace function tracer).
See the patch below for a potential workaround. Giving at least 1 jiffy
should give process_one_work some breathing room before calling back
into team_notify_peers_work/team_mcast_rejoin_work and attempting to
acquire the rtnl_lock mutex.
Regards,
-- Joe
[1] http://marc.info/?l=linux-kernel&m=141192244232345&w=2
-->8--- -->8--- -->8--- -->8---
>From fc5bbf5771b5732f7479ac6e84bbfdde05710023 Mon Sep 17 00:00:00 2001
From: Joe Lawrence <joe.lawrence@stratus.com>
Date: Mon, 29 Sep 2014 11:09:05 -0400
Subject: [PATCH] team: add rescheduling jiffy delay on !rtnl_trylock
Give the CPU running the kworker handling team_notify_peers_work and
team_mcast_rejoin_work functions some scheduling air by specifying a
non-zero delay.
Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com>
---
drivers/net/team/team.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index ef10302..d46df38 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -633,7 +633,7 @@ static void team_notify_peers_work(struct work_struct *work)
team = container_of(work, struct team, notify_peers.dw.work);
if (!rtnl_trylock()) {
- schedule_delayed_work(&team->notify_peers.dw, 0);
+ schedule_delayed_work(&team->notify_peers.dw, 1);
return;
}
call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, team->dev);
@@ -673,7 +673,7 @@ static void team_mcast_rejoin_work(struct work_struct *work)
team = container_of(work, struct team, mcast_rejoin.dw.work);
if (!rtnl_trylock()) {
- schedule_delayed_work(&team->mcast_rejoin.dw, 0);
+ schedule_delayed_work(&team->mcast_rejoin.dw, 1);
return;
}
call_netdevice_notifiers(NETDEV_RESEND_IGMP, team->dev);
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH iproute2] ip link: Shortify printing the usage of link type
From: Stephen Hemminger @ 2014-09-29 15:50 UTC (permalink / raw)
To: Vadim Kochan; +Cc: netdev
In-Reply-To: <1411166627-23848-1-git-send-email-vadim4j@gmail.com>
On Sat, 20 Sep 2014 01:43:47 +0300
Vadim Kochan <vadim4j@gmail.com> wrote:
> Allow to print particular link type usage by:
>
> ip link help [TYPE]
>
> Currently to print usage for some link type it is needed
> to use the following way:
>
> ip link { add | del | set } type TYPE help
>
> Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
I like this, but does not apply to current iproute2 tree.
Probably because I took in some other patches.
^ permalink raw reply
* Re: [PATCH 1/1] iproute2: rsvp classifier support for multiple actions
From: Stephen Hemminger @ 2014-09-29 15:48 UTC (permalink / raw)
To: Jamal Hadi Salim; +Cc: john.fastabend, netdev
In-Reply-To: <1411922993-5828-1-git-send-email-jhs@emojatatu.com>
On Sun, 28 Sep 2014 12:49:53 -0400
Jamal Hadi Salim <jhs@mojatatu.com> wrote:
> From: Jamal Hadi Salim <jhs@mojatatu.com>
>
> Example setup:
>
> sudo tc qdisc del dev eth0 root handle 1:0 prio
> sudo tc qdisc add dev eth0 root handle 1:0 prio
>
> sudo tc filter add dev eth0 pref 10 proto ip parent 1:0 \
> rsvp session 10.0.0.1 ipproto icmp \
> classid 1:1 \
> action police rate 1kbit burst 90k pipe \
> action ok
>
> tc -s filter show dev eth0 parent 1:0
>
> filter protocol ip pref 10 rsvp
> filter protocol ip pref 10 rsvp fh 0x0001100a flowid 1:1 session
> 10.0.0.1 ipproto icmp
> action order 1: police 0x5 rate 1Kbit burst 23440b mtu 2Kb
> action pipe overhead 0b
> ref 1 bind 1
> Action statistics:
> Sent 98000 bytes 1000 pkt (dropped 0, overlimits 761 requeues 0)
> backlog 0b 0p requeues 0
>
> action order 2: gact action pass
> random type none pass val 0
> index 2 ref 1 bind 1 installed 60 sec used 3 sec
> Action statistics:
> Sent 74578 bytes 761 pkt (dropped 0, overlimits 0 requeues 0)
> backlog 0b 0p requeues 0
>
> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Applied both rsvp patches
^ 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