* [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 0/4] sunvnet: add jumbo frames support
From: David L Stevens @ 2014-09-29 17:36 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Sowmini Varadhan, Raghuram Kothakota
In-Reply-To: <542993F1.1090101@oracle.com>
Argh! These patches are whitespace-mangled -- I'll resubmit a different way.
+-DLS
^ permalink raw reply
* [PATCHv7 net-next 0/4] sunvnet: add jumbo frames support
From: David L Stevens @ 2014-09-29 17:42 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
* [PATCH net-next 1/4] sunvnet: upgrade to VIO protocol version 1.6
From: David L Stevens @ 2014-09-29 17:43 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
* [PATCHv7 net-next 2/4] sunvnet: make transmit path zero-copy in the kernel
From: David L Stevens @ 2014-09-29 17:44 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
* [PATCHv7 net-next 3/4] sunvnet: allow admin to set sunvnet MTU
From: David L Stevens @ 2014-09-29 17:45 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
* [PATCHv7 net-next 4/4] sunvnet: generate ICMP PTMUD messages for smaller port MTUs
From: David L Stevens @ 2014-09-29 17:46 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
* Re: [PATCH v2 net-next] mlx4: optimize xmit path
From: Alexei Starovoitov @ 2014-09-29 17:46 UTC (permalink / raw)
To: Eric Dumazet
Cc: Or Gerlitz, David S. Miller, Jesper Dangaard Brouer, Eric Dumazet,
John Fastabend, Linux Netdev List, Amir Vadai, Or Gerlitz
On Sun, Sep 28, 2014 at 9:19 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> send_doorbell = !skb->xmit_more || netif_xmit_stopped(ring->tx_queue);
>
> if (ring->bf_enabled && desc_size <= MAX_BF && !bounce &&
> !vlan_tx_tag_present(skb) && send_doorbell) {
This patch is good,
but I've been thinking more about bf+xmit_more and want
to double check my understanding in that scenario:
xmit_more=true will queue descriptors normally and
the last xmit_more=false packet will write into BF.
I guess BF suppose to pick up the earlier ones from
the queue, otherwise the whole thing is broken.
So if indeed BF can pick up the whole chain, then
it should be the faster way than doing iowrite32(), right?
^ permalink raw reply
* Re: [PATCH net] net/mlx4_en: mlx4_en_netpoll shouldn't call napi_schedule when port is down
From: David Miller @ 2014-09-29 17:47 UTC (permalink / raw)
To: amirv; +Cc: idos, netdev, yevgenyp, ogerlitz
In-Reply-To: <1411988695-30547-1-git-send-email-amirv@mellanox.com>
From: Amir Vadai <amirv@mellanox.com>
Date: Mon, 29 Sep 2014 14:04:55 +0300
> 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.
>
> Signed-off-by: Ido Shamay <idos@mellanox.com>
> Signed-off-by: Amir Vadai <amirv@mellanox.com>
I don't think netpoll should 'variably succeed' on poll controller's
ability to immediately take a trylock.
You need to find a way to make this code always process the queues
when it is called, the approach you are taking here is not a correct.
If you've designed things in such a way that the locking here is
difficult, that's unfortunate but you still have to make this
function behave properly.
^ permalink raw reply
* [PATCHv7 net-next 1/4] sunvnet: upgrade to VIO protocol version 1.6
From: David L Stevens @ 2014-09-29 17:50 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
* Re: VRFs and the scalability of namespaces
From: Cong Wang @ 2014-09-29 18:05 UTC (permalink / raw)
To: David Ahern; +Cc: Eric W. Biederman, Nicolas Dichtel, netdev@vger.kernel.org
In-Reply-To: <5425EAA6.7040302@gmail.com>
On Fri, Sep 26, 2014 at 3:37 PM, David Ahern <dsahern@gmail.com> wrote:
>
> Network Namespaces for VRFs
> ---------------------------
> For the past 4 years or so the response to VRF questions is a drum beat of
> "use network namespaces". But namespaces are not a good match for VRFs.
>
> 1. Network namespaces are a complete separation of the networking stack from
> network devices up. VRFs are an L3 concept. Using namespaces forces an L3
> separation concept onto L2 apps -- lldp, cdp, etc.
>
> There are use cases when you want device level separation, use cases where
> you want only L3 and up separation, and cases where you want both (e.g.,
> divy up the netdevices in a system across some small number of namespaces
> and then provide VRF based features within a namespace).
With regarding to L3 isolation, not limited to VRF, it _does_ sound
like a cleaner
solution than the current L2 isolation, given the fact that:
1) Isolating L2 relies on /sys etc. in practice, which means we have to use
mount namespace as well. Ideally network isolation should be independent of
other namespaces.
2) Some resources still need to be shared, otherwise we have to restart
some services in each of network namespaces as you mentioned. The
~200kb memory overhead is not a problem I think, as now most servers have 8Gb+
memory, the real problem is some service, for example udevd, has some
dependencies, we would fall back to re-implement a whole init service
chain for each
netns, which is the expensive part.
Overall, rather than all or none isolation, we should give the user
some flexibility
to specify which network resources we want to isolation, which we don't. Again,
I am not saying VRF is the solution, I am looking for some more
flexible isolation
solution.
Thanks.
^ permalink raw reply
* Re: [PATCH v2 net-next] mlx4: optimize xmit path
From: Eric Dumazet @ 2014-09-29 18:08 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Or Gerlitz, David S. Miller, Jesper Dangaard Brouer, Eric Dumazet,
John Fastabend, Linux Netdev List, Amir Vadai, Or Gerlitz
In-Reply-To: <CAMEtUuw0UjJuDqSDrK9L-CUWaVdKni1p9cib+VGCOYtBbrCY4Q@mail.gmail.com>
On Mon, 2014-09-29 at 10:46 -0700, Alexei Starovoitov wrote:
> On Sun, Sep 28, 2014 at 9:19 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > send_doorbell = !skb->xmit_more || netif_xmit_stopped(ring->tx_queue);
> >
> > if (ring->bf_enabled && desc_size <= MAX_BF && !bounce &&
> > !vlan_tx_tag_present(skb) && send_doorbell) {
>
> This patch is good,
>
> but I've been thinking more about bf+xmit_more and want
> to double check my understanding in that scenario:
> xmit_more=true will queue descriptors normally and
> the last xmit_more=false packet will write into BF.
> I guess BF suppose to pick up the earlier ones from
> the queue, otherwise the whole thing is broken.
> So if indeed BF can pick up the whole chain, then
> it should be the faster way than doing iowrite32(), right?
> --
Right, this is what my patch is doing.
Say we send a burst of 8 packets.
7 first packets are queued, but no iowrite32() is performed.
final packet is queued, and bf is used to send the doorbell.
With our current stack (net-next), its very easy to check :
Disable tso (ethtool -K eth0 tso off)
Then run netperf -t TCP_RR -H ... -- -r 6000,6000
GSO makes great use of skb->xmit_more right now ;)
(Assuming we do not have GSO preparing hundred of segments out of a
single TSO packet)
^ permalink raw reply
* Re: [PATCH] staging: r8821ae: Remove driver from staging
From: Larry Finger @ 2014-09-29 18:08 UTC (permalink / raw)
To: Greg KH; +Cc: devel, netdev
In-Reply-To: <20140929170519.GA19823@kroah.com>
On 09/29/2014 12:05 PM, Greg KH wrote:
> 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.
I was on the staging-next branch, but when I pulled after receiving this mail, I
got a conflict due to some change in drivers/staging/rtl8821ae/pci.c. That one
must have been in your local copy, but not yet pushed when I pulled.
If you don't mind doing the delete there, the traffic on the Cc sites will be
reduced. I'm sure you know what is needed, but just in case, delete the files in
drivers/staging/rtl8821ae/ and the Makefile and Kconfig entries in drivers/staging/.
Thanks,
Larry
Larry
^ permalink raw reply
* Re: IPv6 FIB related crash with MACVLANs in 3.9.11+ kernel.
From: Hongmei Li @ 2014-09-29 18:15 UTC (permalink / raw)
To: netdev
In-Reply-To: <1411906297.2400343.172598909.66223582@webmail.messagingengine.com>
Thanks Hannes for your prompt response!
We just encountered this issue two times in our product stability test so far,
and my panic backtrace is the exactly same with the one reported here.
I don't know how to reproduce the issue till now.
I tried several method, unfortunately, I can not reproduce it by myself. :(
Thanks,
Hongmei
^ permalink raw reply
* Re: [patch iproute2 1/2] add bridge_slave device support
From: Or Gerlitz @ 2014-09-29 18:20 UTC (permalink / raw)
To: Jiri Pirko
Cc: Linux Netdev List, David Miller, Stephen Hemminger, Scott Feldman,
arvid.brodin, sucheta.chakraborty
In-Reply-To: <1409925309-17881-1-git-send-email-jiri@resnulli.us>
On Fri, Sep 5, 2014 at 4:55 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> Note this depends on "iproute2: allow to change slave options via
> type_slave"
OK, but how about sparing few words what this patch does?
^ permalink raw reply
* Re: [PATCH net 1/1 V2] hyperv: Fix a bug in netvsc_start_xmit()
From: Sitsofe Wheeler @ 2014-09-29 18:31 UTC (permalink / raw)
To: K. Y. Srinivasan; +Cc: davem, netdev, linux-kernel, devel, olaf, apw, jasowang
In-Reply-To: <1411967803-29233-1-git-send-email-kys@microsoft.com>
On Sun, Sep 28, 2014 at 10:16:43PM -0700, K. Y. Srinivasan wrote:
> After the packet is successfully sent, we should not touch the skb
> as it may have been freed. This patch is based on the work done by
> Long Li <longli@microsoft.com>.
>
> In this version of the patch I have fixed issues pointed out by David.
> David, please queue this up for stable.
This patch resolves the following panic I privately reported to KY on September
3rd 2014:
BUG: unable to handle kernel paging request at ffff8800edeb8068
IP: [<ffffffff814e77ec>] netvsc_start_xmit+0x6ac/0x7c0
PGD 2db0067 PUD 2075be067 PMD 20744e067 PTE 80000000edeb8060
Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
CPU: 0 PID: 3 Comm: ksoftirqd/0 Not tainted 3.17.0-rc2.x86_64-00099-g92578ea #139
Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090006 05/23/2012
task: ffff8801fb1b1350 ti: ffff8801fb248000 task.ti: ffff8801fb248000
RIP: 0010:[<ffffffff814e77ec>] [<ffffffff814e77ec>] netvsc_start_xmit+0x6ac/0x7c0
RSP: 0018:ffff8801fb24b808 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff8800efb437c8 RCX: 000000000007f000
RDX: 00000000000782a0 RSI: 000000000000e880 RDI: 000000000007eee8
RBP: ffff8801fb24b850 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000000
R13: ffff8800edeb8000 R14: ffff8800f11b22a0 R15: ffff8800efb47d0e
FS: 0000000000000000(0000) GS:ffff880206c00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff8800edeb8068 CR3: 00000001f6d3d000 CR4: 00000000000406f0
Stack:
ffff8800efb43834 ffffffff00000042 ffff8800f11b22a0 0000000081d23300
0000000000000042 ffff8800f11b22a0 0000000000000002 ffff8801f4866a60
ffff8800edeb8000 ffff8801fb24b8a8 ffffffff815ce528 ffff8800f1164f40
Call Trace:
[<ffffffff815ce528>] dev_hard_start_xmit+0x348/0x630
[<ffffffff815ef67a>] sch_direct_xmit+0x7a/0x290
[<ffffffff815ceb1c>] __dev_queue_xmit+0x30c/0x690
[<ffffffff815ce868>] ? __dev_queue_xmit+0x58/0x690
[<ffffffff815ceeb0>] dev_queue_xmit+0x10/0x20
[<ffffffff8160e6e7>] ip_finish_output+0xaa7/0xc70
[<ffffffff8160eba8>] ? ip_output+0x98/0xf0
[<ffffffff8160eba8>] ip_output+0x98/0xf0
[<ffffffff8160cb71>] ip_local_out_sk+0x71/0xa0
[<ffffffff8160d19a>] ip_queue_xmit+0x38a/0x480
[<ffffffff8160ce15>] ? ip_queue_xmit+0x5/0x480
[<ffffffff81625d69>] tcp_transmit_skb+0x7e9/0x880
[<ffffffff81628bf7>] tcp_send_ack+0x117/0x120
[<ffffffff8161bdf8>] __tcp_ack_snd_check+0x58/0xc0
[<ffffffff81622692>] tcp_rcv_established+0x3f2/0x6e0
[<ffffffff8162d124>] tcp_v4_do_rcv+0xb4/0x350
[<ffffffff8162e571>] tcp_v4_rcv+0x631/0xc30
[<ffffffff81607dc0>] ? ip_local_deliver_finish+0x40/0x2d0
[<ffffffff81607ed8>] ip_local_deliver_finish+0x158/0x2d0
[<ffffffff81607dc0>] ? ip_local_deliver_finish+0x40/0x2d0
[<ffffffff816081f1>] ip_local_deliver+0x51/0x90
[<ffffffff81607cae>] ip_rcv_finish+0x3ae/0x480
[<ffffffff8160854c>] ip_rcv+0x31c/0x3a0
[<ffffffff815ca951>] __netif_receive_skb_core+0x681/0x790
[<ffffffff815ca37c>] ? __netif_receive_skb_core+0xac/0x790
[<ffffffff815caab7>] __netif_receive_skb+0x57/0x80
[<ffffffff815cabaa>] process_backlog+0xca/0x190
[<ffffffff815cf9e8>] net_rx_action+0x88/0x210
[<ffffffff81075303>] __do_softirq+0x183/0x320
[<ffffffff810754c9>] run_ksoftirqd+0x29/0x80
[<ffffffff810929c7>] smpboot_thread_fn+0x1e7/0x210
[<ffffffff8169d545>] ? schedule+0x65/0x70
[<ffffffff810927e0>] ? in_egroup_p+0x40/0x40
[<ffffffff8108e3a8>] kthread+0xf8/0x100
[<ffffffff8108e2b0>] ? __kthread_unpark+0x50/0x50
[<ffffffff816a323c>] ret_from_fork+0x7c/0xb0
[<ffffffff8108e2b0>] ? __kthread_unpark+0x50/0x50
Code: 4b f2 ff ff 41 01 c6 44 39 7d d4 7f c2 44 89 73 58 4c 8b 75 c8 48 89 de 49 8b be 40 0a 00 00 e8 8b 11 00 00 85 c0 41 89 c4 75 1c <41> 8b 45 68 49 83 86 10 01 00 00 01 49 01 86 20 01 00 00 eb 3f
RIP [<ffffffff814e77ec>] netvsc_start_xmit+0x6ac/0x7c0
RSP <ffff8801fb24b808>
CR2: ffff8800edeb8068
---[ end trace 62e7c6df1a71f4a8 ]---
Kernel panic - not syncing: Fatal exception in interrupt
Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffff9fffffff)
---[ end Kernel panic - not syncing: Fatal exception in interrupt
So
Tested-by: Sitsofe Wheeler <sitsofe@yahoo.com>
But I'm still seeing oopses like the following:
BUG: unable to handle kernel paging request at ffff8800ec0b9073
IP: [<ffffffff814e8b63>] netvsc_select_queue+0x53/0x160
PGD 2db3067 PUD 2075be067 PMD 20745d067 PTE 80000000ec0b9060
Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
CPU: 6 PID: 556 Comm: arping Not tainted 3.17.0-rc7.x86_64-00012-gb6beb72-dirty #145
Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090006 05/23/2012
task: ffff8801f3619350 ti: ffff8801f99ac000 task.ti: ffff8801f99ac000
RIP: 0010:[<ffffffff814e8b63>] [<ffffffff814e8b63>] netvsc_select_queue+0x53/0x160
RSP: 0018:ffff8801f99afc60 EFLAGS: 00010202
RAX: 0000000000000000 RBX: ffff8800f1231160 RCX: 000000000000ffff
RDX: ffff8800ec0a9068 RSI: ffff8801f357f3c0 RDI: ffff8800f1231160
RBP: ffff8801f99afc88 R08: 000000000000002a R09: 0000000000000000
R10: ffff8800f12333d8 R11: 0000000000000008 R12: ffff8801f357f3c0
R13: 0000000000000000 R14: ffff8801f97b6f60 R15: ffff8801f357f3c0
FS: 00007fb7a6fbb740(0000) GS:ffff880206cc0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff8800ec0b9073 CR3: 00000001f3518000 CR4: 00000000000406e0
Stack:
ffffffff81698f81 ffff8800f1231160 000000000000001c 0000000000000000
ffff8801f97b6f60 ffff8801f99afd48 ffffffff8169ccec ffff8801f99afcb0
ffffffff816bbf87 0000000000000001 ffff8801f99afdb8 000000000000001c
Call Trace:
[<ffffffff81698f81>] ? packet_pick_tx_queue+0x31/0xa0
[<ffffffff8169ccec>] packet_sendmsg+0xc1c/0xdd0
[<ffffffff816bbf87>] ? _raw_spin_unlock+0x27/0x40
[<ffffffff81090fca>] ? prepare_creds+0x3a/0x170
[<ffffffff815cd978>] sock_sendmsg+0x88/0xb0
[<ffffffff811856d3>] ? might_fault+0xa3/0xb0
[<ffffffff8118568a>] ? might_fault+0x5a/0xb0
[<ffffffff815cdaae>] SYSC_sendto+0x10e/0x150
[<ffffffff8118568a>] ? might_fault+0x5a/0xb0
[<ffffffff816bcc95>] ? sysret_check+0x22/0x5d
[<ffffffff810b97dd>] ? trace_hardirqs_on_caller+0x17d/0x210
[<ffffffff8139da5e>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[<ffffffff815cea8e>] SyS_sendto+0xe/0x10
[<ffffffff816bcc69>] system_call_fastpath+0x16/0x1b
Code: 00 4d 85 d2 0f 84 16 01 00 00 44 8b 9f 8c 03 00 00 31 c0 41 83 fb 01 0f 86 15 01 00 00 0f b7 8e b4 00 00 00 48 8b 96 c0 00 00 00 <66
RIP [<ffffffff814e8b63>] netvsc_select_queue+0x53/0x160
RSP <ffff8801f99afc60>
CR2: ffff8800ec0b9073
---[ end trace 63f1b336a04f57aa ]---
--
Sitsofe | http://sucs.org/~sits/
^ permalink raw reply
* Re: [PATCH v2 0/5] ARCNET: add support for EAE multi interfac card
From: David Miller @ 2014-09-29 18:37 UTC (permalink / raw)
To: m.grzeschik; +Cc: netdev, linux-kernel, kernel
In-Reply-To: <1411984538-953-1-git-send-email-m.grzeschik@pengutronix.de>
From: Michael Grzeschik <m.grzeschik@pengutronix.de>
Date: Mon, 29 Sep 2014 11:55:33 +0200
> this series adds support for the PLX Bridge based multi interface
> pci cards and adds support to change device address on com200xx chips
> during runtime.
>
> This series is based on v3.17-rc7.
> It is fixed for build against com20020_cs.
Series applied, let's see how to compile goes this time.
^ permalink raw reply
* Re: [PATCH next 1/2] tcp: move TCP_ECN_create_request out of header
From: David Miller @ 2014-09-29 18:41 UTC (permalink / raw)
To: fw; +Cc: netdev, dborkman
In-Reply-To: <1411988910-23710-1-git-send-email-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Mon, 29 Sep 2014 13:08:29 +0200
> After Octavian Purdilas tcp ipv4/ipv6 unification work this helper only
> has a single callsite.
>
> While at it, convert name to lowercase, suggested by Stephen.
>
> Suggested-by: Stephen Hemminger <stephen@networkplumber.org>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> Signed-off-by: Florian Westphal <fw@strlen.de>
Applied.
^ permalink raw reply
* Re: [PATCH next 2/2] tcp: change TCP_ECN prefixes to lower case
From: David Miller @ 2014-09-29 18:41 UTC (permalink / raw)
To: fw; +Cc: netdev, dborkman
In-Reply-To: <1411988910-23710-2-git-send-email-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Mon, 29 Sep 2014 13:08:30 +0200
> Suggested by Stephen. Also drop inline keyword and let compiler decide.
>
> gcc 4.7.3 decides to no longer inline tcp_ecn_check_ce, so split it up.
> The actual evaluation is not inlined anymore while the ECN_OK test is.
>
> Suggested-by: Stephen Hemminger <stephen@networkplumber.org>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> Signed-off-by: Florian Westphal <fw@strlen.de>
Applied.
^ permalink raw reply
* Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns
From: Eric W. Biederman @ 2014-09-29 18:43 UTC (permalink / raw)
To: nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w
Cc: Network Development, Linux Containers,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andy Lutomirski, Stephen Hemminger, Cong Wang, Linux API,
Andrew Morton, David S. Miller
In-Reply-To: <54294B4E.70501-pdR9zngts4EAvxtiuMwx3w@public.gmane.org>
Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
> Le 26/09/2014 20:57, Eric W. Biederman a écrit :
>> Andy Lutomirski <luto@amacapital.net> writes:
>>
>>> On Fri, Sep 26, 2014 at 11:10 AM, Eric W. Biederman
>>> <ebiederm@xmission.com> wrote:
>>>> Nicolas Dichtel <nicolas.dichtel@6wind.com> writes:
>>>>
>>>>> The goal of this serie is to be able to multicast netlink messages with an
>>>>> attribute that identify a peer netns.
>>>>> This is needed by the userland to interpret some informations contained in
>>>>> netlink messages (like IFLA_LINK value, but also some other attributes in case
>>>>> of x-netns netdevice (see also
>>>>> http://thread.gmane.org/gmane.linux.network/315933/focus=316064 and
>>>>> http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239)).
>>>>
>>>> I want say that the problem addressed by patch 3/5 of this series is a
>>>> fundamentally valid problem. We have network objects spanning network
>>>> namespaces and it would be very nice to be able to talk about them in
>>>> netlink, and file descriptors are too local and argubably too heavy
>>>> weight for netlink quires and especially for netlink broadcast messages.
>>>>
>>>> Furthermore the concept of ineternal concept of peernet2id seems valid.
>>>>
>>>> However what you do not address is a way for CRIU (aka process
>>>> migration) to be able to restore these ids after process migration.
>>>> Going farther it looks like you are actively breaking process migration
>>>> at this time, making this set of patches a no-go.
> Ok, I will look more deeply into CRIU.
>
>>>>
>>>> When adding a new form of namespace id CRIU patches are just about
>>>> as necessary as iproute patches.
> Noted.
>>>> That does not describe what you have actually implemented in the
>>>> patches.
>>>>
>>>> I see two ways to go with this.
>>>>
>>>> - A per network namespace table to that you can store ids for ``peer''
>>>> network namespaces. The table would need to be populated manually by
>>>> the likes of ip netns add.
>>>>
>>>> That flips the order of assignment and makes this idea solid.
> I have a preference for this solution, because it allows to have a full
> broadcast messages. When you have a lot of network interfaces (> 10k),
> it saves a lot of time to avoid another request to get all informations.
My practical question is how often does it happen that we care?
>>>> Unfortunately in the case of a fully referencing mesh of N network
>>>> namespaces such a mesh winds up taking O(N^2) space, which seems
>>>> undesirable.
> Memory consumption vs performances ;-)
> In fact, when you have a lot of netns, you already should have some memory
> available (at least N lo interfaces + N interfaces (veth or a x-netns
> interface)). I'm not convinced that this is really an obstacle.
I would have to see how it all fits together. O(N^2) grows a lot faster
that N. So after a point it isn't in the same ballpark of memory
consumption.
>> broadcast message business, and only care about the remote namespace for
>> unicast messages. Putting the work in an infrequently used slow path
>> instead of a comparitively common path gives us much more freedom in
>> the implementation.
> I think it's better to have a full netlink messages, instead a partial one.
> There is already a lot of attributes added for each rtnl interface messages to
> be sure to describe all parameters of these interfaces.
> And if the user don't care about ids (user has not set any id with iproute2),
> we can just add the same attribute with id 0 (let's say it's a reserved id) to
> indicate that the link part of this interface is in another netns.
I imagine an id like that is something we would want ip netns add to
set, and probably set in all existing network namespaces as well.
> The great benefit of your first proposal is that the ids are set by the
> userspace and thus it allows a high flexibility.
>
> Would you accept a patch that implements this first solution?
I would not fundamentally reject it. I would really like to make
certain we think through how it will be used and what the practical
benefits are. Depending on how it is used the data structure could
be a killer or it could be a case where we see how to manage it and
simply don't care.
Eric
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
^ permalink raw reply
* Re: IPv6 FIB related crash with MACVLANs in 3.9.11+ kernel.
From: Ben Greear @ 2014-09-29 18:44 UTC (permalink / raw)
To: Hongmei Li; +Cc: netdev
In-Reply-To: <loom.20140929T195637-887@post.gmane.org>
On 09/29/2014 11:15 AM, Hongmei Li wrote:
> Thanks Hannes for your prompt response!
>
> We just encountered this issue two times in our product stability test so far,
> and my panic backtrace is the exactly same with the one reported here.
> I don't know how to reproduce the issue till now.
> I tried several method, unfortunately, I can not reproduce it by myself. :(
We could reproduce it easily using our user-space tool that creates 1000
mac-vlans, configures them, dumps routing tables, etc. But, we could
only reproduce it when we had the ixgbe ports unplugged. If they
were properly connected to a switch, we did not see any crashes.
My original email on 2/3/2014 has more details, and the thread that
follows has some info on debugging we did at the time.
We will be happy to test patches...
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: 3.17-rc1 oops during network interface configuration
From: Chuck Lever @ 2014-09-29 18:52 UTC (permalink / raw)
To: Or Gerlitz
Cc: Govindarajulu Varadarajan, David S. Miller, netdev, LKML Kernel,
linux-rdma, Bart Van Assche, Saeed Mahameed, Tal Alon,
Yevgeny Petrilin, Roland Dreier
In-Reply-To: <541000F1.5000805@mellanox.com>
On Sep 10, 2014, at 3:42 AM, Or Gerlitz <ogerlitz@mellanox.com> wrote:
>
> On 9/9/2014 10:30 PM, Chuck Lever wrote:
>> This crash happens when booting v3.17-rcN on any of my IB-enabled
>> systems. I have both ConnectX-2 and mthca systems, all are affected.
>>
>> I bisected this to:
>>
>> commit e0f31d8498676fda36289603a054d0d490aa2679
>> Author: Govindarajulu Varadarajan <_govind@gmx.com>
>> AuthorDate: Mon Jun 23 16:07:58 2014 +0530
>> Commit: David S. Miller <davem@davemloft.net>
>> CommitDate: Mon Jun 23 14:32:19 2014 -0700
>>
>> flow_keys: Record IP layer protocol in skb_flow_dissect()
>>
>> skb_flow_dissect() dissects only transport header type in ip_proto. It dose not
>> give any information about IPv4 or IPv6.
>> This patch adds new member, n_proto, to struct flow_keys. Which records the
>> IP layer type. i.e IPv4 or IPv6.
>> This can be used in netdev->ndo_rx_flow_steer driver function to dissect flow.
>> Adding new member to flow_keys increases the struct size by around 4 bytes.
>> This causes BUILD_BUG_ON(sizeof(qcb->data) < sz); to fail in
>> qdisc_cb_private_validate()
>> So increase data size by 4
>>
>> Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>>
>>
>> This commit includes a hunk that increases the size of struct qdisc_skb_cb
>> by at least 4 bytes:
>>
>>> diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
>>> index 624f985..a3cfb8e 100644
>>> --- a/include/net/sch_generic.h
>>> +++ b/include/net/sch_generic.h
>>> @@ -231,7 +231,7 @@ struct qdisc_skb_cb {
>>> unsigned int pkt_len;
>>> u16 slave_dev_queue_mapping;
>>> u16 _pad;
>>> - unsigned char data[20];
>>> + unsigned char data[24];
>>> };
>>> static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
>>
>>
>> IPoIB defines the following structure in drivers/infiniband/ulp/ipoib/ipoib.h:
>>
>>> struct ipoib_cb {
>>> struct qdisc_skb_cb qdisc_cb;
>>> u8 hwaddr[INFINIBAND_ALEN];
>>> };
>> IPoIB keeps this in the sk_buff:cb field, which is exactly 48 bytes.
>> After commit e0f31d84, the size of struct ipoib_cb on x86_64 becomes
>> 52 bytes.
>>
>> Thus IPoIB overruns sk_buff:cb, and trashes the sk_buff::_skb_refdst
>> field, which contains a pointer. By the time we get into
>> __dev_queue_xmit() and try to use the result of skb_dst(), that pointer
>> is garbage, and we oops.
>>
>> Obviously, cb[] could be increased to 56 bytes to accommodate struct
>> ipoib_cb. I tried this, and it is effective in preventing the oops on
>> one of my systems.
>>
>> But I suspect there is an historical reason I’m not aware of that it
>> has remained 48 bytes for years.
>
> Hi Chuck, thanks for bisecting this out. Indeed, as of this kernel 3.2 commit 936d7de "IPoIB: Stop lying about hard_header_len and use skb->cb to stash LL addresses" we are using the skb->cb field to enable proper work under GRO and avoid another historical quirk we had there... so I think we can definetly consider commit e0f31d849 to introduce a severe regression... Govindarajulu, Dave - what's your thinking here? any quick idea on how to fix?
Hi Or-
Is there a bugzilla report filed for this issue? Has there been any progress
towards a fix?
> Also, I was thinking we have the mechanics in the kernel, e.g commit a0417fa3a18a ("net: Make qdisc_skb_cb upper size bound explicit.") to catch such over-flows?
>
> Or.
>
>>>> BUG: unable to handle kernel paging request at ffff88090000007e
>>>> IP: __dev_queue_xmit+0x519
>>>> Call Trace:
>>>> ? __dev_queue_xmit+0x49
>>>> dev_queue_xmit+0x10
>>>> neigh_connected_output
>>>> ? ip_finish_output
>>>> ip_finish_output
>>>> ? ip_finish_output
>>>> ? netif_rx_ni
>>>> ip_mc_output
>>>> ip_local_out_sk
>>>> ip_send_skb
>>>> udp_send_skb
>>>> udp_sendmsg
>>>> ? ip_reply_glue_bits
>>>> ? __lock_is_held
>>>> inet_sendmsg
>>>> ? inet_sendmsg
>>>> sock_sendmsg
>>>> ? might_fault
>>>> ? might_fault
>>>> ? move_addr_to_kernel.part.38
>>>> SYSC_sendto
>>>> ? sysret_check
>>>> ? trace_hardirqs_on_caller
>>>> ? trace_hardirqs_on_thunk
>>>> SyS_sendto
>>>> system_call_fastpath
>>>>
>>>> Kernel panic - not syncing: Fatal exception in interrupt
>>>> Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffff9fffffff)
>>>> drm_kms_helper: panic occurred, switching back to text console
>>>>
>>>> A screenshot of this kernel oops can be found here:
>>>> https://drive.google.com/file/d/0B1YQOreL3_FxVDB5UTNwekF6LVU/
>>>>
>>>> gdb translates the crash address into the following (not sure this makes sense
>>>> since offset 0x519 is past the end of __dev_queue_xmit()):
>>>>
>>>> (gdb) list *(__dev_queue_xmit+0x519)
>>>> 0xffffffff8136bc89 is in netdev_adjacent_rename_links (net/core/dev.c:5167).
>>>> 5162 void netdev_adjacent_rename_links(struct net_device *dev, char *oldname)
>>>> 5163 {
>>>> 5164 struct netdev_adjacent *iter;
>>>> 5165
>>>> 5166 list_for_each_entry(iter, &dev->adj_list.upper, list) {
>>>> 5167 netdev_adjacent_sysfs_del(iter->dev, oldname,
>>>> 5168 &iter->dev->adj_list.lower);
>>>> 5169 netdev_adjacent_sysfs_add(iter->dev, dev,
>>>> 5170 &iter->dev->adj_list.lower);
>>>> 5171 }
>>>>
>>>> And the address __dev_queue_xmit+0x49 is translated by gdb into:
>>>>
>>>> (gdb) list *(__dev_queue_xmit+0x49)
>>>> 0xffffffff8136b7b9 is in __dev_queue_xmit (./arch/x86/include/asm/preempt.h:75).
>>>> 70 * The various preempt_count add/sub methods
>>>> 71 */
>>>> 72
>>>> 73 static __always_inline void __preempt_count_add(int val)
>>>> 74 {
>>>> 75 raw_cpu_add_4(__preempt_count, val);
>>>> 76 }
>>>> 77
>>>> 78 static __always_inline void __preempt_count_sub(int val)
>>>> 79 {
>
--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com
^ permalink raw reply
* Re: [PATCH 00/34] pull request: netfilter/ipvs updates for net-next
From: David Miller @ 2014-09-29 18:54 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
In-Reply-To: <1411994363-8451-1-git-send-email-pablo@netfilter.org>
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 29 Sep 2014 14:38:49 +0200
> The following patchset contains Netfilter/IPVS updates for net-next,
> most relevantly they are:
...
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Pulled, thanks Pablo.
Please address Sergei's coding style comments.
Thanks again.
^ permalink raw reply
* Re: [PATCH net-next 2/4] sunvnet: make transmit path zero-copy in the kernel
From: David Miller @ 2014-09-29 18:58 UTC (permalink / raw)
To: david.stevens; +Cc: netdev, sowmini.varadhan, Raghuram.Kothakota
In-Reply-To: <54299407.7010705@oracle.com>
From: David L Stevens <david.stevens@oracle.com>
Date: Mon, 29 Sep 2014 13:16:55 -0400
> 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>
Awesome!!!
However:
> dr->ncookies = ncookies;
> + for (i = 0; i < VNET_TX_RING_SIZE; ++i) {
> + struct vio_net_desc *d;
>
I see a lot of this, I think your patch is corrupted.
^ permalink raw reply
* Re: [PATCH net-next 3/4] sunvnet: allow admin to set sunvnet MTU
From: David Miller @ 2014-09-29 18:58 UTC (permalink / raw)
To: david.stevens; +Cc: netdev, sowmini.varadhan, Raghuram.Kothakota
In-Reply-To: <5429940D.4040500@oracle.com>
From: David L Stevens <david.stevens@oracle.com>
Date: Mon, 29 Sep 2014 13:17:01 -0400
> @@ -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);
More patch corruption.
^ 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