* [PATCH v2 06/11] net: calxedaxgmac: fix race with tx queue stop/wake
From: Rob Herring @ 2013-08-30 3:13 UTC (permalink / raw)
To: netdev; +Cc: Lennert Buytenhek, bhutchings, Rob Herring
In-Reply-To: <1377832428-18117-1-git-send-email-robherring2@gmail.com>
From: Rob Herring <rob.herring@calxeda.com>
Since the xgmac transmit start and completion work locklessly, it is
possible for xgmac_xmit to stop the tx queue after the xgmac_tx_complete
has run resulting in the tx queue never being woken up. Fix this by
ensuring that ring buffer index updates are visible and recheck the ring
space after stopping the queue.
The implementation used here was copied from
drivers/net/ethernet/broadcom/tg3.c.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
v2:
- drop netif_tx_lock
- use netif_start_queue instead of netif_wake_queue
drivers/net/ethernet/calxeda/xgmac.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index f630855..54be55b 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -410,6 +410,9 @@ struct xgmac_priv {
#define dma_ring_space(h, t, s) CIRC_SPACE(h, t, s)
#define dma_ring_cnt(h, t, s) CIRC_CNT(h, t, s)
+#define tx_dma_ring_space(p) \
+ dma_ring_space((p)->tx_head, (p)->tx_tail, DMA_TX_RING_SZ)
+
/* XGMAC Descriptor Access Helpers */
static inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz)
{
@@ -886,8 +889,10 @@ static void xgmac_tx_complete(struct xgmac_priv *priv)
priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ);
}
- if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) >
- MAX_SKB_FRAGS)
+ /* Ensure tx_tail is visible to xgmac_xmit */
+ smp_mb();
+ if (unlikely(netif_queue_stopped(priv->dev) &&
+ (tx_dma_ring_space(priv) > MAX_SKB_FRAGS)))
netif_wake_queue(priv->dev);
}
@@ -1125,10 +1130,15 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)
priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ);
- if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) <
- MAX_SKB_FRAGS)
+ /* Ensure tx_head update is visible to tx completion */
+ smp_mb();
+ if (unlikely(tx_dma_ring_space(priv) < MAX_SKB_FRAGS)) {
netif_stop_queue(dev);
-
+ /* Ensure netif_stop_queue is visible to tx completion */
+ smp_mb();
+ if (tx_dma_ring_space(priv) > MAX_SKB_FRAGS)
+ netif_start_queue(dev);
+ }
return NETDEV_TX_OK;
}
--
1.8.1.2
^ permalink raw reply related
* [PATCH v2 05/11] net: calxedaxgmac: update ring buffer tx_head after barriers
From: Rob Herring @ 2013-08-30 3:13 UTC (permalink / raw)
To: netdev; +Cc: Lennert Buytenhek, bhutchings, Rob Herring
In-Reply-To: <1377832428-18117-1-git-send-email-robherring2@gmail.com>
From: Rob Herring <rob.herring@calxeda.com>
Ensure that the descriptor writes are visible before the ring buffer head
is updated. Since writel is a barrier, we can simply update the head after
the writel.
Reported-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
v2: No change
drivers/net/ethernet/calxeda/xgmac.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 64854ad..f630855 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -1121,9 +1121,10 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)
wmb();
desc_set_tx_owner(first, desc_flags | TXDESC_FIRST_SEG);
+ writel(1, priv->base + XGMAC_DMA_TX_POLL);
+
priv->tx_head = dma_ring_incr(entry, DMA_TX_RING_SZ);
- writel(1, priv->base + XGMAC_DMA_TX_POLL);
if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) <
MAX_SKB_FRAGS)
netif_stop_queue(dev);
--
1.8.1.2
^ permalink raw reply related
* [PATCH v2 04/11] net: calxedaxgmac: fix possible skb free before tx complete
From: Rob Herring @ 2013-08-30 3:13 UTC (permalink / raw)
To: netdev; +Cc: Lennert Buytenhek, bhutchings, Rob Herring
In-Reply-To: <1377832428-18117-1-git-send-email-robherring2@gmail.com>
From: Rob Herring <rob.herring@calxeda.com>
The TX completion code may have freed an skb before the entire sg list
was transmitted. The DMA unmap calls for the fragments could also get
skipped. Now set the skb pointer on every entry in the ring, not just
the head of the sg list. We then use the FS (first segment) bit in the
descriptors to determine skb head vs. fragment.
This also fixes similar bug in xgmac_free_tx_skbufs where clean-up of
a sg list that wraps at the end of the ring buffer would not get
unmapped.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
v2: No change
drivers/net/ethernet/calxeda/xgmac.c | 55 ++++++++++++++++--------------------
1 file changed, 24 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index df7e3e2..64854ad 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -470,6 +470,11 @@ static inline int desc_get_tx_ls(struct xgmac_dma_desc *p)
return le32_to_cpu(p->flags) & TXDESC_LAST_SEG;
}
+static inline int desc_get_tx_fs(struct xgmac_dma_desc *p)
+{
+ return le32_to_cpu(p->flags) & TXDESC_FIRST_SEG;
+}
+
static inline u32 desc_get_buf_addr(struct xgmac_dma_desc *p)
{
return le32_to_cpu(p->buf1_addr);
@@ -796,7 +801,7 @@ static void xgmac_free_rx_skbufs(struct xgmac_priv *priv)
static void xgmac_free_tx_skbufs(struct xgmac_priv *priv)
{
- int i, f;
+ int i;
struct xgmac_dma_desc *p;
if (!priv->tx_skbuff)
@@ -807,16 +812,15 @@ static void xgmac_free_tx_skbufs(struct xgmac_priv *priv)
continue;
p = priv->dma_tx + i;
- dma_unmap_single(priv->device, desc_get_buf_addr(p),
- desc_get_buf_len(p), DMA_TO_DEVICE);
-
- for (f = 0; f < skb_shinfo(priv->tx_skbuff[i])->nr_frags; f++) {
- p = priv->dma_tx + i++;
+ if (desc_get_tx_fs(p))
+ dma_unmap_single(priv->device, desc_get_buf_addr(p),
+ desc_get_buf_len(p), DMA_TO_DEVICE);
+ else
dma_unmap_page(priv->device, desc_get_buf_addr(p),
desc_get_buf_len(p), DMA_TO_DEVICE);
- }
- dev_kfree_skb_any(priv->tx_skbuff[i]);
+ if (desc_get_tx_ls(p))
+ dev_kfree_skb_any(priv->tx_skbuff[i]);
priv->tx_skbuff[i] = NULL;
}
}
@@ -853,8 +857,6 @@ static void xgmac_free_dma_desc_rings(struct xgmac_priv *priv)
*/
static void xgmac_tx_complete(struct xgmac_priv *priv)
{
- int i;
-
while (dma_ring_cnt(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ)) {
unsigned int entry = priv->tx_tail;
struct sk_buff *skb = priv->tx_skbuff[entry];
@@ -864,33 +866,24 @@ static void xgmac_tx_complete(struct xgmac_priv *priv)
if (desc_get_owner(p))
break;
- /* Verify tx error by looking at the last segment */
- if (desc_get_tx_ls(p))
- desc_get_tx_status(priv, p);
-
netdev_dbg(priv->dev, "tx ring: curr %d, dirty %d\n",
priv->tx_head, priv->tx_tail);
- dma_unmap_single(priv->device, desc_get_buf_addr(p),
- desc_get_buf_len(p), DMA_TO_DEVICE);
-
- priv->tx_skbuff[entry] = NULL;
- priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ);
-
- if (!skb) {
- continue;
- }
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- entry = priv->tx_tail = dma_ring_incr(priv->tx_tail,
- DMA_TX_RING_SZ);
- p = priv->dma_tx + priv->tx_tail;
-
+ if (desc_get_tx_fs(p))
+ dma_unmap_single(priv->device, desc_get_buf_addr(p),
+ desc_get_buf_len(p), DMA_TO_DEVICE);
+ else
dma_unmap_page(priv->device, desc_get_buf_addr(p),
desc_get_buf_len(p), DMA_TO_DEVICE);
+
+ /* Check tx error on the last segment */
+ if (desc_get_tx_ls(p)) {
+ desc_get_tx_status(priv, p);
+ dev_kfree_skb(skb);
}
- dev_kfree_skb(skb);
+ priv->tx_skbuff[entry] = NULL;
+ priv->tx_tail = dma_ring_incr(entry, DMA_TX_RING_SZ);
}
if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) >
@@ -1110,7 +1103,7 @@ static netdev_tx_t xgmac_xmit(struct sk_buff *skb, struct net_device *dev)
entry = dma_ring_incr(entry, DMA_TX_RING_SZ);
desc = priv->dma_tx + entry;
- priv->tx_skbuff[entry] = NULL;
+ priv->tx_skbuff[entry] = skb;
desc_set_buf_addr_and_size(desc, paddr, len);
if (i < (nfrags - 1))
--
1.8.1.2
^ permalink raw reply related
* [PATCH v2 02/11] net: calxedaxgmac: read correct field in xgmac_desc_get_buf_len
From: Rob Herring @ 2013-08-30 3:13 UTC (permalink / raw)
To: netdev; +Cc: Lennert Buytenhek, bhutchings, Rob Herring
In-Reply-To: <1377832428-18117-1-git-send-email-robherring2@gmail.com>
From: Rob Herring <rob.herring@calxeda.com>
xgmac_desc_get_buf_len appears to have a copy/paste error. flags is the
wrong field to read. We should be reading buf_size field. cpu_to_le32
should also be le32_to_cpu. This never really mattered as this function
is only used for DMA mapping calls which happen to be nops with coherent
DMA.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
v2: No change
drivers/net/ethernet/calxeda/xgmac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 71f6720..d41af68 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -421,7 +421,7 @@ static inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz)
static inline int desc_get_buf_len(struct xgmac_dma_desc *p)
{
- u32 len = cpu_to_le32(p->flags);
+ u32 len = le32_to_cpu(p->buf_size);
return (len & DESC_BUFFER1_SZ_MASK) +
((len & DESC_BUFFER2_SZ_MASK) >> DESC_BUFFER2_SZ_OFFSET);
}
--
1.8.1.2
^ permalink raw reply related
* [PATCH v2 03/11] net: calxedaxgmac: fix race between xgmac_tx_complete and xgmac_tx_err
From: Rob Herring @ 2013-08-30 3:13 UTC (permalink / raw)
To: netdev; +Cc: Lennert Buytenhek, bhutchings, Rob Herring
In-Reply-To: <1377832428-18117-1-git-send-email-robherring2@gmail.com>
From: Rob Herring <rob.herring@calxeda.com>
It is possible for the xgmac_tx_complete to run concurrently with
xgmac_tx_err since there are no locks. Fix this by moving the tx
error handling to a workqueue so we can disable napi while we reset
the transmitter.
Reported-by: Andreas Herrmann <andreas.herrmann@calxeda.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
v2: No change
drivers/net/ethernet/calxeda/xgmac.c | 38 +++++++++++++++++-------------------
1 file changed, 18 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index d41af68..df7e3e2 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -393,6 +393,7 @@ struct xgmac_priv {
char rx_pause;
char tx_pause;
int wolopts;
+ struct work_struct tx_timeout_work;
};
/* XGMAC Configuration Settings */
@@ -897,21 +898,18 @@ static void xgmac_tx_complete(struct xgmac_priv *priv)
netif_wake_queue(priv->dev);
}
-/**
- * xgmac_tx_err:
- * @priv: pointer to the private device structure
- * Description: it cleans the descriptors and restarts the transmission
- * in case of errors.
- */
-static void xgmac_tx_err(struct xgmac_priv *priv)
+static void xgmac_tx_timeout_work(struct work_struct *work)
{
- u32 reg, value, inten;
+ u32 reg, value;
+ struct xgmac_priv *priv =
+ container_of(work, struct xgmac_priv, tx_timeout_work);
- netif_stop_queue(priv->dev);
+ napi_disable(&priv->napi);
- inten = readl(priv->base + XGMAC_DMA_INTR_ENA);
writel(0, priv->base + XGMAC_DMA_INTR_ENA);
+ netif_tx_lock(priv->dev);
+
reg = readl(priv->base + XGMAC_DMA_CONTROL);
writel(reg & ~DMA_CONTROL_ST, priv->base + XGMAC_DMA_CONTROL);
do {
@@ -927,9 +925,15 @@ static void xgmac_tx_err(struct xgmac_priv *priv)
writel(DMA_STATUS_TU | DMA_STATUS_TPS | DMA_STATUS_NIS | DMA_STATUS_AIS,
priv->base + XGMAC_DMA_STATUS);
- writel(inten, priv->base + XGMAC_DMA_INTR_ENA);
+ netif_tx_unlock(priv->dev);
netif_wake_queue(priv->dev);
+
+ napi_enable(&priv->napi);
+
+ /* Enable interrupts */
+ writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_STATUS);
+ writel(DMA_INTR_DEFAULT_MASK, priv->base + XGMAC_DMA_INTR_ENA);
}
static int xgmac_hw_init(struct net_device *dev)
@@ -1225,9 +1229,7 @@ static int xgmac_poll(struct napi_struct *napi, int budget)
static void xgmac_tx_timeout(struct net_device *dev)
{
struct xgmac_priv *priv = netdev_priv(dev);
-
- /* Clear Tx resources and restart transmitting again */
- xgmac_tx_err(priv);
+ schedule_work(&priv->tx_timeout_work);
}
/**
@@ -1366,7 +1368,6 @@ static irqreturn_t xgmac_pmt_interrupt(int irq, void *dev_id)
static irqreturn_t xgmac_interrupt(int irq, void *dev_id)
{
u32 intr_status;
- bool tx_err = false;
struct net_device *dev = (struct net_device *)dev_id;
struct xgmac_priv *priv = netdev_priv(dev);
struct xgmac_extra_stats *x = &priv->xstats;
@@ -1396,16 +1397,12 @@ static irqreturn_t xgmac_interrupt(int irq, void *dev_id)
if (intr_status & DMA_STATUS_TPS) {
netdev_err(priv->dev, "transmit process stopped\n");
x->tx_process_stopped++;
- tx_err = true;
+ schedule_work(&priv->tx_timeout_work);
}
if (intr_status & DMA_STATUS_FBI) {
netdev_err(priv->dev, "fatal bus error\n");
x->fatal_bus_error++;
- tx_err = true;
}
-
- if (tx_err)
- xgmac_tx_err(priv);
}
/* TX/RX NORMAL interrupts */
@@ -1708,6 +1705,7 @@ static int xgmac_probe(struct platform_device *pdev)
ndev->netdev_ops = &xgmac_netdev_ops;
SET_ETHTOOL_OPS(ndev, &xgmac_ethtool_ops);
spin_lock_init(&priv->stats_lock);
+ INIT_WORK(&priv->tx_timeout_work, xgmac_tx_timeout_work);
priv->device = &pdev->dev;
priv->dev = ndev;
--
1.8.1.2
^ permalink raw reply related
* [PATCH v2 01/11] net: calxedaxgmac: remove NETIF_F_FRAGLIST setting
From: Rob Herring @ 2013-08-30 3:13 UTC (permalink / raw)
To: netdev; +Cc: Lennert Buytenhek, bhutchings, Rob Herring
From: Rob Herring <rob.herring@calxeda.com>
The xgmac does not actually handle frag lists, so this option should not
be set. It does not appear to have had any impact though.
Reported-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
v2: No change
drivers/net/ethernet/calxeda/xgmac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 7cb148c..71f6720 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -1759,7 +1759,7 @@ static int xgmac_probe(struct platform_device *pdev)
if (device_can_wakeup(priv->device))
priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
- ndev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA;
+ ndev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA;
if (readl(priv->base + XGMAC_DMA_HW_FEATURE) & DMA_HW_FEAT_TXCOESEL)
ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM;
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH v3 net-next] tcp: TSO packets automatic sizing
From: Jason Wang @ 2013-08-30 3:02 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, netdev, Neal Cardwell, Yuchung Cheng, Van Jacobson,
Tom Herbert, Michael S. Tsirkin
In-Reply-To: <1377686084.8828.175.camel@edumazet-glaptop>
On 08/28/2013 06:34 PM, Eric Dumazet wrote:
> On Wed, 2013-08-28 at 15:37 +0800, Jason Wang wrote:
>
>>> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
>>> index 884efff..e63ae4c 100644
>>> --- a/net/ipv4/tcp_output.c
>>> +++ b/net/ipv4/tcp_output.c
>>> @@ -1631,7 +1631,7 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
>>>
>>> /* If a full-sized TSO skb can be sent, do it. */
>>> if (limit >= min_t(unsigned int, sk->sk_gso_max_size,
>>> - sk->sk_gso_max_segs * tp->mss_cache))
>>> + tp->xmit_size_goal_segs * tp->mss_cache))
>>> goto send_now;
>> A question is: Does this really guarantee the minimal TSO segments
>> excluding the case of small available window? The skb->len may be much
>> smaller and can still be sent here. Maybe we should check skb->len also?
> tcp_tso_should_defer() is all about hoping the application will
> 'complete' the last skb in write queue with more payload in the near
> future.
>
> skb->len might therefore change because sendmsg()/sendpage() will add
> new stuff in the skb.
Ture, but sometimes the application may be slow to fill the bytes into
skb. Especially the application run in virt guest with multiqueue. In
the case, the application in guest tends to be slower than the
nic(virtio-net) which does the transmission through a host thread
(vhost). Looks like current defer algorithm could not do this very well
and if we want to force the batching of 64K packet, tcp_min_tso_segs
could not works well also.
> We try hard to not remove tcp_tso_should_defer() and take the best of
> it. We have not yet decided to add a real timer instead of relying on
> upcoming ACKS.
>
> Neal has an idea/patch to avoid a defer depending on
> the expected time of following ACKS.
>
> By making the TSO sizes smaller for low rates, we avoid these stalls
> from tcp_tso_should_defer(), because an incoming ACK has normally freed
> enough window to send the next packet in write queue without the need to
> split it into two parts.
>
> These changes are fundamental to use delay based congestion modules like
> Vegas/Westwood and experimental new ones, without having to disable TSO.
>
>
>
^ permalink raw reply
* RE: [PATCH] net: fec: fix build warning of used uninitialized variable
From: Duan Fugang-B38611 @ 2013-08-30 2:47 UTC (permalink / raw)
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, shawn.guo@linaro.org,
bhutchings@solarflare.com, Estevam Fabio-R49496,
stephen@networkplumber.org, Li Frank-B20596
In-Reply-To: <1F990F8245A4214A8CC4BFFBD9F790F908B16AA6@039-SN1MPN1-002.039d.mgd.msft.net>
Ping...
> -----Original Message-----
> From: Li Frank-B20596
> Sent: Thursday, August 22, 2013 10:16 PM
> To: Duan Fugang-B38611; Zhou Luwei-B45643; davem@davemloft.net
> Cc: netdev@vger.kernel.org; shawn.guo@linaro.org;
> bhutchings@solarflare.com; Estevam Fabio-R49496;
> stephen@networkplumber.org
> Subject: RE: [PATCH] net: fec: fix build warning of used uninitialized
> variable
>
> > diff --git a/drivers/net/ethernet/freescale/fec_main.c
> > b/drivers/net/ethernet/freescale/fec_main.c
> > index 77ea0db..4ea1555 100644
> > --- a/drivers/net/ethernet/freescale/fec_main.c
> > +++ b/drivers/net/ethernet/freescale/fec_main.c
> > @@ -835,7 +835,7 @@ fec_enet_rx(struct net_device *ndev, int budget)
> > int pkt_received = 0;
> > struct bufdesc_ex *ebdp = NULL;
> > bool vlan_packet_rcvd = false;
> > - u16 vlan_tag;
> > + u16 vlan_tag = 0;
> >
> > #ifdef CONFIG_M532x
> > flush_cache_all();
>
> Acked
>
> > --
> > 1.7.1
^ permalink raw reply
* [PATCH iproute2] pkt_sched: fq: Fair Queue packet scheduler
From: Eric Dumazet @ 2013-08-30 2:30 UTC (permalink / raw)
To: David Miller, Stephen Hemminger; +Cc: netdev, ycheng, ncardwell
In-Reply-To: <20130829.214730.2158572637993114547.davem@davemloft.net>
From: Eric Dumazet <edumazet@google.com>
Support for FQ packet scheduler
$ tc qd add dev eth0 root fq help
Usage: ... fq [ limit PACKETS ] [ flow_limit PACKETS ]
[ quantum BYTES ] [ initial_quantum BYTES ]
[ maxrate RATE ] [ buckets NUMBER ]
[ [no]pacing ]
$ tc -s -d qd
qdisc fq 8002: dev eth0 root refcnt 32 limit 10000p flow_limit 100p
buckets 256 quantum 3028 initial_quantum 15140
Sent 216532416 bytes 148395 pkt (dropped 0, overlimits 0 requeues 14)
backlog 0b 0p requeues 14
511 flows (511 inactive, 0 throttled)
110 gc, 0 highprio, 0 retrans, 1143 throttled, 0 flows_plimit
limit : max number of packets on whole Qdisc (default 10000)
flow_limit : max number of packets per flow (default 100)
quantum : the max deficit per RR round (default is 2 MTU)
initial_quantum : initial credit for new flows (default is 10 MTU)
maxrate : max per flow rate (default : unlimited)
buckets : number of RB trees (default : 1024) in hash table.
(consumes 8 bytes per bucket)
[no]pacing : disable/enable pacing (default is enable)
Usage :
tc qdisc add dev $ETH root fq
tc qdisc del dev $ETH root 2>/dev/null
tc qdisc add dev $ETH root handle 1: mq
for i in `seq 1 4`
do
tc qdisc add dev $ETH parent 1:$i est 1sec 4sec fq
done
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/pkt_sched.h | 51 ++++++
tc/Makefile | 1
tc/q_fq.c | 279 ++++++++++++++++++++++++++++++++++++
3 files changed, 330 insertions(+), 1 deletion(-)
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index dbd71b0..9b82913 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -73,9 +73,17 @@ struct tc_estimator {
#define TC_H_ROOT (0xFFFFFFFFU)
#define TC_H_INGRESS (0xFFFFFFF1U)
+/* Need to corrospond to iproute2 tc/tc_core.h "enum link_layer" */
+enum tc_link_layer {
+ TC_LINKLAYER_UNAWARE, /* Indicate unaware old iproute2 util */
+ TC_LINKLAYER_ETHERNET,
+ TC_LINKLAYER_ATM,
+};
+#define TC_LINKLAYER_MASK 0x0F /* limit use to lower 4 bits */
+
struct tc_ratespec {
unsigned char cell_log;
- unsigned char __reserved;
+ __u8 linklayer; /* lower 4 bits */
unsigned short overhead;
short cell_align;
unsigned short mpu;
@@ -736,4 +744,45 @@ struct tc_fq_codel_xstats {
};
};
+/* FQ */
+
+enum {
+ TCA_FQ_UNSPEC,
+
+ TCA_FQ_PLIMIT, /* limit of total number of packets in queue */
+
+ TCA_FQ_FLOW_PLIMIT, /* limit of packets per flow */
+
+ TCA_FQ_QUANTUM, /* RR quantum */
+
+ TCA_FQ_INITIAL_QUANTUM, /* RR quantum for new flow */
+
+ TCA_FQ_RATE_ENABLE, /* enable/disable rate limiting */
+
+ TCA_FQ_FLOW_DEFAULT_RATE,/* for sockets with unspecified sk_rate,
+ * use the following rate
+ */
+
+ TCA_FQ_FLOW_MAX_RATE, /* per flow max rate */
+
+ TCA_FQ_BUCKETS_LOG, /* log2(number of buckets) */
+ __TCA_FQ_MAX
+};
+
+#define TCA_FQ_MAX (__TCA_FQ_MAX - 1)
+
+struct tc_fq_qd_stats {
+ __u64 gc_flows;
+ __u64 highprio_packets;
+ __u64 tcp_retrans;
+ __u64 throttled;
+ __u64 flows_plimit;
+ __u64 pkts_too_long;
+ __u64 allocation_errors;
+ __s64 time_next_delayed_flow;
+ __u32 flows;
+ __u32 inactive_flows;
+ __u32 throttled_flows;
+ __u32 pad;
+};
#endif
diff --git a/tc/Makefile b/tc/Makefile
index f26e764..1eeabd8 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -50,6 +50,7 @@ TCMODULES += em_meta.o
TCMODULES += q_mqprio.o
TCMODULES += q_codel.o
TCMODULES += q_fq_codel.o
+TCMODULES += q_fq.o
ifeq ($(TC_CONFIG_IPSET), y)
ifeq ($(TC_CONFIG_XT), y)
diff --git a/tc/q_fq.c b/tc/q_fq.c
new file mode 100644
index 0000000..c0bcdb9
--- /dev/null
+++ b/tc/q_fq.c
@@ -0,0 +1,279 @@
+/*
+ * Fair Queue
+ *
+ * Copyright (C) 2013 Eric Dumazet <edumazet@google.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include "utils.h"
+#include "tc_util.h"
+
+static void explain(void)
+{
+ fprintf(stderr, "Usage: ... fq [ limit PACKETS ] [ flow_limit PACKETS ]\n");
+ fprintf(stderr, " [ quantum BYTES ] [ initial_quantum BYTES ]\n");
+ fprintf(stderr, " [ maxrate RATE ] [ buckets NUMBER ]\n");
+ fprintf(stderr, " [ [no]pacing ]\n");
+}
+
+static unsigned int ilog2(unsigned int val)
+{
+ unsigned int res = 0;
+
+ val--;
+ while (val) {
+ res++;
+ val >>= 1;
+ }
+ return res;
+}
+
+static int fq_parse_opt(struct qdisc_util *qu, int argc, char **argv,
+ struct nlmsghdr *n)
+{
+ unsigned int plimit = ~0U;
+ unsigned int flow_plimit = ~0U;
+ unsigned int quantum = ~0U;
+ unsigned int initial_quantum = ~0U;
+ unsigned int buckets = 0;
+ unsigned int maxrate = ~0U;
+ unsigned int defrate = ~0U;
+ int pacing = -1;
+ struct rtattr *tail;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "limit") == 0) {
+ NEXT_ARG();
+ if (get_unsigned(&plimit, *argv, 0)) {
+ fprintf(stderr, "Illegal \"limit\"\n");
+ return -1;
+ }
+ } else if (strcmp(*argv, "flow_limit") == 0) {
+ NEXT_ARG();
+ if (get_unsigned(&flow_plimit, *argv, 0)) {
+ fprintf(stderr, "Illegal \"flow_limit\"\n");
+ return -1;
+ }
+ } else if (strcmp(*argv, "buckets") == 0) {
+ NEXT_ARG();
+ if (get_unsigned(&buckets, *argv, 0)) {
+ fprintf(stderr, "Illegal \"buckets\"\n");
+ return -1;
+ }
+ } else if (strcmp(*argv, "maxrate") == 0) {
+ NEXT_ARG();
+ if (get_rate(&maxrate, *argv)) {
+ fprintf(stderr, "Illegal \"maxrate\"\n");
+ return -1;
+ }
+ } else if (strcmp(*argv, "defrate") == 0) {
+ NEXT_ARG();
+ if (get_rate(&defrate, *argv)) {
+ fprintf(stderr, "Illegal \"defrate\"\n");
+ return -1;
+ }
+ } else if (strcmp(*argv, "quantum") == 0) {
+ NEXT_ARG();
+ if (get_unsigned(&quantum, *argv, 0)) {
+ fprintf(stderr, "Illegal \"quantum\"\n");
+ return -1;
+ }
+ } else if (strcmp(*argv, "initial_quantum") == 0) {
+ NEXT_ARG();
+ if (get_unsigned(&initial_quantum, *argv, 0)) {
+ fprintf(stderr, "Illegal \"initial_quantum\"\n");
+ return -1;
+ }
+ } else if (strcmp(*argv, "pacing") == 0) {
+ pacing = 1;
+ } else if (strcmp(*argv, "nopacing") == 0) {
+ pacing = 0;
+ } else if (strcmp(*argv, "help") == 0) {
+ explain();
+ return -1;
+ } else {
+ fprintf(stderr, "What is \"%s\"?\n", *argv);
+ explain();
+ return -1;
+ }
+ argc--; argv++;
+ }
+
+ tail = NLMSG_TAIL(n);
+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
+ if (buckets) {
+ unsigned int log = ilog2(buckets);
+
+ addattr_l(n, 1024, TCA_FQ_BUCKETS_LOG,
+ &log, sizeof(log));
+ }
+ if (plimit != ~0U)
+ addattr_l(n, 1024, TCA_FQ_PLIMIT,
+ &plimit, sizeof(plimit));
+ if (flow_plimit != ~0U)
+ addattr_l(n, 1024, TCA_FQ_FLOW_PLIMIT,
+ &flow_plimit, sizeof(flow_plimit));
+ if (quantum != ~0U)
+ addattr_l(n, 1024, TCA_FQ_QUANTUM, &quantum, sizeof(quantum));
+ if (initial_quantum != ~0U)
+ addattr_l(n, 1024, TCA_FQ_INITIAL_QUANTUM,
+ &initial_quantum, sizeof(initial_quantum));
+ if (pacing != -1)
+ addattr_l(n, 1024, TCA_FQ_RATE_ENABLE,
+ &pacing, sizeof(pacing));
+ if (maxrate != ~0U)
+ addattr_l(n, 1024, TCA_FQ_FLOW_MAX_RATE,
+ &maxrate, sizeof(maxrate));
+ if (defrate != ~0U)
+ addattr_l(n, 1024, TCA_FQ_FLOW_DEFAULT_RATE,
+ &defrate, sizeof(defrate));
+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
+ return 0;
+}
+
+static int fq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
+{
+ struct rtattr *tb[TCA_FQ_MAX + 1];
+ unsigned int plimit, flow_plimit;
+ unsigned int buckets_log;
+ int pacing;
+ unsigned int rate, quantum;
+ SPRINT_BUF(b1);
+
+ if (opt == NULL)
+ return 0;
+
+ parse_rtattr_nested(tb, TCA_FQ_MAX, opt);
+
+ if (tb[TCA_FQ_PLIMIT] &&
+ RTA_PAYLOAD(tb[TCA_FQ_PLIMIT]) >= sizeof(__u32)) {
+ plimit = rta_getattr_u32(tb[TCA_FQ_PLIMIT]);
+ fprintf(f, "limit %up ", plimit);
+ }
+ if (tb[TCA_FQ_FLOW_PLIMIT] &&
+ RTA_PAYLOAD(tb[TCA_FQ_FLOW_PLIMIT]) >= sizeof(__u32)) {
+ flow_plimit = rta_getattr_u32(tb[TCA_FQ_FLOW_PLIMIT]);
+ fprintf(f, "flow_limit %up ", flow_plimit);
+ }
+ if (tb[TCA_FQ_BUCKETS_LOG] &&
+ RTA_PAYLOAD(tb[TCA_FQ_BUCKETS_LOG]) >= sizeof(__u32)) {
+ buckets_log = rta_getattr_u32(tb[TCA_FQ_BUCKETS_LOG]);
+ fprintf(f, "buckets %u ", 1U << buckets_log);
+ }
+ if (tb[TCA_FQ_RATE_ENABLE] &&
+ RTA_PAYLOAD(tb[TCA_FQ_RATE_ENABLE]) >= sizeof(int)) {
+ pacing = rta_getattr_u32(tb[TCA_FQ_RATE_ENABLE]);
+ if (pacing == 0)
+ fprintf(f, "nopacing ");
+ }
+ if (tb[TCA_FQ_QUANTUM] &&
+ RTA_PAYLOAD(tb[TCA_FQ_QUANTUM]) >= sizeof(__u32)) {
+ quantum = rta_getattr_u32(tb[TCA_FQ_QUANTUM]);
+ fprintf(f, "quantum %u ", quantum);
+ }
+ if (tb[TCA_FQ_INITIAL_QUANTUM] &&
+ RTA_PAYLOAD(tb[TCA_FQ_INITIAL_QUANTUM]) >= sizeof(__u32)) {
+ quantum = rta_getattr_u32(tb[TCA_FQ_INITIAL_QUANTUM]);
+ fprintf(f, "initial_quantum %u ", quantum);
+ }
+ if (tb[TCA_FQ_FLOW_MAX_RATE] &&
+ RTA_PAYLOAD(tb[TCA_FQ_FLOW_MAX_RATE]) >= sizeof(__u32)) {
+ rate = rta_getattr_u32(tb[TCA_FQ_FLOW_MAX_RATE]);
+
+ if (rate != ~0U)
+ fprintf(f, "maxrate %s ", sprint_rate(rate, b1));
+ }
+ if (tb[TCA_FQ_FLOW_DEFAULT_RATE] &&
+ RTA_PAYLOAD(tb[TCA_FQ_FLOW_DEFAULT_RATE]) >= sizeof(__u32)) {
+ rate = rta_getattr_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]);
+
+ if (rate != 0)
+ fprintf(f, "defrate %s ", sprint_rate(rate, b1));
+ }
+
+ return 0;
+}
+
+static int fq_print_xstats(struct qdisc_util *qu, FILE *f,
+ struct rtattr *xstats)
+{
+ struct tc_fq_qd_stats *st;
+
+ if (xstats == NULL)
+ return 0;
+
+ if (RTA_PAYLOAD(xstats) < sizeof(*st))
+ return -1;
+
+ st = RTA_DATA(xstats);
+
+ fprintf(f, " %u flows (%u inactive, %u throttled)",
+ st->flows, st->inactive_flows, st->throttled_flows);
+
+ if (st->time_next_delayed_flow > 0)
+ fprintf(f, ", next packet delay %llu ns", st->time_next_delayed_flow);
+
+ fprintf(f, "\n %llu gc, %llu highprio",
+ st->gc_flows, st->highprio_packets);
+
+ if (st->tcp_retrans)
+ fprintf(f, ", %llu retrans", st->tcp_retrans);
+
+ fprintf(f, ", %llu throttled", st->throttled);
+
+ if (st->flows_plimit)
+ fprintf(f, ", %llu flows_plimit", st->flows_plimit);
+
+ if (st->pkts_too_long || st->allocation_errors)
+ fprintf(f, "\n %llu too long pkts, %llu alloc errors\n",
+ st->pkts_too_long, st->allocation_errors);
+
+ return 0;
+}
+
+struct qdisc_util fq_qdisc_util = {
+ .id = "fq",
+ .parse_qopt = fq_parse_opt,
+ .print_qopt = fq_print_opt,
+ .print_xstats = fq_print_xstats,
+};
^ permalink raw reply related
* Re: [PATCH net-next] qdisc: allow setting default queuing discipline
From: David Miller @ 2013-08-30 2:25 UTC (permalink / raw)
To: greearb; +Cc: stephen, netdev
In-Reply-To: <521D34CC.205@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Date: Tue, 27 Aug 2013 16:22:52 -0700
> On 08/27/2013 04:19 PM, Stephen Hemminger wrote:
>> +CoDel (codel) or fair queue CoDel (fq_codel). Dont' use queuing
>> disciplines
>
> nit: Don't has typo above....
I fixed this when I commited Stephen's patch, thanks.
^ permalink raw reply
* Re: [PATCH net-next] qdisc: allow setting default queuing discipline
From: David Miller @ 2013-08-30 2:23 UTC (permalink / raw)
To: stephen; +Cc: netdev
In-Reply-To: <20130827161908.26062336@nehalam.linuxnetplumber.net>
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Tue, 27 Aug 2013 16:19:08 -0700
> By default, the pfifo_fast queue discipline has been used by default
> for all devices. But we have better choices now.
>
> This patch allow setting the default queueing discipline with sysctl.
> This allows easy use of better queueing disciplines on all devices
> without having to use tc qdisc scripts. It is intended to allow
> an easy path for distributions to make fq_codel or sfq the default
> qdisc.
>
> This patch also makes pfifo_fast more of a first class qdisc, since
> it is now possible to manually override the default and explicitly
> use pfifo_fast. The behavior for systems who do not use the sysctl
> is unchanged, they still get pfifo_fast
>
> Also removes leftover random # in sysctl net core.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Applied, thanks Stpehen.
^ permalink raw reply
* Re: [PATCH net-next] drivers:net: Convert dma_alloc_coherent(...__GFP_ZERO) to dma_zalloc_coherent
From: David Miller @ 2013-08-30 2:09 UTC (permalink / raw)
To: joe; +Cc: netdev, linux-kernel, e1000-devel, linux-wireless, b43-dev, users
In-Reply-To: <1377582323.2658.10.camel@joe-AO722>
From: Joe Perches <joe@perches.com>
Date: Mon, 26 Aug 2013 22:45:23 -0700
> __GFP_ZERO is an uncommon flag and perhaps is better
> not used. static inline dma_zalloc_coherent exists
> so convert the uses of dma_alloc_coherent with __GFP_ZERO
> to the more common kernel style with zalloc.
>
> Remove memset from the static inline dma_zalloc_coherent
> and add just one use of __GFP_ZERO instead.
>
> Trivially reduces the size of the existing uses of
> dma_zalloc_coherent.
>
> Realign arguments as appropriate.
>
> Signed-off-by: Joe Perches <joe@perches.com>
Applied, thanks a lot Joe.
^ permalink raw reply
* RE: [patch v2] net/fec: cleanup types in fec_get_mac()
From: Duan Fugang-B38611 @ 2013-08-30 2:02 UTC (permalink / raw)
To: Ben Hutchings, Dan Carpenter
Cc: Grant Likely, Rob Herring, David S. Miller, Estevam Fabio-R49496,
Li Frank-B20596, Jim Baxter, netdev@vger.kernel.org,
devicetree@vger.kernel.org, kernel-janitors@vger.kernel.org
In-Reply-To: <1377802138.5372.12.camel@bwh-desktop.uk.level5networks.com>
From: Ben Hutchings [mailto:bhutchings@solarflare.com]
Data: Friday, August 30, 2013 2:49 AM
> To: Dan Carpenter
> Cc: Grant Likely; Rob Herring; David S. Miller; Estevam Fabio-R49496; Li
> Frank-B20596; Jim Baxter; Duan Fugang-B38611; netdev@vger.kernel.org;
> devicetree@vger.kernel.org; kernel-janitors@vger.kernel.org
> Subject: Re: [patch v2] net/fec: cleanup types in fec_get_mac()
>
> On Thu, 2013-08-29 at 11:25 +0300, Dan Carpenter wrote:
> > My static checker complains that on some arches unsigned longs can be
> > 8 characters which is larger than the buffer is only 6 chars.
> > Additionally, Ben Hutchings points out that the buffer actually holds
> > big endian data and the buffer we are reading from is CPU endian.
>
> It's not really as clear-cut as that. :-) But I think it's slightly more
> logical this way.
>
Yes, it is not clear, pls remove somebody's name from the commit log.
> > Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
>
> Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
>
> > ---
> > v2: fix endian annotations and reverse the beXX_to_cpu() calls so that
> > they say cpu_to_beXX().
> >
> > diff --git a/drivers/net/ethernet/freescale/fec_main.c
> > b/drivers/net/ethernet/freescale/fec_main.c
> > index fdf9307..0b12866 100644
> > --- a/drivers/net/ethernet/freescale/fec_main.c
> > +++ b/drivers/net/ethernet/freescale/fec_main.c
> > @@ -1100,10 +1100,10 @@ static void fec_get_mac(struct net_device *ndev)
> > * 4) FEC mac registers set by bootloader
> > */
> > if (!is_valid_ether_addr(iap)) {
> > - *((unsigned long *) &tmpaddr[0]) =
> > - be32_to_cpu(readl(fep->hwp + FEC_ADDR_LOW));
> > - *((unsigned short *) &tmpaddr[4]) =
> > - be16_to_cpu(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
> > + *((__be32 *) &tmpaddr[0]) =
> > + cpu_to_be32(readl(fep->hwp + FEC_ADDR_LOW));
> > + *((__be16 *) &tmpaddr[4]) =
> > + cpu_to_be16(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
> > iap = &tmpaddr[0];
> > }
> >
>
> --
> Ben Hutchings, Staff Engineer, Solarflare Not speaking for my employer;
> that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>
^ permalink raw reply
* RE: [PATCH] net: fec: add the initial to set the physical mac address
From: Duan Fugang-B38611 @ 2013-08-30 1:59 UTC (permalink / raw)
To: Lucas Stach, davem@davemloft.net
Cc: davem@davemloft.net, netdev@vger.kernel.org,
bhutchings@solarflare.com, Estevam Fabio-R49496,
stephen@networkplumber.org
In-Reply-To: <9848F2DB572E5649BA045B288BE08FBE01653FEA@039-SN2MPN1-021.039d.mgd.msft.net>
Ping...
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
> On Behalf Of Duan Fugang-B38611
> Sent: Wednesday, August 28, 2013 10:11 AM
> To: Lucas Stach
> Cc: Li Frank-B20596; Zhou Luwei-B45643; davem@davemloft.net;
> netdev@vger.kernel.org; shawn.guo@linaro.org; bhutchings@solarflare.com;
> Estevam Fabio-R49496; stephen@networkplumber.org
> Subject: RE: [PATCH] net: fec: add the initial to set the physical mac
> address
>
> From: Lucas Stach [mailto:l.stach@pengutronix.de]
> Data: Tuesday, August 27, 2013 10:19 PM
>
> > To: Duan Fugang-B38611
> > Cc: Li Frank-B20596; Zhou Luwei-B45643; davem@davemloft.net;
> > netdev@vger.kernel.org; shawn.guo@linaro.org;
> > bhutchings@solarflare.com; Estevam Fabio-R49496;
> > stephen@networkplumber.org
> > Subject: Re: [PATCH] net: fec: add the initial to set the physical mac
> > address
> >
> > Am Donnerstag, den 22.08.2013, 19:17 +0800 schrieb Fugang Duan:
> > > For imx6slx evk platform, the fec driver cannot work since there
> > > have no valid mac address set in physical mac registers.
> > >
> > > For imx serial platform, fec/enet IPs both need the physical MAC
> > > address initial, otherwise it cannot work.
> > >
> > > After acquiring the valid MAC address from devices tree/pfuse/
> > > kernel command line/random mac address, and then set it to the
> > > physical MAC address registers.
> > >
> > Yeah, we have also seen that we need to set this explicitly. The
> > strange thing is that I recall this used to work without calling
> > fec_set_mac_address() explicitly, so either the netdev core was
> > calling it at some point, or our userspace was. I didn't got around to
> > investigate this further.
> Netdev core don't call the function willingly, if only user config MAC
> address such as call ioctl(sockfd, SIOCSIFHWADDR, ifreq).
>
> > So anyway:
> > Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
> >
> > > Signed-off-by: Fugang Duan <B38611@freescale.com>
> > > ---
> > > drivers/net/ethernet/freescale/fec_main.c | 9 ++++++---
> > > 1 files changed, 6 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/net/ethernet/freescale/fec_main.c
> > > b/drivers/net/ethernet/freescale/fec_main.c
> > > index 4349a9e..9b5e08c 100644
> > > --- a/drivers/net/ethernet/freescale/fec_main.c
> > > +++ b/drivers/net/ethernet/freescale/fec_main.c
> > > @@ -1867,10 +1867,12 @@ fec_set_mac_address(struct net_device *ndev,
> > void *p)
> > > struct fec_enet_private *fep = netdev_priv(ndev);
> > > struct sockaddr *addr = p;
> > >
> > > - if (!is_valid_ether_addr(addr->sa_data))
> > > - return -EADDRNOTAVAIL;
> > > + if (p) {
> > > + if (!is_valid_ether_addr(addr->sa_data))
> > > + return -EADDRNOTAVAIL;
> > >
> > > - memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
> > > + memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
> > > + }
> > >
> > > writel(ndev->dev_addr[3] | (ndev->dev_addr[2] << 8) |
> > > (ndev->dev_addr[1] << 16) | (ndev->dev_addr[0] << 24), @@ -
> > 1969,6
> > > +1971,7 @@ static int fec_enet_init(struct net_device *ndev)
> > >
> > > /* Get the Ethernet address */
> > > fec_get_mac(ndev);
> > > + fec_set_mac_address(ndev, NULL);
> > >
> > > /* Set receive and transmit descriptor base. */
> > > fep->rx_bd_base = cbd_base;
> >
> > --
> > Pengutronix e.K. | Lucas Stach
> |
> > Industrial Linux Solutions | http://www.pengutronix.de/
> |
> > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-5076
> |
> > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555
> |
> >
>
^ permalink raw reply
* Re: [PATCH 1/5] bonding: simplify and use RCU protection for 3ad xmit path
From: Ding Tianhong @ 2013-08-30 1:57 UTC (permalink / raw)
To: Nikolay Aleksandrov
Cc: Jay Vosburgh, Andy Gospodarek, David S. Miller, Veaceslav Falico,
Netdev
In-Reply-To: <521F59E2.8030707@redhat.com>
On 2013/8/29 22:25, Nikolay Aleksandrov wrote:
> On 08/28/2013 06:20 AM, Ding Tianhong wrote:
>> The commit 278b20837511776dc9d5f6ee1c7fabd5479838bb
>> (bonding: initial RCU conversion) has convert the roundrobin, active-backup,
>> broadcast and xor xmit path to rcu protection, the performance will be better
>> for these mode, so this time, convert xmit path for 3ad mode.
>>
>> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
>> Signed-off-by: Wang Yufen <wangyufen@huawei.com>
>> Cc: Nikolay Aleksandrov <nikolay@redhat.com>
>> Cc: Veaceslav Falico <vfalico@redhat.com>
>> ---
>> drivers/net/bonding/bond_3ad.c | 31 +++++++++++++------------------
>> drivers/net/bonding/bonding.h | 22 ++++++++++++++++++++++
>> 2 files changed, 35 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
>> index 9010265..52d76a4 100644
>> --- a/drivers/net/bonding/bond_3ad.c
>> +++ b/drivers/net/bonding/bond_3ad.c
>> @@ -143,7 +143,7 @@ static inline struct bonding *__get_bond_by_port(struct port *port)
>> */
>> static inline struct port *__get_first_port(struct bonding *bond)
>> {
>> - struct slave *first_slave = bond_first_slave(bond);
>> + struct slave *first_slave = bond_first_slave_rcu(bond);
>>
>> return first_slave ? &(SLAVE_AD_INFO(first_slave).port) : NULL;
>> }
>> @@ -163,7 +163,7 @@ static inline struct port *__get_next_port(struct port *port)
>> // If there's no bond for this port, or this is the last slave
>> if (bond == NULL)
>> return NULL;
>> - slave_next = bond_next_slave(bond, slave);
>> + slave_next = bond_next_slave_rcu(bond, slave);
>> if (!slave_next || bond_is_first_slave(bond, slave_next))
>> return NULL;
>>
>> @@ -2417,16 +2417,14 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
>>
>> int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
>> {
>> - struct slave *slave, *start_at;
>> + struct slave *slave;
> Please re-arrange longest -> shortest where possible.
>
something wrong with my vim, so fix it, thanks.
>> struct bonding *bond = netdev_priv(dev);
>> int slave_agg_no;
>> int slaves_in_agg;
>> int agg_id;
>> - int i;
>> struct ad_info ad_info;
>> int res = 1;
>>
>> - read_lock(&bond->lock);
>> if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
>> pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n",
>> dev->name);
>> @@ -2444,13 +2442,16 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
>>
>> slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg);
>>
>> - bond_for_each_slave(bond, slave) {
>> + bond_for_each_slave_rcu(bond, slave) {
>> struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
>>
>> if (agg && (agg->aggregator_identifier == agg_id)) {
>> - slave_agg_no--;
>> - if (slave_agg_no < 0)
>> - break;
>> + if (--slave_agg_no < 0) {
>> + if (SLAVE_IS_OK(slave)) {
>> + res = bond_dev_queue_xmit(bond, skb, slave->dev);
>> + goto out;
>> + }
>> + }
>> }
>> }
>>
>> @@ -2460,23 +2461,17 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
>> goto out;
>> }
>>
>> - start_at = slave;
>> -
>> - bond_for_each_slave_from(bond, slave, i, start_at) {
>> - int slave_agg_id = 0;
>> + bond_for_each_slave_rcu(bond, slave) {
>> struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
>>
>> - if (agg)
>> - slave_agg_id = agg->aggregator_identifier;
>> -
>> - if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) {
>> + if (SLAVE_IS_OK(slave) && agg &&
>> + (agg->aggregator_identifier == agg_id)) {
> Please drop the ( ) from (agg->aggregator_identifier == agg_id), also align it
> properly.
>
my mistake, thanks.
>> res = bond_dev_queue_xmit(bond, skb, slave->dev);
>> break;
>> }
>> }
>>
>> out:
>> - read_unlock(&bond->lock);
>> if (res) {
>> /* no suitable interface, frame not sent */
>> kfree_skb(skb);
>> diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
>> index 4bf52d5..ecb5d1d 100644
>> --- a/drivers/net/bonding/bonding.h
>> +++ b/drivers/net/bonding/bonding.h
>> @@ -74,6 +74,9 @@
>> /* slave list primitives */
>> #define bond_to_slave(ptr) list_entry(ptr, struct slave, list)
>>
>> +/* slave list primitives, Caller must hold rcu_read_lock */
>> +#define bond_to_slave_rcu(ptr) list_entry_rcu(ptr, struct slave, list)
>> +
>> /* IMPORTANT: bond_first/last_slave can return NULL in case of an empty list */
>> #define bond_first_slave(bond) \
>> list_first_entry_or_null(&(bond)->slave_list, struct slave, list)
>> @@ -81,6 +84,16 @@
>> (list_empty(&(bond)->slave_list) ? NULL : \
>> bond_to_slave((bond)->slave_list.prev))
>>
>> +/**
>> + * IMPORTANT: bond_first/last_slave_rcu can return NULL in case of an empty list
>> + * Caller must hold rcu_read_lock
>> + */
> Styling nit: the comments in net/ should be /* text...
miss the net-next. add in resend.
>
>> +#define bond_first_slave_rcu(bond) \
>> + list_first_or_null_rcu(&(bond)->slave_list, struct slave, list)
>> +#define bond_last_slave_rcu(bond) \
>> + (list_emptry(&(bond)->slave_list) ? NULL : \
> ^^^^^^^^^^^^^^^^^^^^^
> Did you compile this ?
oh, I compiled, but the func did not used, so did not show any problem, it's a big error, I will review
and check all above.
>
>> + bond_to_slave_rcu((bond)->slave_list.prev))
>> +
>> #define bond_is_first_slave(bond, pos) ((pos)->list.prev == &(bond)->slave_list)
>> #define bond_is_last_slave(bond, pos) ((pos)->list.next == &(bond)->slave_list)
>>
>> @@ -93,6 +106,15 @@
>> (bond_is_first_slave(bond, pos) ? bond_last_slave(bond) : \
>> bond_to_slave((pos)->list.prev))
>>
>> +/* Since bond_first/last_slave_rcu can return NULL, these can return NULL too */
>> +#define bond_next_slave_rcu(bond, pos) \
>> + (bond_is_last_slave(bond, pos) ? bond_first_slave_rcu(bond) : \
>> + bond_to_slave_rcu((pos)->list.next))
>> +
>> +#define bond_prev_slave_rcu(bond, pos) \
>> + (bond_is_first_slave(bond, pos) ? bond_last_slave_rcu(bond) : \
>> + bond_to_slave_rcu((pos)->list.prev))
>> +
>> /**
>> * bond_for_each_slave_from - iterate the slaves list from a starting point
>> * @bond: the bond holding this list.
>>
>
>
> .
>
^ permalink raw reply
* Re: [PATCH v2 net-next] pkt_sched: fq: Fair Queue packet scheduler
From: David Miller @ 2013-08-30 1:47 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, ycheng, ncardwell
In-Reply-To: <1377816595.8277.54.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 29 Aug 2013 15:49:55 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> - Uses perfect flow match (not stochastic hash like SFQ/FQ_codel)
> - Uses the new_flow/old_flow separation from FQ_codel
> - New flows get an initial credit allowing IW10 without added delay.
> - Special FIFO queue for high prio packets (no need for PRIO + FQ)
> - Uses a hash table of RB trees to locate the flows at enqueue() time
> - Smart on demand gc (at enqueue() time, RB tree lookup evicts old
> unused flows)
> - Dynamic memory allocations.
> - Designed to allow millions of concurrent flows per Qdisc.
> - Small memory footprint : ~8K per Qdisc, and 104 bytes per flow.
> - Single high resolution timer for throttled flows (if any).
> - One RB tree to link throttled flows.
> - Ability to have a max rate per flow. We might add a socket option
> to add per socket limitation.
>
> Attempts have been made to add TCP pacing in TCP stack, but this
> seems to add complex code to an already complex stack.
>
> TCP pacing is welcomed for flows having idle times, as the cwnd
> permits TCP stack to queue a possibly large number of packets.
>
> This removes the 'slow start after idle' choice, hitting badly
> large BDP flows, and applications delivering chunks of data
> as video streams.
>
> Nicely spaced packets :
> Here interface is 10Gbit, but flow bottleneck is ~20Mbit
>
> cwin is big, yet FQ avoids the typical bursts generated by TCP
> (as in netperf TCP_RR -- -r 100000,100000)
...
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied, thanks Eric!
^ permalink raw reply
* Re: [PATCH 0/5] bonding: Patchset for rcu use in bonding
From: Ding Tianhong @ 2013-08-30 1:37 UTC (permalink / raw)
To: Nikolay Aleksandrov
Cc: Jay Vosburgh, Andy Gospodarek, David S. Miller, Veaceslav Falico,
Netdev
In-Reply-To: <521F5AA3.4030105@redhat.com>
On 2013/8/29 22:28, Nikolay Aleksandrov wrote:
> On 08/28/2013 06:20 AM, Ding Tianhong wrote:
>> Hi:
>>
>> The Patch Set convert the xmit of 3ad and alb mode to use rcu lock.
>> replace and add more rcu list function.
>> fix a bug to protect bonding_store_xmit_hash().
>>
>> I test well and no problems found till now.
>>
>> Ding Tianhong (3):
>> Wang Yufen (1):
>> Yang Yingliang (1):
>> bonding: simplify and use RCU protection for 3ad xmit path
>> bonding: replace read_lock to rcu_read_lock for
>> bond_3ad_get_active_agg_info()
>> bonding: add rtnl lock for bonding_store_xmit_hash
>> bonding: restructure and simplify bond_for_each_slave_next()
>> bonding: use RCU protection for alb xmit path
>>
>> drivers/net/bonding/bond_3ad.c | 35 +++++++++++++++-------------------
>> drivers/net/bonding/bond_alb.c | 23 ++++++++++------------
>> drivers/net/bonding/bond_main.c | 6 ++----
>> drivers/net/bonding/bond_sysfs.c | 4 ++++
>> drivers/net/bonding/bonding.h | 41 ++++++++++++++++++++++++++++++++++++----
>> 5 files changed, 68 insertions(+), 41 deletions(-)
>>
> Thanks for the work, I was on vacation and travelling after my initial RCU
> conversion so I got a little behind with these conversions, my idea was quite
> different :-)
> Anyway, I'd also appreciate some benchmarks, also some more information on what
> type of testing did you run ?
> I've given some preliminary comments to the patches, I'll have to think more
> about them in this form.
>
> Cheers,
> Nik
>
> .
It looks like a wonderful vocation :).
I focus on the 3ad and alb mode, because the modify was manly for xmit, so my test environment was consist of 4 Intel82599 10G card, and use mode lacp ,alb.
I use iperf to test, after the patch, the performance was a little better and no problem
occurs.
>
^ permalink raw reply
* Re: [PATCH net-next] tcp: Remove needless check of return value
From: David Miller @ 2013-08-30 1:36 UTC (permalink / raw)
To: subramanian.vijay; +Cc: netdev, eric.dumazet
In-Reply-To: <1377825558-8800-1-git-send-email-subramanian.vijay@gmail.com>
From: Vijay Subramanian <subramanian.vijay@gmail.com>
Date: Thu, 29 Aug 2013 18:19:18 -0700
> After commit 0c24604b (tcp: implement RFC 5961 4.2), tcp_rcv_established() only
> returns 0 since we no longer send RSTs in response to SYNs. We can remove the
> check on the return value.
>
> Signed-off-by: Vijay Subramanian <subramanian.vijay@gmail.com>
Always returning the same value is the same as returning no value at all.
Make tcp_rcv_established() return void please.
^ permalink raw reply
* [PATCH net-next] tcp: Remove needless check of return value
From: Vijay Subramanian @ 2013-08-30 1:19 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, Vijay Subramanian
After commit 0c24604b (tcp: implement RFC 5961 4.2), tcp_rcv_established() only
returns 0 since we no longer send RSTs in response to SYNs. We can remove the
check on the return value.
Signed-off-by: Vijay Subramanian <subramanian.vijay@gmail.com>
---
net/ipv4/tcp_ipv4.c | 5 +----
net/ipv6/tcp_ipv6.c | 3 +--
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 09d45d7..b14266b 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1799,10 +1799,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
sk->sk_rx_dst = NULL;
}
}
- if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
- rsk = sk;
- goto reset;
- }
+ tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len);
return 0;
}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5bcfadf..9acdced 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1360,8 +1360,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
}
}
- if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len))
- goto reset;
+ tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len);
if (opt_skb)
goto ipv6_pktoptions;
return 0;
--
1.7.9.5
^ permalink raw reply related
* Re: [-next] openvswitch BUILD_BUG_ON failed
From: Jesse Gross @ 2013-08-30 1:11 UTC (permalink / raw)
To: David Miller
Cc: geert, Andy Zhou, dev@openvswitch.org, netdev,
Linux Kernel Mailing List, linux-next
In-Reply-To: <20130829.181001.145658561677052552.davem@davemloft.net>
On Thu, Aug 29, 2013 at 3:10 PM, David Miller <davem@davemloft.net> wrote:
> From: Jesse Gross <jesse@nicira.com>
> Date: Thu, 29 Aug 2013 14:42:22 -0700
>
>> On Thu, Aug 29, 2013 at 2:21 PM, Geert Uytterhoeven
>> <geert@linux-m68k.org> wrote:
>>> However, I have some doubts about other alignment "enforcements":
>>>
>>> "__aligned(__alignof__(long))" makes the whole struct aligned to the
>>> alignment rule for "long":
>>> 1. This is only 2 bytes on m68k, i.e. != sizeof(long).
>>> 2. This is 4 bytes on many 32-bit platforms, which may be less than the
>>> default alignment for "__be64" (cfr. some members of struct
>>> ovs_key_ipv4_tunnel), so this may make those 64-bit members unaligned.
>>
>> Do any of those 32-bit architectures actually care about alignment of
>> 64 bit values? On 32-bit x86, a long is 32 bits but the alignment
>> requirement of __be64 is also 32 bit.
>
> All except x86-32 do, it is in fact the odd man out with respect to this
> issue.
Thanks, good to know.
Andy, do you want to modify your patch to just drop the alignment
specification as Geert suggested (but definitely keep the new build
assert that you added)? It's probably better to just send the patch to
netdev (against net-next) as well since you'll likely get better
comments there and we can fix this faster if you cut out the
middleman.
^ permalink raw reply
* Re:Very Urgent!!!
From: Doris Omar @ 2013-08-30 0:55 UTC (permalink / raw)
Greetings from BURKINA FASO:
Let me start by introduce myself,I am Mrs Doris Omar, BILL AND EXCHANGE MANAGER (Bank of Africa) Ouagadougou, Burkina Faso.I am writting you this letter based on the latest development at our bank which I will like to bring to your personal edification. $12,250million transfer claims. this is a legitimate transaction and I agreed to offer you 40% of this money as my foreign partner after confirmation of the fund in your bank account,If you are interested, please get back to me for more clarification.
Yours faithful,
Mrs Doris Omar.
^ permalink raw reply
* Re: [PATCH net-next 1/2] sh_eth: Fix cache invalidation omission of receive buffer
From: Simon Horman @ 2013-08-30 0:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-sh, magnus.damm, sergei.shtylyov, kouei.abe.cp
In-Reply-To: <20130829.161553.755954777649764863.davem@davemloft.net>
On Thu, Aug 29, 2013 at 04:15:53PM -0400, David Miller wrote:
> From: Simon Horman <horms+renesas@verge.net.au>
> Date: Wed, 28 Aug 2013 09:43:08 +0900
>
> > From: Kouei Abe <kouei.abe.cp@renesas.com>
> >
> > Signed-off-by: Kouei Abe <kouei.abe.cp@renesas.com>
> > Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> > ---
> > drivers/net/ethernet/renesas/sh_eth.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
> > index c357076..f386a8f 100644
> > --- a/drivers/net/ethernet/renesas/sh_eth.c
> > +++ b/drivers/net/ethernet/renesas/sh_eth.c
> > @@ -1342,6 +1342,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
> > mdp->rx_skbuff[entry] = NULL;
> > if (mdp->cd->rpadir)
> > skb_reserve(skb, NET_IP_ALIGN);
> > + dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr,
> > + mdp->rx_buf_sz, DMA_FROM_DEVICE);
>
> Please indent the second line of the dma sync call properly.
>
> The arguments should start at the first column after the openning
> parenthesis of the function call on the first line, using the
> appropriate number of TAB then space characters (as needed).
Sorry for missing that. I'll fix it up and re-post.
^ permalink raw reply
* Re: [PATCH net-next v2] net: neighbour: Remove CONFIG_ARPD
From: Eric W. Biederman @ 2013-08-29 23:39 UTC (permalink / raw)
To: Tim Gardner
Cc: netdev, linux-kernel, David S. Miller, Alexey Kuznetsov,
James Morris, Hideaki YOSHIFUJI, Patrick McHardy, Gao feng,
Joe Perches, Veaceslav Falico
In-Reply-To: <1377779927-28500-1-git-send-email-tim.gardner@canonical.com>
Tim Gardner <tim.gardner@canonical.com> writes:
> This config option is superfluous in that it only guards a call
> to neigh_app_ns(). Enabling CONFIG_ARPD by default has no
> change in behavior. There will now be call to __neigh_notify()
> for each ARP resolution, which has no impact unless there is a
> user space daemon waiting to receive the notification, i.e.,
> the case for which CONFIG_ARPD was designed anyways.
This looks good to me, and much less magic to maintain.
Eric
> Suggested-by: Eric W. Biederman <ebiederm@xmission.com>
Reviewed-by: "Eric W. Biederman" <ebiederm@xmission.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
> Cc: James Morris <jmorris@namei.org>
> Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> Cc: Gao feng <gaofeng@cn.fujitsu.com>
> Cc: Joe Perches <joe@perches.com>
> Cc: Veaceslav Falico <vfalico@redhat.com>
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
>
> Eric's suggestion to simply remove the config option makes sense
> to me. If acceptable then I'll submit a patch series that also removes
> CONFIG_ARPD from the various arch defconfigs.
>
> net/core/neighbour.c | 2 --
> net/ipv4/Kconfig | 16 ----------------
> net/ipv4/arp.c | 2 --
> net/ipv6/ndisc.c | 2 --
> 4 files changed, 22 deletions(-)
>
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 60533db..6072610 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -2759,13 +2759,11 @@ errout:
> rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
> }
>
> -#ifdef CONFIG_ARPD
> void neigh_app_ns(struct neighbour *n)
> {
> __neigh_notify(n, RTM_GETNEIGH, NLM_F_REQUEST);
> }
> EXPORT_SYMBOL(neigh_app_ns);
> -#endif /* CONFIG_ARPD */
>
> #ifdef CONFIG_SYSCTL
> static int zero;
> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
> index 37cf1a6..05c57f0 100644
> --- a/net/ipv4/Kconfig
> +++ b/net/ipv4/Kconfig
> @@ -259,22 +259,6 @@ config IP_PIMSM_V2
> gated-5). This routing protocol is not used widely, so say N unless
> you want to play with it.
>
> -config ARPD
> - bool "IP: ARP daemon support"
> - ---help---
> - The kernel maintains an internal cache which maps IP addresses to
> - hardware addresses on the local network, so that Ethernet
> - frames are sent to the proper address on the physical networking
> - layer. Normally, kernel uses the ARP protocol to resolve these
> - mappings.
> -
> - Saying Y here adds support to have an user space daemon to do this
> - resolution instead. This is useful for implementing an alternate
> - address resolution protocol (e.g. NHRP on mGRE tunnels) and also for
> - testing purposes.
> -
> - If unsure, say N.
> -
> config SYN_COOKIES
> bool "IP: TCP syncookie support"
> ---help---
> diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> index 4429b01..7808093 100644
> --- a/net/ipv4/arp.c
> +++ b/net/ipv4/arp.c
> @@ -368,9 +368,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
> } else {
> probes -= neigh->parms->app_probes;
> if (probes < 0) {
> -#ifdef CONFIG_ARPD
> neigh_app_ns(neigh);
> -#endif
> return;
> }
> }
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index 04d31c2..d5693ad 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -663,9 +663,7 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
> }
> ndisc_send_ns(dev, neigh, target, target, saddr);
> } else if ((probes -= neigh->parms->app_probes) < 0) {
> -#ifdef CONFIG_ARPD
> neigh_app_ns(neigh);
> -#endif
> } else {
> addrconf_addr_solict_mult(target, &mcaddr);
> ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
^ permalink raw reply
* Re: [PATCH] USB2NET : SR9700 : One Chip USB 1.1 USB2NET SR9700 Device Driver Support
From: Francois Romieu @ 2013-08-29 23:06 UTC (permalink / raw)
To: liujunliang_ljl
Cc: davem, horms, joe, gregkh, netdev, linux-usb, linux-kernel,
sunhecheng
In-Reply-To: <1377746832-6201-1-git-send-email-liujunliang_ljl@163.com>
Keep it small though literate.
---
drivers/net/usb/sr9700.c | 30 ++++++++++++------------------
1 file changed, 12 insertions(+), 18 deletions(-)
diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
index f7f46e6..3f05b35 100644
--- a/drivers/net/usb/sr9700.c
+++ b/drivers/net/usb/sr9700.c
@@ -71,31 +71,25 @@ static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
static int wait_phy_eeprom_ready(struct usbnet *dev, int phy)
{
- int i, ret;
+ int i;
- ret = 0;
for (i = 0; i < SR_SHARE_TIMEOUT; i++) {
u8 tmp = 0;
+ int ret;
udelay(1);
ret = sr_read_reg(dev, EPCR, &tmp);
if (ret < 0)
- goto out;
+ return ret;
/* ready */
- if ((tmp & EPCR_ERRE) == 0)
- break;
+ if (!(tmp & EPCR_ERRE))
+ return 0;
}
- if (i >= SR_SHARE_TIMEOUT) {
- netdev_err(dev->net, "%s write timed out!\n",
- phy ? "phy" : "eeprom");
- ret = -EIO;
- goto out;
- }
+ netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom");
-out:
- return ret;
+ return -EIO;
}
static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg,
@@ -110,7 +104,7 @@ static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg,
ret = wait_phy_eeprom_ready(dev, phy);
if (ret < 0)
- goto out;
+ goto out_unlock;
sr_write_reg(dev, EPCR, 0x0);
ret = sr_read(dev, EPDR, 2, value);
@@ -118,7 +112,7 @@ static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg,
netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
phy, reg, *value, ret);
-out:
+out_unlock:
mutex_unlock(&dev->phy_mutex);
return ret;
}
@@ -132,18 +126,18 @@ static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg,
ret = sr_write(dev, EPDR, 2, &value);
if (ret < 0)
- goto out;
+ goto out_unlock;
sr_write_reg(dev, EPAR, phy ? (reg | 0x40) : reg);
sr_write_reg(dev, EPCR, phy ? 0x1a : 0x12);
ret = wait_phy_eeprom_ready(dev, phy);
if (ret < 0)
- goto out;
+ goto out_unlock;
sr_write_reg(dev, EPCR, 0x0);
-out:
+out_unlock:
mutex_unlock(&dev->phy_mutex);
return ret;
}
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] USB2NET : SR9700 : One Chip USB 1.1 USB2NET SR9700 Device Driver Support
From: Francois Romieu @ 2013-08-29 23:06 UTC (permalink / raw)
To: liujunliang_ljl
Cc: davem, horms, joe, gregkh, netdev, linux-usb, linux-kernel,
sunhecheng
In-Reply-To: <1377746832-6201-1-git-send-email-liujunliang_ljl@163.com>
Liu, please check those.
---
drivers/net/usb/sr9700.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
index 3f05b35..3ae3caf 100644
--- a/drivers/net/usb/sr9700.c
+++ b/drivers/net/usb/sr9700.c
@@ -99,8 +99,9 @@ static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg,
mutex_lock(&dev->phy_mutex);
+ // FIXME: the mistery 0x40 appears in sr_share_write_word as well.
sr_write_reg(dev, EPAR, phy ? (reg | 0x40) : reg);
- sr_write_reg(dev, EPCR, phy ? 0xc : 0x4);
+ sr_write_reg(dev, EPCR, phy ? (EPCR_EPOS | EPCR_ERPRR) : EPCR_ERPRR);
ret = wait_phy_eeprom_ready(dev, phy);
if (ret < 0)
@@ -128,7 +129,10 @@ static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg,
if (ret < 0)
goto out_unlock;
+ // FIXME: see sr_share_read_word above.
sr_write_reg(dev, EPAR, phy ? (reg | 0x40) : reg);
+ // 0x1a -> EPCR_WEP | EPCR_EPOS | EPCR_ERPRW ?
+ // 0x12 -> EPCR_WEP | EPCR_ERPRW ?
sr_write_reg(dev, EPCR, phy ? 0x1a : 0x12);
ret = wait_phy_eeprom_ready(dev, phy);
--
1.8.3.1
^ permalink raw reply related
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