* Re: [PATCH net-next] net: napi_frags_skb() is static
From: David Miller @ 2012-05-19 6:51 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1337410146.7029.71.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 19 May 2012 08:49:06 +0200
> From: Eric Dumazet <edumazet@google.com>
>
> No need to export napi_frags_skb()
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied.
^ permalink raw reply
* [PATCH net-next] tg3: use netdev_alloc_frag() API
From: Eric Dumazet @ 2012-05-19 7:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Matt Carlson, Michael Chan
From: Eric Dumazet <edumazet@google.com>
Update our reference driver to use netdev_alloc_frag() API instead of
the temporary custom allocator I introduced in commit 8d4057a938
(tg3: provide frags as skb head)
This removes the memory leak we had, since we could leak one page at
device dismantle.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Matt Carlson <mcarlson@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 38 +++-----------------------
drivers/net/ethernet/broadcom/tg3.h | 2 -
2 files changed, 5 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 4230e70..d55df32 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -195,15 +195,6 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
#define TG3_RX_OFFSET(tp) (NET_SKB_PAD)
#endif
-/* This driver uses the new build_skb() API providing a frag as skb->head
- * This strategy permits better GRO aggregation, better TCP coalescing, and
- * better splice() implementation (avoids a copy from head to a page), at
- * minimal memory cost.
- * In this 2048 bytes block, we have enough room to store the MTU=1500 frame
- * and the struct skb_shared_info.
- */
-#define TG3_FRAGSIZE 2048
-
/* minimum number of free TX descriptors required to wake up TX process */
#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4)
#define TG3_TX_BD_DMA_MAX_2K 2048
@@ -5631,25 +5622,6 @@ static void tg3_tx(struct tg3_napi *tnapi)
}
}
-static void *tg3_frag_alloc(struct tg3_rx_prodring_set *tpr)
-{
- void *data;
-
- if (tpr->rx_page_size < TG3_FRAGSIZE) {
- struct page *page = alloc_page(GFP_ATOMIC);
-
- if (!page)
- return NULL;
- atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count);
- tpr->rx_page_addr = page_address(page);
- tpr->rx_page_size = PAGE_SIZE;
- }
- data = tpr->rx_page_addr;
- tpr->rx_page_addr += TG3_FRAGSIZE;
- tpr->rx_page_size -= TG3_FRAGSIZE;
- return data;
-}
-
static void tg3_frag_free(bool is_frag, void *data)
{
if (is_frag)
@@ -5668,7 +5640,7 @@ static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping),
map_sz, PCI_DMA_FROMDEVICE);
- tg3_frag_free(skb_size <= TG3_FRAGSIZE, ri->data);
+ tg3_frag_free(skb_size <= PAGE_SIZE, ri->data);
ri->data = NULL;
}
@@ -5721,9 +5693,9 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
*/
skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) +
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
- if (skb_size <= TG3_FRAGSIZE) {
- data = tg3_frag_alloc(tpr);
- *frag_size = TG3_FRAGSIZE;
+ if (skb_size <= PAGE_SIZE) {
+ data = netdev_alloc_frag(skb_size);
+ *frag_size = skb_size;
} else {
data = kmalloc(skb_size, GFP_ATOMIC);
*frag_size = 0;
@@ -5736,7 +5708,7 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
data_size,
PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(tp->pdev, mapping))) {
- tg3_frag_free(skb_size <= TG3_FRAGSIZE, data);
+ tg3_frag_free(skb_size <= PAGE_SIZE, data);
return -EIO;
}
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 7c85545..93865f8 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2815,8 +2815,6 @@ struct tg3_rx_prodring_set {
struct ring_info *rx_jmb_buffers;
dma_addr_t rx_std_mapping;
dma_addr_t rx_jmb_mapping;
- void *rx_page_addr;
- unsigned int rx_page_size;
};
#define TG3_IRQ_MAX_VECS_RSS 5
^ permalink raw reply related
* Re: [PATCH net-next] tg3: use netdev_alloc_frag() API
From: David Miller @ 2012-05-19 7:19 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, mcarlson, mchan
In-Reply-To: <1337411749.7029.77.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 19 May 2012 09:15:49 +0200
> From: Eric Dumazet <edumazet@google.com>
>
> Update our reference driver to use netdev_alloc_frag() API instead of
> the temporary custom allocator I introduced in commit 8d4057a938
> (tg3: provide frags as skb head)
>
> This removes the memory leak we had, since we could leak one page at
> device dismantle.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Hmmm, doesn't apply cleanly to net-next for some reason:
[davem@drr net-next]$ git am --signoff net-next-tg3-use-netdev_alloc_frag-API.patch
Applying: tg3: use netdev_alloc_frag() API
error: patch failed: drivers/net/ethernet/broadcom/tg3.c:5631
error: drivers/net/ethernet/broadcom/tg3.c: patch does not apply
Patch failed at 0001 tg3: use netdev_alloc_frag() API
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".
^ permalink raw reply
* Re: [PATCH net-next] tg3: use netdev_alloc_frag() API
From: Eric Dumazet @ 2012-05-19 7:31 UTC (permalink / raw)
To: David Miller; +Cc: netdev, mcarlson, mchan
In-Reply-To: <20120519.031914.1744866102736414778.davem@davemloft.net>
On Sat, 2012-05-19 at 03:19 -0400, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Sat, 19 May 2012 09:15:49 +0200
>
> > From: Eric Dumazet <edumazet@google.com>
> >
> > Update our reference driver to use netdev_alloc_frag() API instead of
> > the temporary custom allocator I introduced in commit 8d4057a938
> > (tg3: provide frags as skb head)
> >
> > This removes the memory leak we had, since we could leak one page at
> > device dismantle.
> >
> > Signed-off-by: Eric Dumazet <edumazet@google.com>
>
> Hmmm, doesn't apply cleanly to net-next for some reason:
>
> [davem@drr net-next]$ git am --signoff net-next-tg3-use-netdev_alloc_frag-API.patch
> Applying: tg3: use netdev_alloc_frag() API
> error: patch failed: drivers/net/ethernet/broadcom/tg3.c:5631
> error: drivers/net/ethernet/broadcom/tg3.c: patch does not apply
> Patch failed at 0001 tg3: use netdev_alloc_frag() API
> When you have resolved this problem run "git am --resolved".
> If you would prefer to skip this patch, instead run "git am --skip".
> To restore the original branch and stop patching run "git am --abort".
Indeed, there is an extra space at the end of one line in my tree... ???
atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count); <HERE>
I submit a v2 immediately.
Sorry
^ permalink raw reply
* [PATCH v2 net-next] tg3: use netdev_alloc_frag() API
From: Eric Dumazet @ 2012-05-19 7:33 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Matt Carlson, Michael Chan
In-Reply-To: <1337411749.7029.77.camel@edumazet-glaptop>
From: Eric Dumazet <edumazet@google.com>
Update our reference driver to use netdev_alloc_frag() API instead of
the temporary custom allocator I introduced in commit 8d4057a938
(tg3: provide frags as skb head)
This removes the memory leak we had, since we could leak one page at
device dismantle.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Matt Carlson <mcarlson@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 38 +++-----------------------
drivers/net/ethernet/broadcom/tg3.h | 2 -
2 files changed, 5 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 39b92f5..d55df32 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -195,15 +195,6 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
#define TG3_RX_OFFSET(tp) (NET_SKB_PAD)
#endif
-/* This driver uses the new build_skb() API providing a frag as skb->head
- * This strategy permits better GRO aggregation, better TCP coalescing, and
- * better splice() implementation (avoids a copy from head to a page), at
- * minimal memory cost.
- * In this 2048 bytes block, we have enough room to store the MTU=1500 frame
- * and the struct skb_shared_info.
- */
-#define TG3_FRAGSIZE 2048
-
/* minimum number of free TX descriptors required to wake up TX process */
#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4)
#define TG3_TX_BD_DMA_MAX_2K 2048
@@ -5631,25 +5622,6 @@ static void tg3_tx(struct tg3_napi *tnapi)
}
}
-static void *tg3_frag_alloc(struct tg3_rx_prodring_set *tpr)
-{
- void *data;
-
- if (tpr->rx_page_size < TG3_FRAGSIZE) {
- struct page *page = alloc_page(GFP_ATOMIC);
-
- if (!page)
- return NULL;
- atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count);
- tpr->rx_page_addr = page_address(page);
- tpr->rx_page_size = PAGE_SIZE;
- }
- data = tpr->rx_page_addr;
- tpr->rx_page_addr += TG3_FRAGSIZE;
- tpr->rx_page_size -= TG3_FRAGSIZE;
- return data;
-}
-
static void tg3_frag_free(bool is_frag, void *data)
{
if (is_frag)
@@ -5668,7 +5640,7 @@ static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping),
map_sz, PCI_DMA_FROMDEVICE);
- tg3_frag_free(skb_size <= TG3_FRAGSIZE, ri->data);
+ tg3_frag_free(skb_size <= PAGE_SIZE, ri->data);
ri->data = NULL;
}
@@ -5721,9 +5693,9 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
*/
skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) +
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
- if (skb_size <= TG3_FRAGSIZE) {
- data = tg3_frag_alloc(tpr);
- *frag_size = TG3_FRAGSIZE;
+ if (skb_size <= PAGE_SIZE) {
+ data = netdev_alloc_frag(skb_size);
+ *frag_size = skb_size;
} else {
data = kmalloc(skb_size, GFP_ATOMIC);
*frag_size = 0;
@@ -5736,7 +5708,7 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
data_size,
PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(tp->pdev, mapping))) {
- tg3_frag_free(skb_size <= TG3_FRAGSIZE, data);
+ tg3_frag_free(skb_size <= PAGE_SIZE, data);
return -EIO;
}
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 7c85545..93865f8 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2815,8 +2815,6 @@ struct tg3_rx_prodring_set {
struct ring_info *rx_jmb_buffers;
dma_addr_t rx_std_mapping;
dma_addr_t rx_jmb_mapping;
- void *rx_page_addr;
- unsigned int rx_page_size;
};
#define TG3_IRQ_MAX_VECS_RSS 5
^ permalink raw reply related
* [PATCH net-next] ipv6: disable GSO on sockets hitting dst_allfrag
From: Eric Dumazet @ 2012-05-19 7:51 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Tore Anderson
From: Eric Dumazet <edumazet@google.com>
If the allfrag feature has been set on a host route (due to an ICMPv6
Packet Too Big received indicating a MTU of less than 1280), we hit a
very slow behavior in TCP stack, because all big packets are dropped and
only a retransmit timer is able to push one MSS frame every 200 ms.
One way to handle this is to disable GSO on the socket the first time a
super packet is dropped. Adding a specific dst_allfrag() in the fast
path is probably overkill since the dst_allfrag() case almost never
happen.
Result on netperf TCP_STREAM, one flow :
Before : 60 kbit/sec
After : 1.6 Gbit/sec
Reported-by: Tore Anderson <tore@fud.no>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Tested-by: Tore Anderson <tore@fud.no>
---
Sorry for the delay, thanks Tore for the gentle reminders ;)
( http://thread.gmane.org/gmane.linux.network/217998/focus=218080 )
net/ipv6/ip6_output.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 3dc633f..d99fdc6 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -643,7 +643,10 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
/* We must not fragment if the socket is set to force MTU discovery
* or if the skb it not generated by a local socket.
*/
- if (!skb->local_df && skb->len > mtu) {
+ if (unlikely(!skb->local_df && skb->len > mtu)) {
+ if (skb->sk && dst_allfrag(skb_dst(skb)))
+ sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK);
+
skb->dev = skb_dst(skb)->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
^ permalink raw reply related
* Re: [PATCH net-next] tg3: use netdev_alloc_frag() API
From: David Miller @ 2012-05-19 8:01 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, mcarlson, mchan
In-Reply-To: <1337412701.7029.79.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 19 May 2012 09:31:41 +0200
> Indeed, there is an extra space at the end of one line in my tree... ???
>
> atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count); <HERE>
I silently fix trailing whitespace errors in your patches.
^ permalink raw reply
* Re: [PATCH v2 net-next] tg3: use netdev_alloc_frag() API
From: David Miller @ 2012-05-19 8:03 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, mcarlson, mchan
In-Reply-To: <1337412819.7029.81.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 19 May 2012 09:33:39 +0200
> From: Eric Dumazet <edumazet@google.com>
>
> Update our reference driver to use netdev_alloc_frag() API instead of
> the temporary custom allocator I introduced in commit 8d4057a938
> (tg3: provide frags as skb head)
>
> This removes the memory leak we had, since we could leak one page at
> device dismantle.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] ipv6: disable GSO on sockets hitting dst_allfrag
From: David Miller @ 2012-05-19 8:03 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, tore
In-Reply-To: <1337413904.7029.93.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 19 May 2012 09:51:44 +0200
> From: Eric Dumazet <edumazet@google.com>
>
> If the allfrag feature has been set on a host route (due to an ICMPv6
> Packet Too Big received indicating a MTU of less than 1280), we hit a
> very slow behavior in TCP stack, because all big packets are dropped and
> only a retransmit timer is able to push one MSS frame every 200 ms.
>
> One way to handle this is to disable GSO on the socket the first time a
> super packet is dropped. Adding a specific dst_allfrag() in the fast
> path is probably overkill since the dst_allfrag() case almost never
> happen.
>
> Result on netperf TCP_STREAM, one flow :
>
> Before : 60 kbit/sec
> After : 1.6 Gbit/sec
>
> Reported-by: Tore Anderson <tore@fud.no>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Tested-by: Tore Anderson <tore@fud.no>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] tg3: use netdev_alloc_frag() API
From: Eric Dumazet @ 2012-05-19 8:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, mcarlson, mchan
In-Reply-To: <20120519.040101.508727755785767140.davem@davemloft.net>
On Sat, 2012-05-19 at 04:01 -0400, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Sat, 19 May 2012 09:31:41 +0200
>
> > Indeed, there is an extra space at the end of one line in my tree... ???
> >
> > atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count); <HERE>
>
> I silently fix trailing whitespace errors in your patches.
OK, good to know ;)
^ permalink raw reply
* Re: [PATCH net-next] drivers/net: delete old 8bit ISA 3c501 driver.
From: Ondrej Zary @ 2012-05-19 8:58 UTC (permalink / raw)
To: Paul Gortmaker; +Cc: davem, netdev, Alan Cox
In-Reply-To: <20120518220305.GC15256@windriver.com>
On Saturday 19 May 2012 00:03:06 Paul Gortmaker wrote:
> [Re: [PATCH net-next] drivers/net: delete old 8bit ISA 3c501 driver.] On
18/05/2012 (Fri 20:16) Ondrej Zary wrote:
> > On Friday 18 May 2012 19:39:29 Paul Gortmaker wrote:
> > > It was amusing that linux was able to make use of this 1980's
> > > technology on machines long past its intended lifespan, but
> > > it probably should go now -- it is causing issues in some
> > > distros[1], and while that might be fixable, it is just not
> > > worth it.
> > >
> > > [1]
> > > http://www.linuxquestions.org/questions/linux-networking-3/3com-3c501-c
> > >ard- not-detecting-934344/
> >
> > That looks like a bug elsewhere and removing this driver will not fix it.
>
> You miss the point. We've got someone with a modern i7 machine who is
> getting confused by seeing messages from some ancient 3c501 driver, but
> he doesn't have the context to know it is ancient and the message is a
> red herring. Will it fix a distro's broken init that tries to modprobe
> everything? No. Will it help by not muddying the waters with
> meaningless printk from 3c501 that confuse users? Yes.
Are you going to remove all drivers that complain that the HW is not present
because some broken script is trying to modprobe them all? Or only the first
one? 3c501 is probably the first in alphabet. You remove that and the script
will modprobe 3c503 then...
--
Ondrej Zary
^ permalink raw reply
* [PATCH] net : fix for dst_gc_task not getting scheduled if __dst_free() is called consistently
From: rajan.gupta @ 2012-05-19 9:39 UTC (permalink / raw)
To: "netdev; +Cc: Rajan Gupta
From: Rajan Gupta <rajan.gupta@freescale.com>
dst_gc_work is cancelled and again rescheduled in __ds_free(). In case
__dsf_free() is consistently called dst_gc_work will never get called resulting in
memory not getting freed at all until one stops calling __dst_free
Signed-off-by: Rajan Gupta <rajan.gupta@freescale.com>
---
net/core/dst.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/core/dst.c b/net/core/dst.c
index 8246d47..6820206 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -215,7 +215,6 @@ void __dst_free(struct dst_entry *dst)
if (dst_garbage.timer_inc > DST_GC_INC) {
dst_garbage.timer_inc = DST_GC_INC;
dst_garbage.timer_expires = DST_GC_MIN;
- cancel_delayed_work(&dst_gc_work);
schedule_delayed_work(&dst_gc_work, dst_garbage.timer_expires);
}
spin_unlock_bh(&dst_garbage.lock);
--
1.7.9.5
^ permalink raw reply related
* [PATCH] net : fix for dst_gc_task not getting scheduled if __dst_free() is called consistently
From: rajan.gupta @ 2012-05-19 9:41 UTC (permalink / raw)
To: netdev, kuznet; +Cc: Rajan Gupta
From: Rajan Gupta <rajan.gupta@freescale.com>
dst_gc_work is cancelled and again rescheduled in __ds_free(). In case
__dsf_free() is consistently called dst_gc_work will never get called resulting in
memory not getting freed at all until one stops calling __dst_free
Signed-off-by: Rajan Gupta <rajan.gupta@freescale.com>
---
net/core/dst.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/core/dst.c b/net/core/dst.c
index 8246d47..6820206 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -215,7 +215,6 @@ void __dst_free(struct dst_entry *dst)
if (dst_garbage.timer_inc > DST_GC_INC) {
dst_garbage.timer_inc = DST_GC_INC;
dst_garbage.timer_expires = DST_GC_MIN;
- cancel_delayed_work(&dst_gc_work);
schedule_delayed_work(&dst_gc_work, dst_garbage.timer_expires);
}
spin_unlock_bh(&dst_garbage.lock);
--
1.7.9.5
^ permalink raw reply related
* [PATCH] net : fix for dst_gc_task not getting scheduled if __dst_free() is called consistently
From: b15745 @ 2012-05-19 9:44 UTC (permalink / raw)
To: netdev; +Cc: Rajan Gupta
From: Rajan Gupta <b15745@freescale.com>
dst_gc_work is cancelled and again rescheduled in __ds_free(). In case
__dsf_free() is consistently called dst_gc_work will never get called resulting in
memory not getting freed at all until one stops calling __dst_free
Signed-off-by: Rajan Gupta <b15745@freescale.com>
---
net/core/dst.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/core/dst.c b/net/core/dst.c
index 8246d47..6820206 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -215,7 +215,6 @@ void __dst_free(struct dst_entry *dst)
if (dst_garbage.timer_inc > DST_GC_INC) {
dst_garbage.timer_inc = DST_GC_INC;
dst_garbage.timer_expires = DST_GC_MIN;
- cancel_delayed_work(&dst_gc_work);
schedule_delayed_work(&dst_gc_work, dst_garbage.timer_expires);
}
spin_unlock_bh(&dst_garbage.lock);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] net : fix for dst_gc_task not getting scheduled if __dst_free() is called consistently
From: Eric Dumazet @ 2012-05-19 10:04 UTC (permalink / raw)
To: b15745; +Cc: netdev
In-Reply-To: <1337420654-28200-1-git-send-email-b15745@freescale.com>
On Sat, 2012-05-19 at 04:44 -0500, b15745@freescale.com wrote:
> From: Rajan Gupta <b15745@freescale.com>
>
> dst_gc_work is cancelled and again rescheduled in __ds_free(). In case
> __dsf_free() is consistently called dst_gc_work will never get called resulting in
> memory not getting freed at all until one stops calling __dst_free
> Signed-off-by: Rajan Gupta <b15745@freescale.com>
> ---
> net/core/dst.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/net/core/dst.c b/net/core/dst.c
> index 8246d47..6820206 100644
> --- a/net/core/dst.c
> +++ b/net/core/dst.c
> @@ -215,7 +215,6 @@ void __dst_free(struct dst_entry *dst)
> if (dst_garbage.timer_inc > DST_GC_INC) {
> dst_garbage.timer_inc = DST_GC_INC;
> dst_garbage.timer_expires = DST_GC_MIN;
> - cancel_delayed_work(&dst_gc_work);
> schedule_delayed_work(&dst_gc_work, dst_garbage.timer_expires);
> }
> spin_unlock_bh(&dst_garbage.lock);
Strange, I never met this....
Since "if (dst_garbage.timer_inc > DST_GC_INC)" will be false if
timer_inc is DST_GC_INC.
^ permalink raw reply
* Hello
From: ''Dr. Ma Weihua'' @ 2012-05-19 10:36 UTC (permalink / raw)
To: Recipients
Hello to you,
My letter may come to you as a surprise but I had to contact you in this manner due to the importance and urgent business situation I have at hand. I need you as a partner in a lucratice business which involve the transfer of $32,500,000.00 U.S Dollars from China to your country. We shall share in a ratio to be agreed by both of us when the deal is completed. Please reply for more information if you are interested in doing business with me and also getting to know each other better before proceeding.
Kind Regards,
Dr. Ma Weihua
^ permalink raw reply
* [PATCH 1/1] net:ipv6:fixed a trailing white space issue.
From: Jeffrin Jose @ 2012-05-19 11:45 UTC (permalink / raw)
To: davem, kuznet, jmorris, yoshfuji, kaber; +Cc: netdev, linux-kernel, ahiliation
Fixed a trailing white space issue found by
checkpatch.pl tool in net/ipv6/udp.c
Signed-off-by: Jeffrin Jose <ahiliation@yahoo.co.in>
---
net/ipv6/udp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index c1d91a7..847253c 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -103,7 +103,7 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum)
{
unsigned int hash2_nulladdr =
udp6_portaddr_hash(sock_net(sk), &in6addr_any, snum);
- unsigned int hash2_partial =
+ unsigned int hash2_partial =
udp6_portaddr_hash(sock_net(sk), &inet6_sk(sk)->rcv_saddr, 0);
/* precompute partial secondary hash */
--
1.7.10
^ permalink raw reply related
* [PATCH 1/1] net:ipv6:fixed space issues relating to operators.
From: Jeffrin Jose @ 2012-05-19 11:59 UTC (permalink / raw)
To: davem, kuznet, jmorris, yoshfuji, kaber; +Cc: netdev, linux-kernel, ahiliation
Fixed space issues relating to operators found by
checkpatch.pl tool in net/ipv6/udp.c
Signed-off-by: Jeffrin Jose <ahiliation@yahoo.co.in>
---
net/ipv6/udp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 847253c..f05099f 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -349,7 +349,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
bool slow;
if (addr_len)
- *addr_len=sizeof(struct sockaddr_in6);
+ *addr_len = sizeof(struct sockaddr_in6);
if (flags & MSG_ERRQUEUE)
return ipv6_recv_error(sk, msg, len);
@@ -1379,7 +1379,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
* do checksum of UDP packets sent as multiple IP fragments.
*/
offset = skb_checksum_start_offset(skb);
- csum = skb_checksum(skb, offset, skb->len- offset, 0);
+ csum = skb_checksum(skb, offset, skb->len - offset, 0);
offset += skb->csum_offset;
*(__sum16 *)(skb->data + offset) = csum_fold(csum);
skb->ip_summed = CHECKSUM_NONE;
--
1.7.10
^ permalink raw reply related
* Re: [PATCH net-next] drivers/net: delete old 8bit ISA 3c501 driver.
From: Alan Cox @ 2012-05-19 12:30 UTC (permalink / raw)
To: Paul Gortmaker; +Cc: Ondrej Zary, davem, netdev
In-Reply-To: <20120518220305.GC15256@windriver.com>
> You miss the point. We've got someone with a modern i7 machine who is
> getting confused by seeing messages from some ancient 3c501 driver,
> but he doesn't have the context to know it is ancient and the message
> is a red herring. Will it fix a distro's broken init that tries to
> modprobe everything? No. Will it help by not muddying the waters
> with meaningless printk from 3c501 that confuse users? Yes.
That seems a totally bogus reason for removing stuff. The kernel cannot
manage every possible distribution and user screw up. They have more
variety so they will always win the battle.
Removing it because nobody is running one even in a museum might be a
good reason, but then the driver still works fine.
Also btw: the 3c501 isn't all TTL it's integrated. The 3c500 is all TTL
and an amazing beast, its so big it won't fit a 16bit slot as it has to
drop down after the connector to get all the chips on.
(and yes I have a 3c500)
However I don't think this is the right way to tackle the ethernet
history situation. As with MCA we should pull *all* the real historical
interest only bits in one go so it's immediately obvious where the
break point is for all devices.
That or we'll replace confused distros and uses with confused ancient
machine owners, and the latter can be far more persistent and
irritating ;)
So should we dump ISA ?
Alan
^ permalink raw reply
* Re: [PATCH net-next] drivers/net: delete old 8bit ISA 3c501 driver.
From: Alan Cox @ 2012-05-19 12:31 UTC (permalink / raw)
To: David Miller; +Cc: paul.gortmaker, netdev
In-Reply-To: <20120518.235420.1669350688913610319.davem@davemloft.net>
> > http://www.linuxquestions.org/questions/linux-networking-3/3com-3c501-card-not-detecting-934344/
> >
> > Cc: Alan Cox <alan@linux.intel.com>
> > Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
>
> Alan, any objections?
Wrong reason to remove it, Perfectly reasonable it (and a pile of other
ISA cards) ought to be shown the door.
Check with the M68K people however. 3c501 won't matter to them but I'm
not sure which of the other chips ended up on Amiga ISA bridges. I know
NE2000 clones did.
^ permalink raw reply
* [PATCH net-next 1/3] net: introduce skb_try_coalesce()
From: Eric Dumazet @ 2012-05-19 13:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Alexander Duyck
From: Eric Dumazet <edumazet@google.com>
Move tcp_try_coalesce() protocol independent part to
skb_try_coalesce().
skb_try_coalesce() can be used in IPv4 defrag and IPv6 reassembly,
to build optimized skbs (less sk_buff, and possibly less 'headers')
skb_try_coalesce() is zero copy, unless the copy can fit in destination
header (its a rare case)
kfree_skb_partial() is also moved to net/core/skbuff.c and exported,
because IPv6 will need it in patch (ipv6: use skb coalescing in
reassembly).
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Alexander Duyck <alexander.h.duyck@intel.com>
---
include/linux/skbuff.h | 5 ++
net/core/skbuff.c | 86 +++++++++++++++++++++++++++++++++++++++
net/ipv4/tcp_input.c | 67 +-----------------------------
3 files changed, 94 insertions(+), 64 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index fe37c21..0e50171 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -562,6 +562,11 @@ extern void kfree_skb(struct sk_buff *skb);
extern void consume_skb(struct sk_buff *skb);
extern void __kfree_skb(struct sk_buff *skb);
extern struct kmem_cache *skbuff_head_cache;
+
+extern void kfree_skb_partial(struct sk_buff *skb, bool head_stolen);
+extern bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
+ bool *fragstolen, int *delta_truesize);
+
extern struct sk_buff *__alloc_skb(unsigned int size,
gfp_t priority, int fclone, int node);
extern struct sk_buff *build_skb(void *data, unsigned int frag_size);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 7ceb673..ba8a470 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3346,3 +3346,89 @@ void __skb_warn_lro_forwarding(const struct sk_buff *skb)
skb->dev->name);
}
EXPORT_SYMBOL(__skb_warn_lro_forwarding);
+
+void kfree_skb_partial(struct sk_buff *skb, bool head_stolen)
+{
+ if (head_stolen)
+ kmem_cache_free(skbuff_head_cache, skb);
+ else
+ __kfree_skb(skb);
+}
+EXPORT_SYMBOL(kfree_skb_partial);
+
+/**
+ * skb_try_coalesce - try to merge skb to prior one
+ * @to: prior buffer
+ * @from: buffer to add
+ * @fragstolen: pointer to boolean
+ *
+ */
+bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
+ bool *fragstolen, int *delta_truesize)
+{
+ int i, delta, len = from->len;
+
+ *fragstolen = false;
+
+ if (skb_cloned(to))
+ return false;
+
+ if (len <= skb_tailroom(to)) {
+ BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len));
+ *delta_truesize = 0;
+ return true;
+ }
+
+ if (skb_has_frag_list(to) || skb_has_frag_list(from))
+ return false;
+
+ if (skb_headlen(from) != 0) {
+ struct page *page;
+ unsigned int offset;
+
+ if (skb_shinfo(to)->nr_frags +
+ skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS)
+ return false;
+
+ if (skb_head_is_locked(from))
+ return false;
+
+ delta = from->truesize - SKB_DATA_ALIGN(sizeof(struct sk_buff));
+
+ page = virt_to_head_page(from->head);
+ offset = from->data - (unsigned char *)page_address(page);
+
+ skb_fill_page_desc(to, skb_shinfo(to)->nr_frags,
+ page, offset, skb_headlen(from));
+ *fragstolen = true;
+ } else {
+ if (skb_shinfo(to)->nr_frags +
+ skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS)
+ return false;
+
+ delta = from->truesize -
+ SKB_TRUESIZE(skb_end_pointer(from) - from->head);
+ }
+
+ WARN_ON_ONCE(delta < len);
+
+ memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags,
+ skb_shinfo(from)->frags,
+ skb_shinfo(from)->nr_frags * sizeof(skb_frag_t));
+ skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags;
+
+ if (!skb_cloned(from))
+ skb_shinfo(from)->nr_frags = 0;
+
+ /* if the skb is cloned this does nothing since we set nr_frags to 0 */
+ for (i = 0; i < skb_shinfo(from)->nr_frags; i++)
+ skb_frag_ref(from, i);
+
+ to->truesize += delta;
+ to->len += len;
+ to->data_len += len;
+
+ *delta_truesize = delta;
+ return true;
+}
+EXPORT_SYMBOL(skb_try_coalesce);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b961ef5..cfa2aa1 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4549,84 +4549,23 @@ static bool tcp_try_coalesce(struct sock *sk,
struct sk_buff *from,
bool *fragstolen)
{
- int i, delta, len = from->len;
+ int delta;
*fragstolen = false;
- if (tcp_hdr(from)->fin || skb_cloned(to))
+ if (tcp_hdr(from)->fin)
return false;
-
- if (len <= skb_tailroom(to)) {
- BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len));
- goto merge;
- }
-
- if (skb_has_frag_list(to) || skb_has_frag_list(from))
+ if (!skb_try_coalesce(to, from, fragstolen, &delta))
return false;
- if (skb_headlen(from) != 0) {
- struct page *page;
- unsigned int offset;
-
- if (skb_shinfo(to)->nr_frags +
- skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS)
- return false;
-
- if (skb_head_is_locked(from))
- return false;
-
- delta = from->truesize - SKB_DATA_ALIGN(sizeof(struct sk_buff));
-
- page = virt_to_head_page(from->head);
- offset = from->data - (unsigned char *)page_address(page);
-
- skb_fill_page_desc(to, skb_shinfo(to)->nr_frags,
- page, offset, skb_headlen(from));
- *fragstolen = true;
- } else {
- if (skb_shinfo(to)->nr_frags +
- skb_shinfo(from)->nr_frags > MAX_SKB_FRAGS)
- return false;
-
- delta = from->truesize -
- SKB_TRUESIZE(skb_end_pointer(from) - from->head);
- }
-
- WARN_ON_ONCE(delta < len);
-
- memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags,
- skb_shinfo(from)->frags,
- skb_shinfo(from)->nr_frags * sizeof(skb_frag_t));
- skb_shinfo(to)->nr_frags += skb_shinfo(from)->nr_frags;
-
- if (!skb_cloned(from))
- skb_shinfo(from)->nr_frags = 0;
-
- /* if the skb is cloned this does nothing since we set nr_frags to 0 */
- for (i = 0; i < skb_shinfo(from)->nr_frags; i++)
- skb_frag_ref(from, i);
-
- to->truesize += delta;
atomic_add(delta, &sk->sk_rmem_alloc);
sk_mem_charge(sk, delta);
- to->len += len;
- to->data_len += len;
-
-merge:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOALESCE);
TCP_SKB_CB(to)->end_seq = TCP_SKB_CB(from)->end_seq;
TCP_SKB_CB(to)->ack_seq = TCP_SKB_CB(from)->ack_seq;
return true;
}
-static void kfree_skb_partial(struct sk_buff *skb, bool head_stolen)
-{
- if (head_stolen)
- kmem_cache_free(skbuff_head_cache, skb);
- else
- __kfree_skb(skb);
-}
-
static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
{
struct tcp_sock *tp = tcp_sk(sk);
^ permalink raw reply related
* [PATCH net-next 2/3] ipv4: use skb coalescing in defragmentation
From: Eric Dumazet @ 2012-05-19 13:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Alexander Duyck
From: Eric Dumazet <edumazet@google.com>
ip_frag_reasm() can use skb_try_coalesce() to build optimized skb,
reducing memory used by them (truesize), and reducing number of cache
line misses and overhead for the consumer.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Alexander Duyck <alexander.h.duyck@intel.com>
---
net/ipv4/ip_fragment.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 695b27f..9dbd3dd 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -545,6 +545,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
int len;
int ihlen;
int err;
+ int sum_truesize;
u8 ecn;
ipq_kill(qp);
@@ -611,19 +612,32 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
atomic_add(clone->truesize, &qp->q.net->mem);
}
- skb_shinfo(head)->frag_list = head->next;
skb_push(head, head->data - skb_network_header(head));
- for (fp=head->next; fp; fp = fp->next) {
- head->data_len += fp->len;
- head->len += fp->len;
+ sum_truesize = head->truesize;
+ for (fp = head->next; fp;) {
+ bool headstolen;
+ int delta;
+ struct sk_buff *next = fp->next;
+
+ sum_truesize += fp->truesize;
if (head->ip_summed != fp->ip_summed)
head->ip_summed = CHECKSUM_NONE;
else if (head->ip_summed == CHECKSUM_COMPLETE)
head->csum = csum_add(head->csum, fp->csum);
- head->truesize += fp->truesize;
+
+ if (skb_try_coalesce(head, fp, &headstolen, &delta)) {
+ kfree_skb_partial(fp, headstolen);
+ } else {
+ if (!skb_shinfo(head)->frag_list)
+ skb_shinfo(head)->frag_list = fp;
+ head->data_len += fp->len;
+ head->len += fp->len;
+ head->truesize += fp->truesize;
+ }
+ fp = next;
}
- atomic_sub(head->truesize, &qp->q.net->mem);
+ atomic_sub(sum_truesize, &qp->q.net->mem);
head->next = NULL;
head->dev = dev;
^ permalink raw reply related
* [PATCH net-next 3/3] ipv6: use skb coalescing in reassembly
From: Eric Dumazet @ 2012-05-19 13:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Alexander Duyck
From: Eric Dumazet <edumazet@google.com>
ip6_frag_reasm() can use skb_try_coalesce() to build optimized skb,
reducing memory used by them (truesize), and reducing number of cache
line misses and overhead for the consumer.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Alexander Duyck <alexander.h.duyck@intel.com>
---
net/ipv6/reassembly.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 5d32dfa..4ff9af6 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -415,6 +415,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
struct sk_buff *fp, *head = fq->q.fragments;
int payload_len;
unsigned int nhoff;
+ int sum_truesize;
fq_kill(fq);
@@ -484,20 +485,33 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
head->mac_header += sizeof(struct frag_hdr);
head->network_header += sizeof(struct frag_hdr);
- skb_shinfo(head)->frag_list = head->next;
skb_reset_transport_header(head);
skb_push(head, head->data - skb_network_header(head));
- for (fp=head->next; fp; fp = fp->next) {
- head->data_len += fp->len;
- head->len += fp->len;
+ sum_truesize = head->truesize;
+ for (fp = head->next; fp;) {
+ bool headstolen;
+ int delta;
+ struct sk_buff *next = fp->next;
+
+ sum_truesize += fp->truesize;
if (head->ip_summed != fp->ip_summed)
head->ip_summed = CHECKSUM_NONE;
else if (head->ip_summed == CHECKSUM_COMPLETE)
head->csum = csum_add(head->csum, fp->csum);
- head->truesize += fp->truesize;
+
+ if (skb_try_coalesce(head, fp, &headstolen, &delta)) {
+ kfree_skb_partial(fp, headstolen);
+ } else {
+ if (!skb_shinfo(head)->frag_list)
+ skb_shinfo(head)->frag_list = fp;
+ head->data_len += fp->len;
+ head->len += fp->len;
+ head->truesize += fp->truesize;
+ }
+ fp = next;
}
- atomic_sub(head->truesize, &fq->q.net->mem);
+ atomic_sub(sum_truesize, &fq->q.net->mem);
head->next = NULL;
head->dev = dev;
^ permalink raw reply related
* [PATCH] USB CDC-Ether - Add ZTE WWAN matches before generic Ethernet
From: Andrew Bird @ 2012-05-19 13:56 UTC (permalink / raw)
To: oliver; +Cc: gregkh, linux-usb, netdev, linux-kernel, Andrew Bird
Some ZTE WWAN devices have generic CDC Ether descriptors. Add those
into the whitelist so that we get FLAG_WWAN on the interface
Signed-off-by: Andrew Bird <ajb@spheresystems.co.uk>
---
drivers/net/usb/cdc_ether.c | 56 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 425e201..fffee6a 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -486,6 +486,7 @@ static const struct driver_info wwan_info = {
#define HUAWEI_VENDOR_ID 0x12D1
#define NOVATEL_VENDOR_ID 0x1410
+#define ZTE_VENDOR_ID 0x19D2
static const struct usb_device_id products [] = {
/*
@@ -618,6 +619,61 @@ static const struct usb_device_id products [] = {
.bInterfaceProtocol = USB_CDC_PROTO_NONE,
.driver_info = (unsigned long)&wwan_info,
}, {
+ /* ZTE (Vodafone) K3805-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1003,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
+ /* ZTE (Vodafone) K3806-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1015,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
+ /* ZTE (Vodafone) K4510-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1173,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
+ /* ZTE (Vodafone) K3770-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1177,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
+ /* ZTE (Vodafone) K3772-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1181,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &cdc_info,
--
1.7.6.5
^ permalink raw reply related
* [PATCH] iproute2: man page and /bin/ip disagree on del vs delete
From: Andreas Henriksson @ 2012-05-19 14:08 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Robert Henney, 673355, netdev
In-Reply-To: <20120518012928.26883.11644.reportbug@linear.rut.org>
On Thu, May 17, 2012 at 09:29:28PM -0400, Robert Henney wrote:
> the 'ip' man page does not mention the command "del" at all but does
> claim, "As a rule, it is possible to add, delete and show (or list ) objects".
> however, 'ip' does not always recognize "delete" as a commend.
>
> robh@debian:~$ ip tunnel delete
> Command "delete" is unknown, try "ip tunnel help".
Lets use "delete" in all calls to matches() for consistency. This will
make both "del" and "delete" work everywhere.
Signed-off-by: Andreas Henriksson <andreas@fatal.se>
diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c
index d5bee36..c9720eb 100644
--- a/ip/ip6tunnel.c
+++ b/ip/ip6tunnel.c
@@ -408,7 +408,7 @@ int do_ip6tunnel(int argc, char **argv)
return do_add(SIOCADDTUNNEL, argc - 1, argv + 1);
if (matches(*argv, "change") == 0)
return do_add(SIOCCHGTUNNEL, argc - 1, argv + 1);
- if (matches(*argv, "del") == 0)
+ if (matches(*argv, "delete") == 0)
return do_del(argc - 1, argv + 1);
if (matches(*argv, "show") == 0 ||
matches(*argv, "lst") == 0 ||
diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c
index c5683f5..3a5f94b 100644
--- a/ip/ipl2tp.c
+++ b/ip/ipl2tp.c
@@ -795,7 +795,7 @@ int do_ipl2tp(int argc, char **argv)
if (matches(*argv, "add") == 0)
return do_add(argc-1, argv+1);
- if (matches(*argv, "del") == 0)
+ if (matches(*argv, "delete") == 0)
return do_del(argc-1, argv+1);
if (matches(*argv, "show") == 0 ||
matches(*argv, "lst") == 0 ||
diff --git a/ip/iptunnel.c b/ip/iptunnel.c
index 3d41a27..38ccd87 100644
--- a/ip/iptunnel.c
+++ b/ip/iptunnel.c
@@ -620,7 +620,7 @@ int do_iptunnel(int argc, char **argv)
return do_add(SIOCADDTUNNEL, argc-1, argv+1);
if (matches(*argv, "change") == 0)
return do_add(SIOCCHGTUNNEL, argc-1, argv+1);
- if (matches(*argv, "del") == 0)
+ if (matches(*argv, "delete") == 0)
return do_del(argc-1, argv+1);
if (matches(*argv, "show") == 0 ||
matches(*argv, "lst") == 0 ||
diff --git a/ip/iptuntap.c b/ip/iptuntap.c
index 29f2777..20914e1 100644
--- a/ip/iptuntap.c
+++ b/ip/iptuntap.c
@@ -307,7 +307,7 @@ int do_iptuntap(int argc, char **argv)
if (argc > 0) {
if (matches(*argv, "add") == 0)
return do_add(argc-1, argv+1);
- if (matches(*argv, "del") == 0)
+ if (matches(*argv, "delete") == 0)
return do_del(argc-1, argv+1);
if (matches(*argv, "show") == 0 ||
matches(*argv, "lst") == 0 ||
^ 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