* Re: [PATCH v4 2/3] net: Add Keystone NetCP ethernet driver
From: Joe Perches @ 2014-09-25 14:29 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA, sandeep_n-l0cyMroinI0
In-Reply-To: <1411653805-29257-3-git-send-email-santosh.shilimkar-l0cyMroinI0@public.gmane.org>
On Thu, 2014-09-25 at 10:03 -0400, Santosh Shilimkar wrote:
> From: Sandeep Nair <sandeep_n-l0cyMroinI0@public.gmane.org>
>
> The network coprocessor (NetCP) is a hardware accelerator that processes
> Ethernet packets. NetCP has a gigabit Ethernet (GbE) subsystem with a ethernet
> switch sub-module to send and receive packets. NetCP also includes a packet
> accelerator (PA) module to perform packet classification operations such as
> header matching, and packet modification operations such as checksum
> generation. NetCP can also optionally include a Security Accelerator(SA)
> capable of performing IPSec operations on ingress/egress packets.
Some checkpatch trivia you might consider:
---
drivers/net/ethernet/ti/netcp_ethss.c | 29 ++++++++++++-----------------
1 file changed, 12 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c
index 4b273a2..8443bf3 100644
--- a/drivers/net/ethernet/ti/netcp_ethss.c
+++ b/drivers/net/ethernet/ti/netcp_ethss.c
@@ -253,6 +253,7 @@ struct xgbe_hw_stats {
u32 rx_mof_overruns;
u32 rx_dma_overruns;
};
+
#define XGBE10_NUM_STAT_ENTRIES (sizeof(struct xgbe_hw_stats)/sizeof(u32))
struct gbe_ss_regs {
@@ -264,12 +265,12 @@ struct gbe_ss_regs {
u32 rx_en;
u32 tx_en;
u32 misc_en;
- u32 mem_allign1[8];
+ u32 mem_align1[8];
u32 rx_thresh_stat;
u32 rx_stat;
u32 tx_stat;
u32 misc_stat;
- u32 mem_allign2[8];
+ u32 mem_align2[8];
u32 rx_imax;
u32 tx_imax;
};
@@ -398,6 +399,7 @@ struct gbe_hw_stats {
u32 rx_mof_overruns;
u32 rx_dma_overruns;
};
+
#define GBE13_NUM_HW_STAT_ENTRIES (sizeof(struct gbe_hw_stats)/sizeof(u32))
#define GBE13_NUM_HW_STATS_MOD 2
#define XGBE10_NUM_HW_STATS_MOD 3
@@ -1188,7 +1190,6 @@ static void gbe_slave_stop(struct gbe_intf *intf)
cpsw_ale_del_mcast(gbe_dev->ale, intf->ndev->broadcast,
1 << slave->port_num, 0, 0);
-
if (!slave->phy)
return;
@@ -1253,12 +1254,11 @@ static int gbe_slave_open(struct gbe_intf *gbe_intf)
dev_err(priv->dev, "phy not found on slave %d\n",
slave->slave_num);
return -ENODEV;
- } else {
- dev_dbg(priv->dev, "phy found: id is: 0x%s\n",
- dev_name(&slave->phy->dev));
- phy_start(slave->phy);
- phy_read_status(slave->phy);
}
+ dev_dbg(priv->dev, "phy found: id is: 0x%s\n",
+ dev_name(&slave->phy->dev));
+ phy_start(slave->phy);
+ phy_read_status(slave->phy);
}
return 0;
}
@@ -1501,7 +1501,6 @@ static int gbe_open(void *intf_priv, struct net_device *ndev)
else
gbe_intf->tx_pipe.dma_psflags = port_num;
-
dev_dbg(gbe_dev->dev, "opened TX channel %s: %p with psflags %d\n",
gbe_intf->tx_pipe.dma_chan_name,
gbe_intf->tx_pipe.dma_channel,
@@ -1557,7 +1556,7 @@ static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave,
u32 port_reg_ofs, emac_reg_ofs;
if (of_property_read_u32(node, "slave-port", &slave->slave_num)) {
- dev_err(gbe_dev->dev, "missing slave-port paramater\n");
+ dev_err(gbe_dev->dev, "missing slave-port parameter\n");
return -EINVAL;
}
@@ -1906,10 +1905,8 @@ static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
}
gbe_dev = devm_kzalloc(dev, sizeof(struct gbe_priv), GFP_KERNEL);
- if (!gbe_dev) {
- dev_err(dev, "gbe_dev memory allocation failed\n");
+ if (!gbe_dev)
return -ENOMEM;
- }
gbe_dev->dev = dev;
gbe_dev->netcp_device = netcp_device;
@@ -2053,10 +2050,9 @@ static int gbe_attach(void *inst_priv, struct net_device *ndev,
}
gbe_intf = devm_kzalloc(gbe_dev->dev, sizeof(*gbe_intf), GFP_KERNEL);
- if (!gbe_intf) {
- dev_err(gbe_dev->dev, "gbe interface memory allocation failed\n");
+ if (!gbe_intf)
return -ENOMEM;
- }
+
gbe_intf->ndev = ndev;
gbe_intf->dev = gbe_dev->dev;
gbe_intf->gbe_dev = gbe_dev;
@@ -2065,7 +2061,6 @@ static int gbe_attach(void *inst_priv, struct net_device *ndev,
sizeof(*gbe_intf->slave),
GFP_KERNEL);
if (!gbe_intf->slave) {
- dev_err(gbe_dev->dev, "gbe interface slave memory allocation failed\n");
ret = -ENOMEM;
goto fail;
}
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v1 2/4] net: fec: ptp: Use hardware algorithm to adjust PTP counter.
From: Richard Cochran @ 2014-09-25 14:29 UTC (permalink / raw)
To: Luwei Zhou
Cc: davem, netdev, shawn.guo, bhutchings, R49496, b38611, b20596,
stephen
In-Reply-To: <1411632621-17429-3-git-send-email-b45643@freescale.com>
On Thu, Sep 25, 2014 at 04:10:19PM +0800, Luwei Zhou wrote:
> The FEC IP supports hardware adjustment for ptp timer. Refer to the description of
> ENET_ATCOR and ENET_ATINC registers in the spec about the hardware adjustment. This
> patch uses hardware support to adjust the ptp offset and frequency on the slave side.
>
> Signed-off-by: Luwei Zhou <b45643@freescale.com>
> Signed-off-by: Frank Li <Frank.Li@freescale.com>
> Signed-off-by: Fugang Duan <b38611@freescale.com>
> ---
> drivers/net/ethernet/freescale/fec_ptp.c | 68 +++++++++++++++++++++++++++-----
> 1 file changed, 58 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
> index 8016bdd..e2bf786 100644
> --- a/drivers/net/ethernet/freescale/fec_ptp.c
> +++ b/drivers/net/ethernet/freescale/fec_ptp.c
> @@ -71,6 +71,7 @@
>
> #define FEC_CC_MULT (1 << 31)
> #define FEC_COUNTER_PERIOD (1 << 31)
> +#define FEC_T_PERIOD_ONE_SEC (1000000000UL)
Why not use NSEC_PER_USEC?
> /**
> * fec_ptp_read - read raw cycle counter (to be used by time counter)
> * @cc: the cyclecounter structure
> @@ -145,33 +146,65 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
> */
> static int fec_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
> {
> - u64 diff;
> unsigned long flags;
> int neg_adj = 0;
> - u32 mult = FEC_CC_MULT;
> + u32 i, tmp;
> + u32 ptp_ts_clk, ptp_inc;
> + u32 corr_inc, corr_period;
> + u32 corr_ns;
>
> struct fec_enet_private *fep =
> container_of(ptp, struct fec_enet_private, ptp_caps);
>
> + if (ppb == 0)
> + return 0;
> +
> if (ppb < 0) {
> ppb = -ppb;
> neg_adj = 1;
> }
>
> - diff = mult;
> - diff *= ppb;
> - diff = div_u64(diff, 1000000000ULL);
> + ptp_ts_clk = clk_get_rate(fep->clk_ptp);
> + ptp_inc = FEC_T_PERIOD_ONE_SEC / ptp_ts_clk;
No need to calculate this every time.
> +
> + /*
> + * In theory, corr_inc/corr_period = ppb/FEC_T_PERIOD_ONE_SEC;
> + * Try to find the corr_inc between 1 to ptp_inc to meet adjustment
> + * requirement.
> + */
> + for (i = 1; i <= ptp_inc; i++) {
> + if (((i * FEC_T_PERIOD_ONE_SEC) / ppb) >= ptp_inc) {
Does this code even work?
(i * FEC_T_PERIOD_ONE_SEC) overflows when i > 4.
Does this code even compile? You don't use div_u64().
Also, remember that this code is a performance critical path. You have
a 64 bit division in every loop iteration. With a high Sync rate, this
function will be called many times per second. You should really
optimize here.
Instead of testing for
i * FEC_T_PERIOD_ONE_SEC / ppb >= ptp_inc
why not something like
u64 lhs = NSEC_PER_USEC, rhs = ptp_inc * ppb;
for (i = 1; i <= ptp_inc; i++) {
if (lhs >= rhs) {
...
}
lhs += NSEC_PER_USEC;
}
instead?
> + corr_inc = i;
> + corr_period = ((i * FEC_T_PERIOD_ONE_SEC) /
> + (ptp_inc * ppb));
32 bit overflow again.
> + break;
> + }
> + }
> + /*
> + * Not found? Set it to high value - double speed
> + * correct in every clock step.
> + */
> + if (i > ptp_inc) {
> + corr_inc = ptp_inc;
> + corr_period = 1;
> + }
> +
> + if (neg_adj)
> + corr_ns = ptp_inc - corr_inc;
> + else
> + corr_ns = ptp_inc + corr_inc;
>
> spin_lock_irqsave(&fep->tmreg_lock, flags);
> +
> + tmp = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK;
> + tmp |= corr_ns << FEC_T_INC_CORR_OFFSET;
> + writel(tmp, fep->hwp + FEC_ATIME_INC);
> + writel(corr_period, fep->hwp + FEC_ATIME_CORR);
> /*
> - * dummy read to set cycle_last in tc to now.
> - * So use adjusted mult to calculate when next call
> - * timercounter_read.
> + * dummy read to update the timer.
> */
> timecounter_read(&fep->tc);
>
> - fep->cc.mult = neg_adj ? mult - diff : mult + diff;
> -
> spin_unlock_irqrestore(&fep->tmreg_lock, flags);
>
> return 0;
> @@ -190,12 +223,20 @@ static int fec_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
> container_of(ptp, struct fec_enet_private, ptp_caps);
> unsigned long flags;
> u64 now;
> + u32 counter;
>
> spin_lock_irqsave(&fep->tmreg_lock, flags);
>
> now = timecounter_read(&fep->tc);
> now += delta;
>
> + /*
> + * Get the timer value based on adjusted timestamp.
> + * Update the counter with the masked value.
> + */
> + counter = now & fep->cc.mask;
> + writel(counter, fep->hwp + FEC_ATIME);
Why is this needed?
Thanks,
Richard
> +
> /* reset the timecounter */
> timecounter_init(&fep->tc, &fep->cc, now);
>
> @@ -246,6 +287,7 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
>
> u64 ns;
> unsigned long flags;
> + u32 counter;
>
> mutex_lock(&fep->ptp_clk_mutex);
> /* Check the ptp clock */
> @@ -256,8 +298,14 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
>
> ns = ts->tv_sec * 1000000000ULL;
> ns += ts->tv_nsec;
> + /*
> + * Get the timer value based on timestamp.
> + * Update the counter with the masked value.
> + */
> + counter = ns & fep->cc.mask;
>
> spin_lock_irqsave(&fep->tmreg_lock, flags);
> + writel(counter, fep->hwp + FEC_ATIME);
> timecounter_init(&fep->tc, &fep->cc, ns);
> spin_unlock_irqrestore(&fep->tmreg_lock, flags);
> mutex_unlock(&fep->ptp_clk_mutex);
> --
> 1.9.1
>
^ permalink raw reply
* [PATCH net-next] macvlan: add source mode
From: michael-dev @ 2014-09-25 14:31 UTC (permalink / raw)
To: netdev; +Cc: Michael Braun, projekt-wlan
From: Michael Braun <michael-dev@fami-braun.de>
This patch adds a new mode of operation to macvlan, called "source".
It allows one to set a list of allowed mac address, which is used
to match against source mac address from received frames on underlying
interface.
This enables creating mac based VLAN associations, instead of standard
port or tag based. The feature is useful to deploy 802.1x mac based
behavior, where drivers of underlying interfaces doesn't allows that.
Configuration is done through the netlink interface using e.g.:
ip link add link eth0 name macvlan0 type macvlan mode source
ip link add link eth0 name macvlan1 type macvlan mode source
ip link set link dev macvlan0 type macvlan macaddr add 00:11:11:11:11:11
ip link set link dev macvlan0 type macvlan macaddr add 00:22:22:22:22:22
ip link set link dev macvlan0 type macvlan macaddr add 00:33:33:33:33:33
ip link set link dev macvlan1 type macvlan macaddr add 00:33:33:33:33:33
ip link set link dev macvlan1 type macvlan macaddr add 00:44:44:44:44:44
This allows clients with MAC addresses 00:11:11:11:11:11,
00:22:22:22:22:22 to be part of only VLAN associated with macvlan0
interface. Clients with MAC addresses 00:44:44:44:44:44 with only VLAN
associated with macvlan1 interface. And client with MAC address
00:33:33:33:33:33 to be associated with both VLANs.
Based on work of Stefan Gula <steweg@gmail.com>
Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
Cc: <netdev@vger.kernel.org>
Cc: <projekt-wlan@fem.tu-ilmenau.de>
v8: last version of Stefan Gula for Kernel 3.2.1
v9: rework onto linux-next 2014-03-12 by Michael Braun
add MACADDR_SET command, enable to configure mac for source mode
while creating interface
v10:
- reduce indention level
- rename source_list to source_entry
- use aligned 64bit ether address
- use hash_64 instead of addr[5]
v11:
- rebase for 3.14 / linux-next 20.04.2014
v12
- rebase for linux-next 2014-09-25
---
drivers/net/macvlan.c | 304 ++++++++++++++++++++++++++++++++++++++++++-
include/linux/if_macvlan.h | 1 +
include/uapi/linux/if_link.h | 12 ++
3 files changed, 314 insertions(+), 3 deletions(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 726edab..e8a453f 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -35,7 +35,8 @@
#include <net/xfrm.h>
#include <linux/netpoll.h>
-#define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE)
+#define MACVLAN_HASH_BITS 8
+#define MACVLAN_HASH_SIZE (1<<MACVLAN_HASH_BITS)
#define MACVLAN_BC_QUEUE_LEN 1000
struct macvlan_port {
@@ -47,6 +48,14 @@ struct macvlan_port {
struct work_struct bc_work;
bool passthru;
int count;
+ struct hlist_head vlan_source_hash[MACVLAN_HASH_SIZE];
+};
+
+struct macvlan_source_entry {
+ struct hlist_node hlist;
+ struct macvlan_dev *vlan;
+ unsigned char addr[6+2] __aligned(sizeof(u16));
+ struct rcu_head rcu;
};
struct macvlan_skb_cb {
@@ -57,6 +66,20 @@ struct macvlan_skb_cb {
static void macvlan_port_destroy(struct net_device *dev);
+/* Hash Ethernet address */
+static u32 macvlan_eth_hash(const unsigned char *addr)
+{
+ u64 value = get_unaligned((u64 *)addr);
+
+ /* only want 6 bytes */
+#ifdef __BIG_ENDIAN
+ value >>= 16;
+#else
+ value <<= 16;
+#endif
+ return hash_64(value, MACVLAN_HASH_BITS);
+}
+
static struct macvlan_port *macvlan_port_get_rcu(const struct net_device *dev)
{
return rcu_dereference(dev->rx_handler_data);
@@ -73,20 +96,68 @@ static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
const unsigned char *addr)
{
struct macvlan_dev *vlan;
+ u32 idx = macvlan_eth_hash(addr);
- hlist_for_each_entry_rcu(vlan, &port->vlan_hash[addr[5]], hlist) {
+ hlist_for_each_entry_rcu(vlan, &port->vlan_hash[idx], hlist) {
if (ether_addr_equal_64bits(vlan->dev->dev_addr, addr))
return vlan;
}
return NULL;
}
+static struct macvlan_source_entry *macvlan_hash_lookup_source(
+ const struct macvlan_dev *vlan,
+ const unsigned char *addr)
+{
+ struct macvlan_source_entry *entry;
+ u32 idx = macvlan_eth_hash(addr);
+ struct hlist_head *h = &vlan->port->vlan_source_hash[idx];
+
+ hlist_for_each_entry_rcu(entry, h, hlist) {
+ if (ether_addr_equal_64bits(entry->addr, addr) &&
+ entry->vlan == vlan)
+ return entry;
+ }
+ return NULL;
+}
+
+static int macvlan_hash_add_source(struct macvlan_dev *vlan,
+ const unsigned char *addr)
+{
+ struct macvlan_port *port = vlan->port;
+ struct macvlan_source_entry *entry;
+ struct hlist_head *h;
+
+ entry = macvlan_hash_lookup_source(vlan, addr);
+ if (entry)
+ return 0;
+
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ ether_addr_copy(entry->addr, addr);
+ entry->vlan = vlan;
+ h = &port->vlan_source_hash[macvlan_eth_hash(addr)];
+ hlist_add_head_rcu(&entry->hlist, h);
+ vlan->macaddr_count++;
+
+ return 0;
+}
+
static void macvlan_hash_add(struct macvlan_dev *vlan)
{
struct macvlan_port *port = vlan->port;
const unsigned char *addr = vlan->dev->dev_addr;
+ u32 idx = macvlan_eth_hash(addr);
- hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[addr[5]]);
+ hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[idx]);
+}
+
+static void macvlan_hash_del_source(struct macvlan_source_entry *entry)
+{
+ hlist_del_rcu(&entry->hlist);
+ kfree_rcu(entry, rcu);
}
static void macvlan_hash_del(struct macvlan_dev *vlan, bool sync)
@@ -267,6 +338,65 @@ err:
atomic_long_inc(&skb->dev->rx_dropped);
}
+static void macvlan_flush_sources(struct macvlan_port *port,
+ struct macvlan_dev *vlan)
+{
+ int i;
+
+ for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
+ struct hlist_node *h, *n;
+
+ hlist_for_each_safe(h, n, &port->vlan_source_hash[i]) {
+ struct macvlan_source_entry *entry;
+
+ entry = hlist_entry(h, struct macvlan_source_entry,
+ hlist);
+ if (entry->vlan == vlan)
+ macvlan_hash_del_source(entry);
+ }
+ }
+ vlan->macaddr_count = 0;
+}
+
+static void macvlan_forward_source_one(struct sk_buff *skb,
+ struct macvlan_dev *vlan)
+{
+ struct sk_buff *nskb;
+ struct net_device *dev;
+ int len;
+ int ret;
+
+ dev = vlan->dev;
+ if (unlikely(!(dev->flags & IFF_UP)))
+ return;
+
+ nskb = skb_clone(skb, GFP_ATOMIC);
+ if (!nskb)
+ return;
+
+ len = nskb->len + ETH_HLEN;
+ nskb->dev = dev;
+ nskb->pkt_type = PACKET_HOST;
+
+ ret = netif_rx(nskb);
+ macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, 0);
+}
+
+static void macvlan_forward_source(struct sk_buff *skb,
+ struct macvlan_port *port,
+ const unsigned char *addr)
+{
+ struct macvlan_source_entry *entry;
+ u32 idx = macvlan_eth_hash(addr);
+ struct hlist_head *h = &port->vlan_source_hash[idx];
+
+ hlist_for_each_entry_rcu(entry, h, hlist) {
+ if (ether_addr_equal_64bits(entry->addr, addr))
+ if (entry->vlan->dev->flags & IFF_UP)
+ macvlan_forward_source_one(skb, entry->vlan);
+ }
+}
+
/* called under rcu_read_lock() from netif_receive_skb */
static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
{
@@ -285,6 +415,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
if (!skb)
return RX_HANDLER_CONSUMED;
eth = eth_hdr(skb);
+ macvlan_forward_source(skb, port, eth->h_source);
src = macvlan_hash_lookup(port, eth->h_source);
if (src && src->mode != MACVLAN_MODE_VEPA &&
src->mode != MACVLAN_MODE_BRIDGE) {
@@ -301,6 +432,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
return RX_HANDLER_PASS;
}
+ macvlan_forward_source(skb, port, eth->h_source);
if (port->passthru)
vlan = list_first_or_null_rcu(&port->vlans,
struct macvlan_dev, list);
@@ -667,6 +799,7 @@ static void macvlan_uninit(struct net_device *dev)
free_percpu(vlan->pcpu_stats);
+ macvlan_flush_sources(port, vlan);
port->count -= 1;
if (!port->count)
macvlan_port_destroy(port->dev);
@@ -925,6 +1058,8 @@ static int macvlan_port_create(struct net_device *dev)
INIT_LIST_HEAD(&port->vlans);
for (i = 0; i < MACVLAN_HASH_SIZE; i++)
INIT_HLIST_HEAD(&port->vlan_hash[i]);
+ for (i = 0; i < MACVLAN_HASH_SIZE; i++)
+ INIT_HLIST_HEAD(&port->vlan_source_hash[i]);
skb_queue_head_init(&port->bc_queue);
INIT_WORK(&port->bc_work, macvlan_process_broadcast);
@@ -966,11 +1101,102 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
case MACVLAN_MODE_VEPA:
case MACVLAN_MODE_BRIDGE:
case MACVLAN_MODE_PASSTHRU:
+ case MACVLAN_MODE_SOURCE:
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ if (data && data[IFLA_MACVLAN_MACADDR_MODE]) {
+ switch (nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE])) {
+ case MACVLAN_MACADDR_ADD:
+ case MACVLAN_MACADDR_DEL:
+ case MACVLAN_MACADDR_FLUSH:
+ case MACVLAN_MACADDR_SET:
break;
default:
return -EINVAL;
}
}
+
+ if (data && data[IFLA_MACVLAN_MACADDR]) {
+ if (nla_len(data[IFLA_MACVLAN_MACADDR]) != ETH_ALEN)
+ return -EINVAL;
+
+ if (!is_valid_ether_addr(nla_data(data[IFLA_MACVLAN_MACADDR])))
+ return -EADDRNOTAVAIL;
+ }
+
+ if (data && data[IFLA_MACVLAN_MACADDR_COUNT])
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * reconfigure list of remote source mac address
+ * (only for macvlan devices in source mode)
+ * Note regarding alignment: all netlink data is aligned to 4 Byte, which
+ * suffices for both ether_addr_copy and ether_addr_equal_64bits usage.
+ */
+static int macvlan_changelink_sources(struct macvlan_dev *vlan, u32 mode,
+ struct nlattr *data[])
+{
+ char *addr = NULL;
+ int ret, rem, len;
+ struct nlattr *nla, *head;
+ struct macvlan_source_entry *entry;
+
+ if (data[IFLA_MACVLAN_MACADDR])
+ addr = nla_data(data[IFLA_MACVLAN_MACADDR]);
+
+ if (mode == MACVLAN_MACADDR_ADD) {
+ if (!addr)
+ return -EINVAL;
+
+ return macvlan_hash_add_source(vlan, addr);
+
+ } else if (mode == MACVLAN_MACADDR_DEL) {
+ if (!addr)
+ return -EINVAL;
+
+ entry = macvlan_hash_lookup_source(vlan, addr);
+ if (entry) {
+ macvlan_hash_del_source(entry);
+ vlan->macaddr_count--;
+ }
+ } else if (mode == MACVLAN_MACADDR_FLUSH) {
+ macvlan_flush_sources(vlan->port, vlan);
+ } else if (mode == MACVLAN_MACADDR_SET) {
+ macvlan_flush_sources(vlan->port, vlan);
+
+ if (addr) {
+ ret = macvlan_hash_add_source(vlan, addr);
+ if (ret)
+ return ret;
+ }
+
+ if (!data || !data[IFLA_MACVLAN_MACADDR_DATA])
+ return 0;
+
+ head = nla_data(data[IFLA_MACVLAN_MACADDR_DATA]);
+ len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
+
+ nla_for_each_attr(nla, head, len, rem) {
+ if (nla_type(nla) != IFLA_MACVLAN_MACADDR ||
+ nla_len(nla) != ETH_ALEN)
+ continue;
+
+ addr = nla_data(nla);
+ ret = macvlan_hash_add_source(vlan, addr);
+ if (ret)
+ return ret;
+ }
+ } else {
+ return -EINVAL;
+ }
+
return 0;
}
@@ -981,6 +1207,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
struct macvlan_port *port;
struct net_device *lowerdev;
int err;
+ int macmode;
if (!tb[IFLA_LINK])
return -EINVAL;
@@ -1034,6 +1261,15 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
eth_hw_addr_inherit(dev, lowerdev);
}
+ if (data && data[IFLA_MACVLAN_MACADDR_MODE]) {
+ if (vlan->mode != MACVLAN_MODE_SOURCE)
+ return -EINVAL;
+ macmode = nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE]);
+ err = macvlan_changelink_sources(vlan, macmode, data);
+ if (err)
+ return err;
+ }
+
port->count += 1;
err = register_netdevice(dev);
if (err < 0)
@@ -1070,6 +1306,8 @@ void macvlan_dellink(struct net_device *dev, struct list_head *head)
{
struct macvlan_dev *vlan = netdev_priv(dev);
+ if (vlan->mode == MACVLAN_MODE_SOURCE)
+ macvlan_flush_sources(vlan->port, vlan);
list_del_rcu(&vlan->list);
unregister_netdevice_queue(dev, head);
netdev_upper_dev_unlink(vlan->lowerdev, dev);
@@ -1082,6 +1320,8 @@ static int macvlan_changelink(struct net_device *dev,
struct macvlan_dev *vlan = netdev_priv(dev);
enum macvlan_mode mode;
bool set_mode = false;
+ enum macvlan_macaddr_mode macmode;
+ int ret;
/* Validate mode, but don't set yet: setting flags may fail. */
if (data && data[IFLA_MACVLAN_MODE]) {
@@ -1091,6 +1331,9 @@ static int macvlan_changelink(struct net_device *dev,
if ((mode == MACVLAN_MODE_PASSTHRU) !=
(vlan->mode == MACVLAN_MODE_PASSTHRU))
return -EINVAL;
+ if (vlan->mode == MACVLAN_MODE_SOURCE &&
+ vlan->mode != mode)
+ macvlan_flush_sources(vlan->port, vlan);
}
if (data && data[IFLA_MACVLAN_FLAGS]) {
@@ -1110,26 +1353,77 @@ static int macvlan_changelink(struct net_device *dev,
}
if (set_mode)
vlan->mode = mode;
+ if (data && data[IFLA_MACVLAN_MACADDR_MODE]) {
+ if (vlan->mode != MACVLAN_MODE_SOURCE)
+ return -EINVAL;
+ macmode = nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE]);
+ ret = macvlan_changelink_sources(vlan, macmode, data);
+ if (ret)
+ return ret;
+ }
return 0;
}
+static size_t macvlan_get_size_mac(const struct macvlan_dev *vlan)
+{
+ if (vlan->macaddr_count == 0)
+ return 0;
+ return nla_total_size(0) /* IFLA_MACVLAN_MACADDR_DATA */
+ + vlan->macaddr_count * nla_total_size(sizeof(u8) * ETH_ALEN);
+}
+
static size_t macvlan_get_size(const struct net_device *dev)
{
+ struct macvlan_dev *vlan = netdev_priv(dev);
+
return (0
+ nla_total_size(4) /* IFLA_MACVLAN_MODE */
+ nla_total_size(2) /* IFLA_MACVLAN_FLAGS */
+ + nla_total_size(4) /* IFLA_MACVLAN_MACADDR_COUNT */
+ + macvlan_get_size_mac(vlan) /* IFLA_MACVLAN_MACADDR */
);
}
+static int macvlan_fill_info_macaddr(struct sk_buff *skb,
+ const struct macvlan_dev *vlan,
+ const int i)
+{
+ struct hlist_head *h = &vlan->port->vlan_source_hash[i];
+ struct macvlan_source_entry *entry;
+
+ hlist_for_each_entry_rcu(entry, h, hlist) {
+ if (entry->vlan != vlan)
+ continue;
+ if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr))
+ return 1;
+ }
+ return 0;
+}
+
static int macvlan_fill_info(struct sk_buff *skb,
const struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
+ int i;
+ struct nlattr *nest;
if (nla_put_u32(skb, IFLA_MACVLAN_MODE, vlan->mode))
goto nla_put_failure;
if (nla_put_u16(skb, IFLA_MACVLAN_FLAGS, vlan->flags))
goto nla_put_failure;
+ if (nla_put_u32(skb, IFLA_MACVLAN_MACADDR_COUNT, vlan->macaddr_count))
+ goto nla_put_failure;
+ if (vlan->macaddr_count > 0) {
+ nest = nla_nest_start(skb, IFLA_MACVLAN_MACADDR_DATA);
+ if (nest == NULL)
+ goto nla_put_failure;
+
+ for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
+ if (macvlan_fill_info_macaddr(skb, vlan, i))
+ goto nla_put_failure;
+ }
+ nla_nest_end(skb, nest);
+ }
return 0;
nla_put_failure:
@@ -1139,6 +1433,10 @@ nla_put_failure:
static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = {
[IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
[IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
+ [IFLA_MACVLAN_MACADDR_MODE] = { .type = NLA_U32 },
+ [IFLA_MACVLAN_MACADDR] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
+ [IFLA_MACVLAN_MACADDR_DATA] = { .type = NLA_NESTED },
+ [IFLA_MACVLAN_MACADDR_COUNT] = { .type = NLA_U32 },
};
int macvlan_link_register(struct rtnl_link_ops *ops)
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h
index 6b2c7cf..6f6929e 100644
--- a/include/linux/if_macvlan.h
+++ b/include/linux/if_macvlan.h
@@ -60,6 +60,7 @@ struct macvlan_dev {
#ifdef CONFIG_NET_POLL_CONTROLLER
struct netpoll *netpoll;
#endif
+ unsigned int macaddr_count;
};
static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index c80f95f..0bdb77e 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -303,6 +303,10 @@ enum {
IFLA_MACVLAN_UNSPEC,
IFLA_MACVLAN_MODE,
IFLA_MACVLAN_FLAGS,
+ IFLA_MACVLAN_MACADDR_MODE,
+ IFLA_MACVLAN_MACADDR,
+ IFLA_MACVLAN_MACADDR_DATA,
+ IFLA_MACVLAN_MACADDR_COUNT,
__IFLA_MACVLAN_MAX,
};
@@ -313,6 +317,14 @@ enum macvlan_mode {
MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
+ MACVLAN_MODE_SOURCE = 16,/* use source MAC address list to assign */
+};
+
+enum macvlan_macaddr_mode {
+ MACVLAN_MACADDR_ADD,
+ MACVLAN_MACADDR_DEL,
+ MACVLAN_MACADDR_FLUSH,
+ MACVLAN_MACADDR_SET,
};
#define MACVLAN_FLAG_NOPROMISC 1
--
1.8.5.5
^ permalink raw reply related
* Re: [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Tom Herbert @ 2014-09-25 14:40 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: Jesper Dangaard Brouer, Eric Dumazet, Linux Netdev List,
David S. Miller, Alexander Duyck,
Toke Høiland-Jørgensen, Florian Westphal, Dave Taht,
John Fastabend, Daniel Borkmann, Hannes Frederic Sowa
In-Reply-To: <54240F34.1050707@mojatatu.com>
On Thu, Sep 25, 2014 at 5:48 AM, Jamal Hadi Salim <jhs@mojatatu.com> wrote:
> On 09/25/14 04:25, Jesper Dangaard Brouer wrote:
>>
>> On Wed, 24 Sep 2014 18:13:57 -0400
>
>
>> I've done measurements with netperf-wrapper:
>>
>> http://netoptimizer.blogspot.dk/2014/09/mini-tutorial-for-netperf-wrapper-setup.html
>>
>> I have already previously posted my measurements here:
>> http://people.netfilter.org/hawk/qdisc/
>> http://people.netfilter.org/hawk/qdisc/measure01/
>> http://people.netfilter.org/hawk/qdisc/experiment01/
>>
>
> Theres a lot of data there to digest; all good looking.
> I will try to pay attention to detail and get back to you.
> What you have on those urls is fit for a paper, but what someone
> like me (with ADD) needs is a summary somewhere maybe in the commit
> logs.
>
>> Please, see my previous mail where I described each graph.
>>
>
> Is this patch 0?
> I think a simple statement in the commit log that no cats
> were harmed ^W^W^W performance was affected. A paragraph
> at most but if you want to do more, DaveM actually has no
> problems if you write the details of a novel in patch 0.
>
+1
A few test results in patch 0 are good. I like to have results for
with and without patch. These should two things: 1) Any regressions
caused by the patch 2) Performance gains (in that order of importance
:-) ). There doesn't need to be a lot here, just something reasonably
representative, simple, and should be easily reproducible. My
expectation in bulk dequeue is that we should see no obvious
regression and hopefully an improvement in CPU utilization-- are you
able to verify this?
> cheers,
> jamal
^ permalink raw reply
* Re: [PATCH v1 3/4] net: fec: ptp: Enalbe PPS ouput based on ptp clock
From: Richard Cochran @ 2014-09-25 14:41 UTC (permalink / raw)
To: Luwei Zhou
Cc: davem, netdev, shawn.guo, bhutchings, R49496, b38611, b20596,
stephen
In-Reply-To: <1411632621-17429-4-git-send-email-b45643@freescale.com>
On Thu, Sep 25, 2014 at 04:10:20PM +0800, Luwei Zhou wrote:
> FEC ptp timer has 4 channel compare/trigger function. It can be used to enable pps output.
> The pulse would be ouput high exactly on N second. The pulse ouput high on compare event mode
> is used to produce pulse per second. The pulse width would be one cycle based on ptp timer clock
> source.Since 31-bit ptp hardware timer is used, the timer will wrap more than 2 seconds. We need to
> reload the compare compare event about every 1 second.
>
> Signed-off-by: Luwei Zhou <b45643@freescale.com>
> ---
> drivers/net/ethernet/freescale/fec.h | 7 +
> drivers/net/ethernet/freescale/fec_main.c | 2 +
> drivers/net/ethernet/freescale/fec_ptp.c | 223 +++++++++++++++++++++++++++++-
> 3 files changed, 231 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
> index 26fb1de..f8e23e6 100644
> --- a/drivers/net/ethernet/freescale/fec.h
> +++ b/drivers/net/ethernet/freescale/fec.h
> @@ -481,12 +481,19 @@ struct fec_enet_private {
> unsigned int tx_pkts_itr;
> unsigned int tx_time_itr;
> unsigned int itr_clk_rate;
> +
> + /* pps */
> + int pps_channel;
> + unsigned int reload_period;
> + int pps_enable;
> + unsigned int next_counter;
> };
>
> void fec_ptp_init(struct platform_device *pdev);
> void fec_ptp_start_cyclecounter(struct net_device *ndev);
> int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);
> int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr);
> +uint fec_ptp_check_pps_event(struct fec_enet_private *fep);
>
> /****************************************************************************/
> #endif /* FEC_H */
> diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
> index 3a4ec0f..5a4ce36 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -1558,6 +1558,8 @@ fec_enet_interrupt(int irq, void *dev_id)
> complete(&fep->mdio_done);
> }
>
> + fec_ptp_check_pps_event(fep);
> +
> return ret;
> }
>
> diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
> index e2bf786..c55239d 100644
> --- a/drivers/net/ethernet/freescale/fec_ptp.c
> +++ b/drivers/net/ethernet/freescale/fec_ptp.c
> @@ -61,6 +61,24 @@
> #define FEC_T_INC_CORR_MASK 0x00007f00
> #define FEC_T_INC_CORR_OFFSET 8
>
> +#define FEC_T_CTRL_PINPER 0x00000080
> +#define FEC_T_TF0_MASK 0x00000001
> +#define FEC_T_TF0_OFFSET 0
> +#define FEC_T_TF1_MASK 0x00000002
> +#define FEC_T_TF1_OFFSET 1
> +#define FEC_T_TF2_MASK 0x00000004
> +#define FEC_T_TF2_OFFSET 2
> +#define FEC_T_TF3_MASK 0x00000008
> +#define FEC_T_TF3_OFFSET 3
> +#define FEC_T_TDRE_MASK 0x00000001
> +#define FEC_T_TDRE_OFFSET 0
> +#define FEC_T_TMODE_MASK 0x0000003C
> +#define FEC_T_TMODE_OFFSET 2
> +#define FEC_T_TIE_MASK 0x00000040
> +#define FEC_T_TIE_OFFSET 6
> +#define FEC_T_TF_MASK 0x00000080
> +#define FEC_T_TF_OFFSET 7
> +
> #define FEC_ATIME_CTRL 0x400
> #define FEC_ATIME 0x404
> #define FEC_ATIME_EVT_OFFSET 0x408
> @@ -69,9 +87,162 @@
> #define FEC_ATIME_INC 0x414
> #define FEC_TS_TIMESTAMP 0x418
>
> +#define FEC_TGSR 0x604
> +#define FEC_TCSR(n) (0x608 + n * 0x08)
> +#define FEC_TCCR(n) (0x60C + n * 0x08)
> +#define MAX_TIMER_CHANNEL 3
> +#define FEC_TMODE_TOGGLE 0x05
> +#define FEC_HIGH_PULSE 0x0F
> +
> #define FEC_CC_MULT (1 << 31)
> #define FEC_COUNTER_PERIOD (1 << 31)
> #define FEC_T_PERIOD_ONE_SEC (1000000000UL)
> +#define PPS_OUPUT_RELOAD_PERIOD FEC_T_PERIOD_ONE_SEC
> +
> +/**
> + * fec_ptp_enable_pps
> + * @fep: the fec_enet_private structure handle
> + * @enable: enable the channel pps output
> + *
> + * This function enble the PPS ouput on the timer channel.
> + */
> +static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
> +{
> + unsigned long flags;
> + u32 val, tempval;
> + int inc;
> + struct timespec ts;
> + u64 ns;
> + u32 remainder;
> + val = 0;
> +
> + if (fep->pps_channel == -1 || fep->pps_channel > MAX_TIMER_CHANNEL) {
> + dev_err(&fep->pdev->dev, "Invalid pps channel\n");
> + return -EINVAL;
> + }
> +
> + if (!(fep->hwts_tx_en || fep->hwts_rx_en)) {
> + dev_err(&fep->pdev->dev, "No ptp stack is running\n");
> + return -EINVAL;
> + }
> +
> + if (fep->pps_enable == enable)
> + return 0;
> +
> + fep->reload_period = PPS_OUPUT_RELOAD_PERIOD;
> + inc = FEC_T_PERIOD_ONE_SEC / clk_get_rate(fep->clk_ptp);
> +
> + spin_lock_irqsave(&fep->tmreg_lock, flags);
> +
> + if (enable) {
> + /*
> + * clear capture or output compare interrupt status if have.
> + */
> + writel(FEC_T_TF_MASK, fep->hwp + FEC_TCSR(fep->pps_channel));
> +
> + /*
> + * It is recommended to doulbe check the TMODE field in the
> + * TCSR register to be cleared before the first compare counter
> + * is written into TCCR register. Just add a double check.
> + */
> + val = readl(fep->hwp + FEC_TCSR(fep->pps_channel));
> + do {
> + val &= ~(FEC_T_TMODE_MASK);
> + writel(val, fep->hwp + FEC_TCSR(fep->pps_channel));
> + val = readl(fep->hwp + FEC_TCSR(fep->pps_channel));
> + } while (val & FEC_T_TMODE_MASK);
> +
> + /*
> + * Dummy read counter to update the counter
> + */
> + timecounter_read(&fep->tc);
> + /*
> + * linux ptp is running. We want to find the first compare event
^^^^^^^^^^^^^^^^^^^^
What does this mean?
> + * in the next second point. So we need to know what the ptp time
> + * is now and how many nanoseconds is ahead to get next second.
> + * The remaining nanosecond ahead before the next second would be
> + * FEC_T_PERIOD_ONE_SEC - ts.tv_nsec. Add the remaining nanoseconds
> + * to current timer would be next second.
> + */
> + tempval = readl(fep->hwp + FEC_ATIME_CTRL);
> + tempval |= FEC_T_CTRL_CAPTURE;
> + writel(tempval, fep->hwp + FEC_ATIME_CTRL);
> +
> + tempval = readl(fep->hwp + FEC_ATIME);
> + /*
> + * Converse the ptp local counter to 1588 timestamp
^^^^^^^^
Convert?
> + */
> + ns = timecounter_cyc2time(&fep->tc, tempval);
> + ts.tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder);
> + ts.tv_nsec = remainder;
> +
> + /*
> + * The tempval is less than 3 seconds, and so val is less than
> + * 4 seconds. No overflow for 32bit calculation.
> + */
> + val = FEC_T_PERIOD_ONE_SEC - (u32)ts.tv_nsec + tempval;
> +
> + /* Need to consider the situation that the current time is
> + * very close to the second point, which means FEC_T_PERIOD_ONE_SEC
> + * - ts.tv_nsec is close to be zero(For example 20ns); Since the timer
> + * is still running when we calculate the first compare event, it is
> + * possible that the remaining nanoseonds run out before the compare
> + * counter is calculated and written into TCCR register. To avoid
> + * this possibility, we will set the compare event to be the next
> + * of next second. The current setting is 31-bit timer and wrap
> + * around over 2 seconds. So it is okay to set the next of next
> + * seond for the timer.
> + */
> + val += FEC_T_PERIOD_ONE_SEC;
> +
> + /*
> + * We add (2 *FEC_T_PERIOD_ONE_SEC - (u32)ts.tv_nsec) to current
> + * ptp counter, which maybe cause 32-bit wrap. Since the
> + * (FEC_T_PERIOD_ONE_SEC - (u32)ts.tv_nsec) is less than 2 second.
> + * We can ensure the wrap will not cause issue. If the offset
> + * is bigger than fep->cc.mask would be a error.
> + */
> + val &= fep->cc.mask;
> + writel(val, fep->hwp + FEC_TCCR(fep->pps_channel));
> +
> + /*
> + * Calculate the second the compare event timestamp.
> + */
> + fep->next_counter = (val + fep->reload_period) & fep->cc.mask;
> +
> + /*
> + * Enable compare event when overflow
> + */
> + val = readl(fep->hwp + FEC_ATIME_CTRL);
> + val |= FEC_T_CTRL_PINPER;
> + writel(val, fep->hwp + FEC_ATIME_CTRL);
> +
> + /*
> + * Compare channel setting.
> + */
> + val = readl(fep->hwp + FEC_TCSR(fep->pps_channel));
> + val |= (1 << FEC_T_TF_OFFSET | 1 << FEC_T_TIE_OFFSET);
> + val &= ~(1 << FEC_T_TDRE_OFFSET);
> + val &= ~(FEC_T_TMODE_MASK);
> + val |= (FEC_HIGH_PULSE << FEC_T_TMODE_OFFSET);
> + writel(val, fep->hwp + FEC_TCSR(fep->pps_channel));
> +
> + /*
> + * Write the second compare event timestamp and calculate
> + * the third timestamp. Refer the TCCR register detail in the spec.
> + */
> + writel(fep->next_counter, fep->hwp + FEC_TCCR(fep->pps_channel));
> + fep->next_counter = (fep->next_counter + fep->reload_period) & fep->cc.mask;
> + } else {
> + writel(0, fep->hwp + FEC_TCSR(fep->pps_channel));
> + }
> +
> + fep->pps_enable = enable;
> + spin_unlock_irqrestore(&fep->tmreg_lock, flags);
> +
> + return 0;
> +}
> +
> /**
> * fec_ptp_read - read raw cycle counter (to be used by time counter)
> * @cc: the cyclecounter structure
> @@ -322,6 +493,15 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp,
> static int fec_ptp_enable(struct ptp_clock_info *ptp,
> struct ptp_clock_request *rq, int on)
> {
> + struct fec_enet_private *fep =
> + container_of(ptp, struct fec_enet_private, ptp_caps);
> + int ret = 0;
> +
> + if (rq->type == PTP_CLK_REQ_PPS) {
> + ret = fec_ptp_enable_pps(fep, on);
> +
> + return ret;
> + }
> return -EOPNOTSUPP;
> }
>
> @@ -427,6 +607,8 @@ void fec_ptp_init(struct platform_device *pdev)
> {
> struct net_device *ndev = platform_get_drvdata(pdev);
> struct fec_enet_private *fep = netdev_priv(ndev);
> + struct device_node *np = pdev->dev.of_node;
> + int err;
>
> fep->ptp_caps.owner = THIS_MODULE;
> snprintf(fep->ptp_caps.name, 16, "fec ptp");
> @@ -436,7 +618,7 @@ void fec_ptp_init(struct platform_device *pdev)
> fep->ptp_caps.n_ext_ts = 0;
> fep->ptp_caps.n_per_out = 0;
> fep->ptp_caps.n_pins = 0;
> - fep->ptp_caps.pps = 0;
> + fep->ptp_caps.pps = 1;
> fep->ptp_caps.adjfreq = fec_ptp_adjfreq;
> fep->ptp_caps.adjtime = fec_ptp_adjtime;
> fep->ptp_caps.gettime = fec_ptp_gettime;
> @@ -444,6 +626,10 @@ void fec_ptp_init(struct platform_device *pdev)
> fep->ptp_caps.enable = fec_ptp_enable;
>
> fep->cycle_speed = clk_get_rate(fep->clk_ptp);
> + err = of_property_read_u32(np, "pps-channel",
> + &fep->pps_channel);
Please do not make another DT property for this.
Instead, use the PTP_PIN_SET/GETFUNC interface. You can add a new
enumeration value to ptp_pin_function, like PTP_PF_PPS.
Thanks,
Richard
> + if (err)
> + fep->pps_channel = -1;
>
> spin_lock_init(&fep->tmreg_lock);
>
> @@ -459,3 +645,38 @@ void fec_ptp_init(struct platform_device *pdev)
>
> schedule_delayed_work(&fep->time_keep, HZ);
> }
> +
> +/**
> + * fec_ptp_check_pps_event
> + * @fep: the fec_enet_private structure handle
> + *
> + * This function check the pps event and reload the timer compare counter.
> + */
> +uint fec_ptp_check_pps_event(struct fec_enet_private *fep)
> +{
> + u32 val;
> + u8 channel = fep->pps_channel;
> + struct ptp_clock_event event;
> +
> + val = readl(fep->hwp + FEC_TCSR(channel));
> + if (val & FEC_T_TF_MASK) {
> + /*
> + * Write the next next compare(not the next according the spec) value to the register
> + */
> + writel(fep->next_counter, fep->hwp + FEC_TCCR(channel));
> + do {
> + writel(val, fep->hwp + FEC_TCSR(channel));
> + } while (readl(fep->hwp + FEC_TCSR(channel)) & FEC_T_TF_MASK);
> +
> + /*
> + * Update the counter;
> + */
> + fep->next_counter = (fep->next_counter + fep->reload_period) & fep->cc.mask;
> +
> + event.type = PTP_CLOCK_PPS;
> + ptp_clock_event(fep->ptp_clock, &event);
> + return 1;
> + }
> +
> + return 0;
> +}
> --
> 1.9.1
>
^ permalink raw reply
* Re: [PATCH net-next] mlx4: exploit skb->xmit_more to conditionally send doorbell
From: Jesper Dangaard Brouer @ 2014-09-25 14:43 UTC (permalink / raw)
To: Eric Dumazet; +Cc: brouer, David Miller, netdev, Amir Vadai, John Fastabend
In-Reply-To: <1411654669.16953.17.camel@edumazet-glaptop2.roam.corp.google.com>
On Thu, 25 Sep 2014 07:17:49 -0700
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Tested with a modified pktgen version, I got a 40% increase of
> throughput.
Pktgen is artificial benchmarking, you know ;-) :-P
If you really must use pktgen for this, you can use an unmodified
pktgen against the qdisc layer by adding a VLAN interface on-top of the
device you want to test. I blame John, for telling me this ;-)
/me running away
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Sr. Network Kernel Developer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [PATCH v1 4/4] ARM: Documentation: Update fec dts binding doc
From: Richard Cochran @ 2014-09-25 14:43 UTC (permalink / raw)
To: Luwei Zhou
Cc: davem, netdev, shawn.guo, bhutchings, R49496, b38611, b20596,
stephen
In-Reply-To: <1411632621-17429-5-git-send-email-b45643@freescale.com>
On Thu, Sep 25, 2014 at 04:10:21PM +0800, Luwei Zhou wrote:
> This patch update fec devicetree binding doc that add Optional properties
> "pps-channel".
Again, use the PTP pin interface. We don't need a random new FEC DT
property for this.
Thanks,
Richard
^ permalink raw reply
* Re: [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Jesper Dangaard Brouer @ 2014-09-25 14:57 UTC (permalink / raw)
To: Tom Herbert
Cc: Jamal Hadi Salim, Eric Dumazet, Linux Netdev List,
David S. Miller, Alexander Duyck,
Toke Høiland-Jørgensen, Florian Westphal, Dave Taht,
John Fastabend, Daniel Borkmann, Hannes Frederic Sowa, brouer
In-Reply-To: <CA+mtBx8Nie9AiCG6iuY+EN7HiLAe-bxWpZxTpRhASmYabRUyFA@mail.gmail.com>
On Thu, 25 Sep 2014 07:40:33 -0700
Tom Herbert <therbert@google.com> wrote:
> A few test results in patch 0 are good. I like to have results for
> with and without patch. These should two things: 1) Any regressions
> caused by the patch 2) Performance gains (in that order of importance
> :-) ). There doesn't need to be a lot here, just something reasonably
> representative, simple, and should be easily reproducible. My
> expectation in bulk dequeue is that we should see no obvious
> regression and hopefully an improvement in CPU utilization-- are you
> able to verify this?
We are saving 3% CPU, as I described in my post with subject:
"qdisc/UDP_STREAM: measuring effect of qdisc bulk dequeue":
http://thread.gmane.org/gmane.linux.network/331152/focus=331154
Using UDP_STREAM on 1Gbit/s driver igb, I can show that the
_raw_spin_lock calls are reduced with approx 3%, when enabling
bulking of just 2 packets.
This test can only demonstrates a CPU usage reduction, as the
throughput is already at maximum link (bandwidth) capacity.
Notice netperf option "-m 1472" which makes sure we are not sending
UDP IP-fragments::
netperf -H 192.168.111.2 -t UDP_STREAM -l 120 -- -m 1472
Results from perf diff::
# Command: perf diff
# Event 'cycles'
# Baseline Delta Symbol
# no-bulk bulk(1)
# ........ ....... .........................................
#
7.05% -3.03% [k] _raw_spin_lock
6.34% +0.23% [k] copy_user_enhanced_fast_string
6.30% +0.26% [k] fib_table_lookup
3.03% +0.01% [k] __slab_free
3.00% +0.08% [k] intel_idle
2.49% +0.05% [k] sock_alloc_send_pskb
2.31% +0.30% netperf [.] send_omni_inner
2.12% +0.12% netperf [.] send_data
2.11% +0.10% [k] udp_sendmsg
1.96% +0.02% [k] __ip_append_data
1.48% -0.01% [k] __alloc_skb
1.46% +0.07% [k] __mkroute_output
1.34% +0.05% [k] __ip_select_ident
1.29% +0.03% [k] check_leaf
1.27% +0.09% [k] __skb_get_hash
A nitpick is that, this testing were done on V2 of the patchset.
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Sr. Network Kernel Developer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Tom Herbert @ 2014-09-25 15:05 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: Jamal Hadi Salim, Eric Dumazet, Linux Netdev List,
David S. Miller, Alexander Duyck,
Toke Høiland-Jørgensen, Florian Westphal, Dave Taht,
John Fastabend, Daniel Borkmann, Hannes Frederic Sowa
In-Reply-To: <20140925165738.646d0783@redhat.com>
On Thu, Sep 25, 2014 at 7:57 AM, Jesper Dangaard Brouer
<brouer@redhat.com> wrote:
> On Thu, 25 Sep 2014 07:40:33 -0700
> Tom Herbert <therbert@google.com> wrote:
>
>> A few test results in patch 0 are good. I like to have results for
>> with and without patch. These should two things: 1) Any regressions
>> caused by the patch 2) Performance gains (in that order of importance
>> :-) ). There doesn't need to be a lot here, just something reasonably
>> representative, simple, and should be easily reproducible. My
>> expectation in bulk dequeue is that we should see no obvious
>> regression and hopefully an improvement in CPU utilization-- are you
>> able to verify this?
>
> We are saving 3% CPU, as I described in my post with subject:
> "qdisc/UDP_STREAM: measuring effect of qdisc bulk dequeue":
> http://thread.gmane.org/gmane.linux.network/331152/focus=331154
>
> Using UDP_STREAM on 1Gbit/s driver igb, I can show that the
> _raw_spin_lock calls are reduced with approx 3%, when enabling
> bulking of just 2 packets.
>
That's great. In commit log, would be good to have results with
TCP_STREAM also and please report aggregate CPU utilization changes
(like from mpstat).
Thanks,
Tom
> This test can only demonstrates a CPU usage reduction, as the
> throughput is already at maximum link (bandwidth) capacity.
>
> Notice netperf option "-m 1472" which makes sure we are not sending
> UDP IP-fragments::
>
> netperf -H 192.168.111.2 -t UDP_STREAM -l 120 -- -m 1472
>
> Results from perf diff::
>
> # Command: perf diff
> # Event 'cycles'
> # Baseline Delta Symbol
> # no-bulk bulk(1)
> # ........ ....... .........................................
> #
> 7.05% -3.03% [k] _raw_spin_lock
> 6.34% +0.23% [k] copy_user_enhanced_fast_string
> 6.30% +0.26% [k] fib_table_lookup
> 3.03% +0.01% [k] __slab_free
> 3.00% +0.08% [k] intel_idle
> 2.49% +0.05% [k] sock_alloc_send_pskb
> 2.31% +0.30% netperf [.] send_omni_inner
> 2.12% +0.12% netperf [.] send_data
> 2.11% +0.10% [k] udp_sendmsg
> 1.96% +0.02% [k] __ip_append_data
> 1.48% -0.01% [k] __alloc_skb
> 1.46% +0.07% [k] __mkroute_output
> 1.34% +0.05% [k] __ip_select_ident
> 1.29% +0.03% [k] check_leaf
> 1.27% +0.09% [k] __skb_get_hash
>
> A nitpick is that, this testing were done on V2 of the patchset.
>
> --
> Best regards,
> Jesper Dangaard Brouer
> MSc.CS, Sr. Network Kernel Developer at Red Hat
> Author of http://www.iptv-analyzer.org
> LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [PATCH net-next] mlx4: exploit skb->xmit_more to conditionally send doorbell
From: Eric Dumazet @ 2014-09-25 15:06 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: David Miller, netdev, Amir Vadai, John Fastabend
In-Reply-To: <20140925164333.7cba128a@redhat.com>
On Thu, 2014-09-25 at 16:43 +0200, Jesper Dangaard Brouer wrote:
> On Thu, 25 Sep 2014 07:17:49 -0700
> Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> > From: Eric Dumazet <edumazet@google.com>
> >
> > Tested with a modified pktgen version, I got a 40% increase of
> > throughput.
>
> Pktgen is artificial benchmarking, you know ;-) :-P
>
> If you really must use pktgen for this, you can use an unmodified
> pktgen against the qdisc layer by adding a VLAN interface on-top of the
> device you want to test. I blame John, for telling me this ;-)
>
> /me running away
But... Nothing yet in qdisc layer sets xmit_more, unless TSO is
disabled, and a GSO packet is segmented.
So you might notice some improvement with this patch, but not if you use
TSO, and a 40GB NIC is better with TSO on you know ;)
^ permalink raw reply
* Re: [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Eric Dumazet @ 2014-09-25 15:12 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: Tom Herbert, Jamal Hadi Salim, Linux Netdev List, David S. Miller,
Alexander Duyck, Toke Høiland-Jørgensen,
Florian Westphal, Dave Taht, John Fastabend, Daniel Borkmann,
Hannes Frederic Sowa
In-Reply-To: <20140925165738.646d0783@redhat.com>
On Thu, 2014-09-25 at 16:57 +0200, Jesper Dangaard Brouer wrote:
> We are saving 3% CPU, as I described in my post with subject:
> "qdisc/UDP_STREAM: measuring effect of qdisc bulk dequeue":
> http://thread.gmane.org/gmane.linux.network/331152/focus=331154
>
> Using UDP_STREAM on 1Gbit/s driver igb, I can show that the
> _raw_spin_lock calls are reduced with approx 3%, when enabling
> bulking of just 2 packets.
>
> This test can only demonstrates a CPU usage reduction, as the
> throughput is already at maximum link (bandwidth) capacity.
>
> Notice netperf option "-m 1472" which makes sure we are not sending
> UDP IP-fragments::
>
> netperf -H 192.168.111.2 -t UDP_STREAM -l 120 -- -m 1472
>
> Results from perf diff::
>
> # Command: perf diff
> # Event 'cycles'
> # Baseline Delta Symbol
> # no-bulk bulk(1)
> # ........ ....... .........................................
> #
> 7.05% -3.03% [k] _raw_spin_lock
> 6.34% +0.23% [k] copy_user_enhanced_fast_string
> 6.30% +0.26% [k] fib_table_lookup
> 3.03% +0.01% [k] __slab_free
> 3.00% +0.08% [k] intel_idle
> 2.49% +0.05% [k] sock_alloc_send_pskb
> 2.31% +0.30% netperf [.] send_omni_inner
> 2.12% +0.12% netperf [.] send_data
> 2.11% +0.10% [k] udp_sendmsg
> 1.96% +0.02% [k] __ip_append_data
> 1.48% -0.01% [k] __alloc_skb
> 1.46% +0.07% [k] __mkroute_output
> 1.34% +0.05% [k] __ip_select_ident
> 1.29% +0.03% [k] check_leaf
> 1.27% +0.09% [k] __skb_get_hash
>
> A nitpick is that, this testing were done on V2 of the patchset.
>
You could avoid the fib_table_lookup() cost by using netperf -- -N -n
(connected UDP sockets)
And of course reduce message sizes to increase pps
^ permalink raw reply
* Re: [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Jesper Dangaard Brouer @ 2014-09-25 15:23 UTC (permalink / raw)
To: Tom Herbert
Cc: Jamal Hadi Salim, Eric Dumazet, Linux Netdev List,
David S. Miller, Alexander Duyck,
Toke Høiland-Jørgensen, Florian Westphal, Dave Taht,
John Fastabend, Daniel Borkmann, Hannes Frederic Sowa, brouer
In-Reply-To: <CA+mtBx9ZW0qYh+_BEEVTgZ79Xbq0bH1Agfss_7kdEus_syeMhA@mail.gmail.com>
On Thu, 25 Sep 2014 08:05:38 -0700
Tom Herbert <therbert@google.com> wrote:
> On Thu, Sep 25, 2014 at 7:57 AM, Jesper Dangaard Brouer
> <brouer@redhat.com> wrote:
> > On Thu, 25 Sep 2014 07:40:33 -0700
> > Tom Herbert <therbert@google.com> wrote:
> >
> >> A few test results in patch 0 are good. I like to have results for
> >> with and without patch. These should two things: 1) Any regressions
> >> caused by the patch 2) Performance gains (in that order of importance
> >> :-) ). There doesn't need to be a lot here, just something reasonably
> >> representative, simple, and should be easily reproducible. My
> >> expectation in bulk dequeue is that we should see no obvious
> >> regression and hopefully an improvement in CPU utilization-- are you
> >> able to verify this?
> >
> > We are saving 3% CPU, as I described in my post with subject:
> > "qdisc/UDP_STREAM: measuring effect of qdisc bulk dequeue":
> > http://thread.gmane.org/gmane.linux.network/331152/focus=331154
> >
> > Using UDP_STREAM on 1Gbit/s driver igb, I can show that the
> > _raw_spin_lock calls are reduced with approx 3%, when enabling
> > bulking of just 2 packets.
> >
>
> That's great. In commit log, would be good to have results with
> TCP_STREAM also and please report aggregate CPU utilization changes
> (like from mpstat).
The TCP_STREAM is not a good test for this, because unless disabling
both TSO and GSO the packets will not hit the code path (that this
patch changes). When we later add support for TSO and GSO bulking,
then it will make sense to include TCP_STREAM testing, not before.
I will redo the tests, once I get home to my testlab, as the remote lab
I'm using now is annoyingly slow rebooting machines, as we not longer
have a runtime option for enable/disable (I'm currently in Switzerland).
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Sr. Network Kernel Developer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [PATCH] neigh: check error pointer instead of NULL for ipv4_neigh_lookup()
From: Alexei Starovoitov @ 2014-09-25 15:35 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev@vger.kernel.org, David S. Miller
In-Reply-To: <1411603673-19084-1-git-send-email-xiyou.wangcong@gmail.com>
On Wed, Sep 24, 2014 at 5:07 PM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> Fixes: commit f187bc6efb7250afee0e2009b6106 ("ipv4: No need to set generic neighbour pointer")
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
> ---
> net/ipv4/route.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 173e7ea..cbadb94 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -746,7 +746,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow
> }
>
> n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw);
> - if (n) {
> + if (!IS_ERR(n)) {
> if (!(n->nud_state & NUD_VALID)) {
> neigh_event_send(n, NULL);
assuming symptoms of this was a crash?
Could you share the stack trace to see how we got to this state ?
Or was it spotted just by code inspection?
Thanks!
^ permalink raw reply
* Re: [PATCH net-next] mlx4: exploit skb->xmit_more to conditionally send doorbell
From: Eric Dumazet @ 2014-09-25 15:36 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: David Miller, netdev, Amir Vadai, John Fastabend
In-Reply-To: <1411657615.16953.21.camel@edumazet-glaptop2.roam.corp.google.com>
On Thu, 2014-09-25 at 08:06 -0700, Eric Dumazet wrote:
>
> But... Nothing yet in qdisc layer sets xmit_more, unless TSO is
> disabled, and a GSO packet is segmented.
>
> So you might notice some improvement with this patch, but not if you use
> TSO, and a 40GB NIC is better with TSO on you know ;)
>
So playing with TSO=off (but GSO=on), we see about 12 % increase of
throughput on a TCP_STREAM flow.
And kernel profile clearly shows the difference of sending or not the
doorbell, as mlx4_en_xmit() shifts. Note also mlx4_en_free_tx_desc()
disappears, this might point to some false sharing or something worth
investigating.
Before patch :
26.36% [kernel] [k] __copy_skb_header
16.59% [kernel] [k] mlx4_en_xmit
5.62% [kernel] [k] __alloc_skb
5.48% [kernel] [k] copy_user_enhanced_fast_string
4.48% [kernel] [k] skb_segment
2.46% [kernel] [k] mlx4_en_free_tx_desc.isra.27
2.31% [kernel] [k] _raw_spin_lock
2.10% [kernel] [k] memcpy
2.01% [kernel] [k] tcp_sendmsg
1.62% [kernel] [k] __iowrite64_copy
After patch :
32.78% [kernel] [k] __copy_skb_header
8.26% [kernel] [k] mlx4_en_xmit
7.25% [kernel] [k] __alloc_skb
7.18% [kernel] [k] copy_user_enhanced_fast_string
4.39% [kernel] [k] skb_segment
2.87% [kernel] [k] memcpy
2.59% [kernel] [k] tcp_sendmsg
2.50% [kernel] [k] _raw_spin_lock
2.38% [kernel] [k] dev_hard_start_xmit
1.52% [kernel] [k] tcp_gso_segment
1.50% [kernel] [k] kmem_cache_alloc_node_trace
1.40% [kernel] [k] kmem_cache_alloc_node
1.16% [kernel] [k] ip_send_check
^ permalink raw reply
* Re: [PATCH net-next] mlx4: exploit skb->xmit_more to conditionally send doorbell
From: Eric Dumazet @ 2014-09-25 15:40 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: David Miller, netdev, Amir Vadai, John Fastabend
In-Reply-To: <1411659380.16953.29.camel@edumazet-glaptop2.roam.corp.google.com>
On Thu, 2014-09-25 at 08:36 -0700, Eric Dumazet wrote:
> So playing with TSO=off (but GSO=on), we see about 12 % increase of
> throughput on a TCP_STREAM flow.
Correction, this was a 20 % increase.
( 849284 pps -> 1023469 pps)
^ permalink raw reply
* Re: [PATCH v2 net-next 3/3] tcp: better TCP_SKB_CB layout to reduce cache line misses
From: Christoph Paasch @ 2014-09-25 15:48 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David S. Miller, netdev, Yuchung Cheng, Neal Cardwell
In-Reply-To: <1411468452-3729-4-git-send-email-edumazet@google.com>
On 23/09/14 - 03:34:12, Eric Dumazet wrote:
> TCP maintains lists of skb in write queue, and in receive queues
> (in order and out of order queues)
>
> Scanning these lists both in input and output path usually requires
> access to skb->next, TCP_SKB_CB(skb)->seq, and TCP_SKB_CB(skb)->end_seq
>
> These fields are currently in two different cache lines, meaning we
> waste lot of memory bandwidth when these queues are big and flows
> have either packet drops or packet reorders.
>
> We can move TCP_SKB_CB(skb)->header at the end of TCP_SKB_CB, because
> this header is not used in fast path. This allows TCP to search much faster
> in the skb lists.
>
> Even with regular flows, we save one cache line miss in fast path.
>
> Thanks to Christoph Paasch for noticing we need to cleanup
> skb->cb[] (IPCB/IP6CB) before entering IP stack in tx path.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> include/net/tcp.h | 12 ++++++------
> net/ipv4/tcp_ipv4.c | 7 +++++++
> net/ipv4/tcp_output.c | 5 +++++
> net/ipv6/tcp_ipv6.c | 7 +++++++
> 4 files changed, 25 insertions(+), 6 deletions(-)
Hello Eric,
I think that in tcp_v4_hnd_req() and tcp_v4_save_options() we also need to
avoid calling IPCB() and do TCP_SKB_CB(skb)->header.h4.opt instead.
Cheers,
Christoph
^ permalink raw reply
* Re: [PATCH net-next] mlx4: exploit skb->xmit_more to conditionally send doorbell
From: Alexei Starovoitov @ 2014-09-25 15:53 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev, Amir Vadai
In-Reply-To: <1411654669.16953.17.camel@edumazet-glaptop2.roam.corp.google.com>
On Thu, Sep 25, 2014 at 7:17 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> skb->xmit_more tells us if another skb is coming next.
>
> We need to send doorbell when : xmit_more is not set,
> or txqueue is stopped (preventing next skb to come immediately)
>
> Tested with a modified pktgen version, I got a 40% increase of
> throughput.
this is awesome!
I've been hacking pktgen as well based on Jesper's earlier patch,
but in slightly different way. Sounds like you already have working
pktgen with xmit_more. Do you mind sharing it? even rough patch
would be great.
Thanks
^ permalink raw reply
* Re: [net-next PATCH 1/1 V4] qdisc: bulk dequeue support for qdiscs with TCQ_F_ONETXQUEUE
From: Tom Herbert @ 2014-09-25 15:58 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: Jamal Hadi Salim, Eric Dumazet, Linux Netdev List,
David S. Miller, Alexander Duyck,
Toke Høiland-Jørgensen, Florian Westphal, Dave Taht,
John Fastabend, Daniel Borkmann, Hannes Frederic Sowa
In-Reply-To: <20140925172329.7460f787@redhat.com>
On Thu, Sep 25, 2014 at 8:23 AM, Jesper Dangaard Brouer
<brouer@redhat.com> wrote:
> On Thu, 25 Sep 2014 08:05:38 -0700
> Tom Herbert <therbert@google.com> wrote:
>
>> On Thu, Sep 25, 2014 at 7:57 AM, Jesper Dangaard Brouer
>> <brouer@redhat.com> wrote:
>> > On Thu, 25 Sep 2014 07:40:33 -0700
>> > Tom Herbert <therbert@google.com> wrote:
>> >
>> >> A few test results in patch 0 are good. I like to have results for
>> >> with and without patch. These should two things: 1) Any regressions
>> >> caused by the patch 2) Performance gains (in that order of importance
>> >> :-) ). There doesn't need to be a lot here, just something reasonably
>> >> representative, simple, and should be easily reproducible. My
>> >> expectation in bulk dequeue is that we should see no obvious
>> >> regression and hopefully an improvement in CPU utilization-- are you
>> >> able to verify this?
>> >
>> > We are saving 3% CPU, as I described in my post with subject:
>> > "qdisc/UDP_STREAM: measuring effect of qdisc bulk dequeue":
>> > http://thread.gmane.org/gmane.linux.network/331152/focus=331154
>> >
>> > Using UDP_STREAM on 1Gbit/s driver igb, I can show that the
>> > _raw_spin_lock calls are reduced with approx 3%, when enabling
>> > bulking of just 2 packets.
>> >
>>
>> That's great. In commit log, would be good to have results with
>> TCP_STREAM also and please report aggregate CPU utilization changes
>> (like from mpstat).
>
> The TCP_STREAM is not a good test for this, because unless disabling
> both TSO and GSO the packets will not hit the code path (that this
> patch changes). When we later add support for TSO and GSO bulking,
> then it will make sense to include TCP_STREAM testing, not before.
>
Disabling TSO and GSO is fine. I'm interested to see interactions with TCP.
> I will redo the tests, once I get home to my testlab, as the remote lab
> I'm using now is annoyingly slow rebooting machines, as we not longer
> have a runtime option for enable/disable (I'm currently in Switzerland).
>
> --
> Best regards,
> Jesper Dangaard Brouer
> MSc.CS, Sr. Network Kernel Developer at Red Hat
> Author of http://www.iptv-analyzer.org
> LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* RE: netxen: BUG: sleeping function called from invalid context at include/linux/netdevice.h:476
From: Manish Chopra @ 2014-09-25 16:01 UTC (permalink / raw)
To: Mike Galbraith, linux-kernel; +Cc: Sony Chacko, Rajesh Borundia, netdev
In-Reply-To: <1411654896.15810.52.camel@marge.simpson.net>
> -----Original Message-----
> From: Mike Galbraith [mailto:umgwanakikbuti@gmail.com]
> Sent: Thursday, September 25, 2014 7:52 PM
> To: linux-kernel
> Cc: Manish Chopra; Sony Chacko; Rajesh Borundia; netdev
> Subject: netxen: BUG: sleeping function called from invalid context at
> include/linux/netdevice.h:476
>
> Greetings,
>
> While testing some sched patches that require CONFIG_DEBUG_ATOMIC_SLEEP,
> the below fell out.
>
> /etc/init.d/network restart -> gripe
>
> [ 97.850408] BUG: sleeping function called from invalid context at
> include/linux/netdevice.h:476
> [ 97.941177] in_atomic(): 1, irqs_disabled(): 0, pid: 6458, name: ip
> [ 98.012784] Preemption disabled at:[<ffffffffa0509719>]
> __netxen_nic_down+0x79/0x1b0 [netxen_nic]
> [ 98.047283]
> [ 98.047289] CPU: 63 PID: 6458 Comm: ip Tainted: G E 3.17.0-default #7
> [ 98.047291] Hardware name: Hewlett-Packard ProLiant DL980 G7, BIOS P66
> 07/07/2010
> [ 98.047295] 00000000ffffffff ffff88003702f528 ffffffff81589dbd
> 0000000000000000
> [ 98.047301] ffff88026ee96210 ffff88003702f548 ffffffff8108e1df
> ffff88026ee96210
> [ 98.047305] 0000000000000000 ffff88003702f578 ffffffff8108e298
> ffff88026bf89c38
> [ 98.047307] Call Trace:
> [ 98.047313] [<ffffffff81589dbd>] dump_stack+0x4d/0x90
> [ 98.047331] [<ffffffff8108e1df>] ___might_sleep+0x10f/0x180
> [ 98.047343] [<ffffffff8108e298>] __might_sleep+0x48/0xd0
> [ 98.047348] [<ffffffffa0506d54>] netxen_napi_disable+0x84/0xe0
> [netxen_nic]
> [ 98.047353] [<ffffffffa05097f0>] __netxen_nic_down+0x150/0x1b0
> [netxen_nic]
> [ 98.047367] [<ffffffffa0509b0b>] netxen_nic_close+0x1b/0x20 [netxen_nic]
> [ 98.047375] [<ffffffff814aa525>] __dev_close_many+0x95/0xe0
> [ 98.047379] [<ffffffff814aa5a6>] __dev_close+0x36/0x50
> [ 98.047384] [<ffffffff814ab89c>] __dev_change_flags+0xac/0x180
> [ 98.047389] [<ffffffff814ab9a7>] dev_change_flags+0x37/0x80
> [ 98.047398] [<ffffffff814be874>] do_setlink+0x244/0x7e0
> [ 98.047403] [<ffffffff814c0310>] rtnl_newlink+0x5a0/0x7d0
> [ 98.047408] [<ffffffff814bfeba>] ? rtnl_newlink+0x14a/0x7d0
> [ 98.047421] [<ffffffff8105259c>] ? __do_page_fault+0x2ac/0x520
> [ 98.047431] [<ffffffff812a14a0>] ? apparmor_capable+0x20/0x60
> [ 98.047436] [<ffffffff814bf981>] rtnetlink_rcv_msg+0xa1/0x240
> [ 98.047446] [<ffffffff81308f86>] ? rhashtable_lookup_compare+0x46/0x70
> [ 98.047451] [<ffffffff814bf8e0>] ? __rtnl_unlock+0x20/0x20
> [ 98.047463] [<ffffffff814dc3d9>] netlink_rcv_skb+0x89/0xb0
> [ 98.047466] [<ffffffff814bfb7c>] rtnetlink_rcv+0x2c/0x40
> [ 98.047468] [<ffffffff814dbdc9>] netlink_unicast+0x119/0x180
> [ 98.047473] [<ffffffff81306a3c>] ? memcpy_fromiovec+0x6c/0x90
> [ 98.047477] [<ffffffff814dc7c0>] netlink_sendmsg+0x3c0/0x450
> [ 98.047487] [<ffffffff8149449c>] sock_sendmsg+0x9c/0xd0
> [ 98.047497] [<ffffffff810aa113>] ? __wake_up+0x53/0x70
> [ 98.047502] [<ffffffff8108e298>] ? __might_sleep+0x48/0xd0
> [ 98.047509] [<ffffffff814a204e>] ? verify_iovec+0x5e/0xf0
> [ 98.047512] [<ffffffff81494df6>] ___sys_sendmsg+0x436/0x440
> [ 98.047515] [<ffffffff8108e298>] ? __might_sleep+0x48/0xd0
> [ 98.047523] [<ffffffff81194513>] ? might_fault+0x43/0x50
> [ 98.047525] [<ffffffff81491eef>] ? copy_to_user+0x2f/0x40
> [ 98.047528] [<ffffffff814951cc>] ? ___sys_recvmsg+0x19c/0x310
> [ 98.047531] [<ffffffff8105259c>] ? __do_page_fault+0x2ac/0x520
> [ 98.047538] [<ffffffff8119e681>] ? __vma_link_rb+0x101/0x120
> [ 98.047544] [<ffffffff8119fef8>] ? do_brk+0x1c8/0x340
> [ 98.047550] [<ffffffff814924a2>] ? SyS_getsockname+0xb2/0xc0
> [ 98.047555] [<ffffffff81494fd9>] __sys_sendmsg+0x49/0x80
> [ 98.047558] [<ffffffff81495029>] SyS_sendmsg+0x19/0x20
> [ 98.047567] [<ffffffff8158f7a9>] system_call_fastpath+0x16/0x1b
>
> (gdb) list *__netxen_nic_down+0x79
> 0x8749 is in __netxen_nic_down
> (drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c:1190).
> 1185 if (!test_and_clear_bit(__NX_DEV_UP, &adapter->state))
> 1186 return;
> 1187
> 1188 smp_mb();
> 1189 spin_lock(&adapter->tx_clean_lock);
> 1190 netif_carrier_off(netdev);
> 1191 netif_tx_disable(netdev);
> 1192
> 1193 if (adapter->capabilities &
> NX_FW_CAPABILITY_LINK_NOTIFICATION)
> 1194 netxen_linkevent_request(adapter, 0);
Hello Mike,
Thanks for finding this out. Mostly I have fix for it.
I will send a patch to net for fixing it after doing some testing.
Thanks,
Manish
^ permalink raw reply
* Re: [PATCH net-next 2/3] ipv6: mld: do not overwrite uri when receiving an mldv2 query
From: David L Stevens @ 2014-09-25 16:02 UTC (permalink / raw)
To: Daniel Borkmann, davem; +Cc: hannes, netdev
In-Reply-To: <1411455828-5196-3-git-send-email-dborkman@redhat.com>
While I can see the case you're making, I think the intent of MRC is
violated by arbitrary URI.
> 5.1.3. Maximum Response Code
>
> The Maximum Response Code field specifies the maximum time allowed
> before sending a responding Report.
>...
> Small values of Maximum Response Delay allow MLDv2 routers to tune
> the "leave latency" (the time between the moment the last node on a
> link ceases to listen to a specific multicast address and the moment
> the routing protocol is notified that there are no more listeners for
> that address). Larger values, especially in the exponential range,
> allow the tuning of the burstiness of MLD traffic on a link.
If URI is larger than MRD, then a lost unsolicited report, or series,
specifically will *not* propagate changes throughout the network in less
than MRD*QRV, as intended.
It was an intentional design choice, not required or prohibited by RFC.
I'm not sure what problem you think it's causing, but if they are not
equal, I think at least the URI should be enforced to <= MRD. The querier,
IMO, should set these network-wide relevant parameters, not the individual
hosts.
Is there actually some bad effect from this?
+-DLS
^ permalink raw reply
* Re: [PATCH net-next] mlx4: exploit skb->xmit_more to conditionally send doorbell
From: Eric Dumazet @ 2014-09-25 16:05 UTC (permalink / raw)
To: Alexei Starovoitov; +Cc: David Miller, netdev, Amir Vadai
In-Reply-To: <CAADnVQJ_FfZEUbFBz4wwZM9Gfbsagfjk51VVbjWJPG7KgJjHWQ@mail.gmail.com>
On Thu, 2014-09-25 at 08:53 -0700, Alexei Starovoitov wrote:
> On Thu, Sep 25, 2014 at 7:17 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > From: Eric Dumazet <edumazet@google.com>
> >
> > skb->xmit_more tells us if another skb is coming next.
> >
> > We need to send doorbell when : xmit_more is not set,
> > or txqueue is stopped (preventing next skb to come immediately)
> >
> > Tested with a modified pktgen version, I got a 40% increase of
> > throughput.
>
> this is awesome!
>
> I've been hacking pktgen as well based on Jesper's earlier patch,
> but in slightly different way. Sounds like you already have working
> pktgen with xmit_more. Do you mind sharing it? even rough patch
> would be great.
The plan was to add a 'pburst x' parameter.
Because not only we want to avoid sending the doorbell, but we could
also not doing the spinlock for every start_xmit().
We also can enforce a global [p]rate (say 100000 packets per second),
but still allow pktgen to send burts of x packets to use (and test) this
xmit_more
Nothing ready yet ;)
^ permalink raw reply
* Re: [PATCH net-next] mlx4: exploit skb->xmit_more to conditionally send doorbell
From: Alexei Starovoitov @ 2014-09-25 16:08 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev, Amir Vadai
In-Reply-To: <1411661114.16953.33.camel@edumazet-glaptop2.roam.corp.google.com>
On Thu, Sep 25, 2014 at 9:05 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Thu, 2014-09-25 at 08:53 -0700, Alexei Starovoitov wrote:
>> On Thu, Sep 25, 2014 at 7:17 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>> > From: Eric Dumazet <edumazet@google.com>
>> >
>> > skb->xmit_more tells us if another skb is coming next.
>> >
>> > We need to send doorbell when : xmit_more is not set,
>> > or txqueue is stopped (preventing next skb to come immediately)
>> >
>> > Tested with a modified pktgen version, I got a 40% increase of
>> > throughput.
>>
>> this is awesome!
>>
>> I've been hacking pktgen as well based on Jesper's earlier patch,
>> but in slightly different way. Sounds like you already have working
>> pktgen with xmit_more. Do you mind sharing it? even rough patch
>> would be great.
>
> The plan was to add a 'pburst x' parameter.
>
> Because not only we want to avoid sending the doorbell, but we could
> also not doing the spinlock for every start_xmit().
exactly!
I also hacked
atomic_inc(&(pkt_dev->skb->users))
into
single atomic_add of N packets for bursting to amortize the cost
of both spin_lock and lock xadd
> We also can enforce a global [p]rate (say 100000 packets per second),
> but still allow pktgen to send burts of x packets to use (and test) this
> xmit_more
that would be nice. I'm not sure how yet.
> Nothing ready yet ;)
can't wait :)
^ permalink raw reply
* Re: [PATCH] neigh: check error pointer instead of NULL for ipv4_neigh_lookup()
From: Cong Wang @ 2014-09-25 16:18 UTC (permalink / raw)
To: Alexei Starovoitov; +Cc: netdev@vger.kernel.org, David S. Miller
In-Reply-To: <CAADnVQ+=yuG0+0kSj291MbbxMRvmeYN7D_2PkJsjkLWtnkt4WQ@mail.gmail.com>
On Thu, Sep 25, 2014 at 8:35 AM, Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
> assuming symptoms of this was a crash?
No.
> Or was it spotted just by code inspection?
Yes.
^ permalink raw reply
* Re: [PATCH net-next] mlx4: exploit skb->xmit_more to conditionally send doorbell
From: Eric Dumazet @ 2014-09-25 16:19 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: David Miller, netdev, Amir Vadai, John Fastabend
In-Reply-To: <1411659380.16953.29.camel@edumazet-glaptop2.roam.corp.google.com>
On Thu, 2014-09-25 at 08:36 -0700, Eric Dumazet wrote:
> 26.36% [kernel] [k] __copy_skb_header
Note to myself :
Time to optimize this thing, doing a memset() to copy a bunch of
consecutive fields.
^ permalink raw reply
* Re: [PATCH v4 2/3] net: Add Keystone NetCP ethernet driver
From: Santosh Shilimkar @ 2014-09-25 17:06 UTC (permalink / raw)
To: Joe Perches
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Nair, Sandeep
In-Reply-To: <1411655363.4026.13.camel@joe-AO725>
On Thursday 25 September 2014 10:29 AM, Joe Perches wrote:
> On Thu, 2014-09-25 at 10:03 -0400, Santosh Shilimkar wrote:
>> From: Sandeep Nair <sandeep_n-l0cyMroinI0@public.gmane.org>
>>
>> The network coprocessor (NetCP) is a hardware accelerator that processes
>> Ethernet packets. NetCP has a gigabit Ethernet (GbE) subsystem with a ethernet
>> switch sub-module to send and receive packets. NetCP also includes a packet
>> accelerator (PA) module to perform packet classification operations such as
>> header matching, and packet modification operations such as checksum
>> generation. NetCP can also optionally include a Security Accelerator(SA)
>> capable of performing IPSec operations on ingress/egress packets.
>
> Some checkpatch trivia you might consider:
Sure. I fold that in. Thanks !!
regards,
Santosh
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox