* Re: [PATCH RESEND] net: remove obsolete simple_strto<foo>
From: Abhijit Pawar @ 2012-12-11 3:33 UTC (permalink / raw)
To: David Miller
Cc: abhi.c.pawar, pablo, kaber, kuznet, jmorris, yoshfuji, linville,
johannes, amwang, edumazet, nhorman, joe, netdev, linux-kernel,
netfilter-devel, netfilter, coreteam, linux-wireless
In-Reply-To: <20121210.141002.450030380391247897.davem@davemloft.net>
On 12/11/2012 12:40 AM, David Miller wrote:
> From: Abhijit Pawar <abhi.c.pawar@gmail.com>
> Date: Mon, 10 Dec 2012 14:42:28 +0530
>
>> This patch replace the obsolete simple_strto<foo> with kstrto<foo>
>>
>> Signed-off-by: Abhijit Pawar <abhi.c.pawar@gmail.com>
>
> Applied.
>
Hi David,
It seems that there are occurences of simple_strto* still present in the
couple of files which are not yet removed correctly by this patch. I
will send a modified patch shortly. Please revert this commit and use
the newly sent patch to merge with the tree.
--
-
Abhijit
^ permalink raw reply
* Hello Do you need a loan?
From: intercomloanfirmservice @ 2012-12-11 3:23 UTC (permalink / raw)
Hello
Do you need a loan?
If yes, then you have no problem because all we are doing is
give credit to the pepole 3% rates with us, you are sure of your sum
credit.
We are making history, and many others.
as we are the best online lenders have loans internet.We different
customers in Singapore, United States of America and its
surroundings.
You can contact us by.
mail: starbicloanagency@gmail.com
^ permalink raw reply
* Re: [PATCH][RFC] smsc95xx: enable dynamic autosuspend (RFC)
From: Ming Lei @ 2012-12-11 2:24 UTC (permalink / raw)
To: Steve Glendinning
Cc: Oliver Neukum, Steve Glendinning, netdev,
linux-usb-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman
In-Reply-To: <CAKh2mn5LgZBJDJWNzN8A3NK72Vk_fiUjJfmdn5njSrm400q36w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, Dec 10, 2012 at 10:18 PM, Steve Glendinning <steve-nksJyM/082jR7s880joybQ@public.gmane.org> wrote:
> On 10 December 2012 12:09, Oliver Neukum <oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org> wrote:
>> So this is a problem with remote wakeup on older hardware?
>
> Exactly, the older hardware revisions can't reliably do it.
>
>>> Unfortunately we don't know if the connected device supports
>>> this feature until we query its ID register at runtime.
>>>
>>> Suggestions on how best to indicate this capability at runtime
>>> instead of compile-time would be appreciated, so we don't have
>>> to repeatedly fail if accidentally enabled. Or maybe this is
>>> actually the best way?
>>
>> If this is a problem with remote wakeup, you should up the
>> pm counter (usb_autopm_get_noresume()) in .manage_power
>> That was the reason I implemented this is a callback and not as
>> a helper in usbnet.
>
> Thanks, so something like this should do the job?
This will do, but not simple as clearing .manage_power function
pointer in bind(), and still disable runtime suspend for link off case
since these devices which don't support suspend 3 can generate
remote wakeup for link change event.
I suggest to introduce link-off triggered runtime suspend for these
usbnet devices(non-LAN9500A device, devices which don't support
USB auto-suspend), and I have posted one patch set before[1].
If no one objects that, I'd like to post them again with some fix and
update for checking link after link_reset().
[1], http://marc.info/?w=2&r=1&s=usbnet%3A+support+runtime+PM+triggered+by+&q=t
>
> static int smsc95xx_manage_power(struct usbnet *dev, int on)
> {
> struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
>
> dev->intf->needs_remote_wakeup = on;
>
> if (pdata->features & FEATURE_AUTOSUSPEND)
> return 0;
>
> /* this chip revision doesn't support autosuspend */
> netdev_info(dev->net, "hardware doesn't support USB autosuspend\n");
>
> if (on)
> usb_autopm_get_interface_no_resume(dev->intf);
> else
> usb_autopm_put_interface_no_suspend(dev->intf);
>
> return 0;
> }
Thanks,
--
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* request to queue patches for stable
From: CAI Qian @ 2012-12-11 2:03 UTC (permalink / raw)
To: netdev
In-Reply-To: <20121206.222321.485936471142281291.davem@davemloft.net>
----- Original Message -----
> From: "David Miller" <davem@davemloft.net>
> To: caiqian@redhat.com
> Cc: greg@kroah.com, stable@vger.kernel.org, mbizon@freebox.fr, ja@ssi.bg
> Sent: Friday, December 7, 2012 11:23:21 AM
> Subject: Re: [PATCH] ipv4: do not cache looped multicasts
>
> From: CAI Qian <caiqian@redhat.com>
> Date: Thu, 6 Dec 2012 21:56:35 -0500 (EST)
>
> > OK, I have a few network patches in the queue that looks applicable
> > to
> > the stable as well. I think I'll send them out here too to seek
> > their
> > ACKs. David, please let me know if I should stop doing this.
>
> Please stop doing this.
>
> If you want networking patches to reach stable, first
> consult:
>
> http://patchwork.ozlabs.org/bundle/davem/stable/
>
> to see if the patch you want isn't queued up already.
>
> If it is not, ask me to queue it up on netdev@vger.kernel.org
>
> But note that I like to let networking patches "cook" upstream
> in Linus's tree for a certain amount of time before I submit
> them to -stable. There can be up to even a week or two.
Dave, the following patches looks applicable for the stable
releases. Please queue them up if you agree.
0e376bd0b791ac6ac6bdb051492df0769c840848 (for 3.0.x, 3.4.x and 3.6.x)
e196c0e579902f42cf72414461fb034e5a1ffbf7 (for 3.0.x, 3.4.x and 3.6.x)
6e51fe7572590d8d86e93b547fab6693d305fd0d (for 3.0.x, 3.4.x and 3.6.x)
e1a676424c290b1c8d757e3860170ac7ecd89af4 (for 3.6.x)
636174219b52b5a8bc51bc23bbcba97cd30a65e3 (for 3.6.x)
CAI Qian
^ permalink raw reply
* [PATCH] tun: allow setting ethernet addresss while running
From: Stephen Hemminger @ 2012-12-11 1:16 UTC (permalink / raw)
To: davem; +Cc: netdev, jasowang, Stephen Hemminger
This is a pure software device, and ok with live address change.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
drivers/net/tun.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 14a0454..2ac2164 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -849,6 +849,7 @@ static void tun_net_init(struct net_device *dev)
/* Ethernet TAP Device */
ether_setup(dev);
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
eth_hw_addr_random(dev);
--
1.7.10.4
^ permalink raw reply related
* RE: [net-next 1/7] bna: Code Cleanup and Enhancements
From: Rasesh Mody @ 2012-12-11 0:39 UTC (permalink / raw)
To: David Miller
Cc: netdev@vger.kernel.org, bhutchings@solarflare.com,
David.Laight@ACULAB.COM, Adapter Linux Open SRC Team
In-Reply-To: <20121210.171349.1368932708858713762.davem@davemloft.net>
>From: David Miller [mailto:davem@davemloft.net]
>Sent: Monday, December 10, 2012 2:14 PM
>
>From: Rasesh Mody <rmody@brocade.com>
>Date: Mon, 10 Dec 2012 13:41:59 -0800
>
>> - skb = unmap_array[unmap_cons].skb;
>> - BUG_ON(!(skb));
>> - unmap_array[unmap_cons].skb = NULL;
>> + curr_ua = &unmap_array[unmap_cons];
>> +
>> + skb = curr_ua->skb;
>> + BUG_ON(!(skb));\
> ^^^
>
>Really?
>
>Please carefully review your own work before submitting it for
>inclusion. When you have erroneous things like this in the very first
>patch it reflects very poorly upon the quality of your work.
Sorry Dave, it accidentally got introduced. I will rectify it and resend the patches after carefully reviewing patches for similar errors.
Thanks
Rasesh
^ permalink raw reply
* Re: [tcpdump-workers] vlan tagged packets and libpcap breakage
From: Ani Sinha @ 2012-12-11 0:11 UTC (permalink / raw)
To: Michael Richardson
Cc: Eric W. Biederman, tcpdump-workers, netdev, Francesco Ruggeri
In-Reply-To: <8795.1354845553@obiwan.sandelman.ca>
On Thu, 6 Dec 2012, Michael Richardson wrote:
> Date: Thu, 6 Dec 2012 17:59:13
> From: Michael Richardson <mcr@sandelman.ca>
> To: Eric W. Biederman <ebiederm@xmission.com>
> Cc: ani@aristanetworks.com, tcpdump-workers@lists.tcpdump.org,
> netdev@vger.kernel.org, Francesco Ruggeri <fruggeri@aristanetworks.com>
> Subject: Re: [tcpdump-workers] vlan tagged packets and libpcap breakage
>
>
> >>>>> "Eric" == Eric W Biederman <ebiederm@xmission.com> writes:
> Eric> It is a bit odd that you are indenting with spaces instead of tabs
> Eric> in a file that is indented with tab. Again libpcap isn't my code so I
> Eric> don't care but someone else might.
Here's an updated patch. I have converted spaces to tabs consistent with
rest of the file. I have also set up github and sent a pull request
:
commit b977ebd9d9608bb8a8e4927e7a6286bdfd6b94a8
Author: Ani Sinha <ani@aristanetworks.com>
Date: Mon Dec 10 14:58:15 2012 -0800
Linux kernel 3.0 uses TP_STATUS_VLAN_VALID flag in packet
auxilliary data aux->tp_status to indicate a packet tagged
with a valid vlan ID 0 with another packet that is not
vlan tagged. Use this flag to check for the presence of
a vlan tagged packet. Also be careful not to cause any
breakage when libpcap is compiled against a newer kernel
(>=3.0) and used on top of an older kernel that does not
use this flag.
Signed-off-by: Ani Sinha <ani@aristanetworks.com>
diff --git a/pcap-linux.c b/pcap-linux.c
index a42c3ac..ffcabdf 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -133,6 +133,7 @@ static const char rcsid[] _U_ =
#include <sys/utsname.h>
#include <sys/mman.h>
#include <linux/if.h>
+#include <linux/if_packet.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <net/if_arp.h>
@@ -1543,7 +1544,13 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
continue;
aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
- if (aux->tp_vlan_tci == 0)
+#if defined(TP_STATUS_VLAN_VALID)
+ if ((aux->tp_vlan_tci == 0) && !(aux->tp_status & TP_STATUS_VLAN_VALID))
+#else
+ if (aux->tp_vlan_tci == 0) /* this is ambigious but without the
+ TP_STATUS_VLAN_VALID flag, there is
+ nothing that we can do */
+#endif
continue;
len = packet_len > iov.iov_len ? iov.iov_len : packet_len;
@@ -3936,7 +3943,12 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
}
#ifdef HAVE_TPACKET2
- if (handle->md.tp_version == TPACKET_V2 && h.h2->tp_vlan_tci &&
+ if ((handle->md.tp_version == TPACKET_V2) &&
+#if defined(TP_STATUS_VLAN_VALID)
+ (h.h2->tp_vlan_tci || (h.h2->tp_status & TP_STATUS_VLAN_VALID)) &&
+#else
+ h.h2->tp_vlan_tci &&
+#endif
handle->md.vlan_offset != -1 &&
tp_snaplen >= (unsigned int) handle->md.vlan_offset) {
struct vlan_tag *tag;
^ permalink raw reply related
* Re: linux-next: build failure after merge of the virtio tree
From: Rusty Russell @ 2012-12-10 22:41 UTC (permalink / raw)
To: Stephen Rothwell
Cc: linux-next, linux-kernel, Jason Wang, David Miller, netdev
In-Reply-To: <20121210133725.cb4a76545691b099c73c40ea@canb.auug.org.au>
Stephen Rothwell <sfr@canb.auug.org.au> writes:
> Hi Rusty,
>
> After merging the virtio tree, today's linux-next build (x86_64
> allmodconfig) failed like this:
>
> drivers/net/virtio_net.c: In function 'vq2txq':
> drivers/net/virtio_net.c:150:2: error: implicit declaration of function 'virtqueue_get_queue_index' [-Werror=implicit-function-declaration]
>
> Caused by commit 986a4f4d452d ("virtio_net: multiqueue support") from the
> net-next tree interacting with commit 105e892960e1 ("virtio: move
> queue_index and num_free fields into core struct virtqueue") from the
> virtio tree.
>
> I applied the patch below and can carry it as necessary.
Thanks for this, your fix is correct.
Cheers,
Rusty.
^ permalink raw reply
* Re: [PATCHv7] virtio-spec: virtio network device multiqueue support
From: Rusty Russell @ 2012-12-10 23:50 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: bhutchings, netdev, kvm, virtualization
In-Reply-To: <20121210104025.GA26640@redhat.com>
"Michael S. Tsirkin" <mst@redhat.com> writes:
> Add multiqueue support to virtio network device.
> Add a new feature flag VIRTIO_NET_F_MQ for this feature, a new
> configuration field max_virtqueue_pairs to detect supported number of
> virtqueues as well as a new command VIRTIO_NET_CTRL_MQ to program
> packet steering for unidirectional protocols.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Thanks, applied.
Cheers,
Rusty.
^ permalink raw reply
* [PATCH net-next] net: gro: dev_gro_receive() cleanup
From: Eric Dumazet @ 2012-12-10 23:28 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
__napi_gro_receive() is inlined from two call sites for no good reason.
Lets move the prep stuff in a function of its own, called only if/when
needed. This saves 300 bytes on x86 :
# size net/core/dev.o.after net/core/dev.o.before
text data bss dec hex filename
51968 1238 1040 54246 d3e6 net/core/dev.o.before
51664 1238 1040 53942 d2b6 net/core/dev.o.after
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/core/dev.c | 52 +++++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index a4c4a1b..4783850 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3603,6 +3603,28 @@ void napi_gro_flush(struct napi_struct *napi, bool flush_old)
}
EXPORT_SYMBOL(napi_gro_flush);
+static void gro_list_prepare(struct napi_struct *napi, struct sk_buff *skb)
+{
+ struct sk_buff *p;
+ unsigned int maclen = skb->dev->hard_header_len;
+
+ for (p = napi->gro_list; p; p = p->next) {
+ unsigned long diffs;
+
+ diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
+ diffs |= p->vlan_tci ^ skb->vlan_tci;
+ if (maclen == ETH_HLEN)
+ diffs |= compare_ether_header(skb_mac_header(p),
+ skb_gro_mac_header(skb));
+ else if (!diffs)
+ diffs = memcmp(skb_mac_header(p),
+ skb_gro_mac_header(skb),
+ maclen);
+ NAPI_GRO_CB(p)->same_flow = !diffs;
+ NAPI_GRO_CB(p)->flush = 0;
+ }
+}
+
static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
struct sk_buff **pp = NULL;
@@ -3619,6 +3641,8 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
if (skb_is_gso(skb) || skb_has_frag_list(skb))
goto normal;
+ gro_list_prepare(napi, skb);
+
rcu_read_lock();
list_for_each_entry_rcu(ptype, head, list) {
if (ptype->type != type || !ptype->callbacks.gro_receive)
@@ -3695,30 +3719,6 @@ normal:
goto pull;
}
-static inline gro_result_t
-__napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
-{
- struct sk_buff *p;
- unsigned int maclen = skb->dev->hard_header_len;
-
- for (p = napi->gro_list; p; p = p->next) {
- unsigned long diffs;
-
- diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
- diffs |= p->vlan_tci ^ skb->vlan_tci;
- if (maclen == ETH_HLEN)
- diffs |= compare_ether_header(skb_mac_header(p),
- skb_gro_mac_header(skb));
- else if (!diffs)
- diffs = memcmp(skb_mac_header(p),
- skb_gro_mac_header(skb),
- maclen);
- NAPI_GRO_CB(p)->same_flow = !diffs;
- NAPI_GRO_CB(p)->flush = 0;
- }
-
- return dev_gro_receive(napi, skb);
-}
static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
{
@@ -3768,7 +3768,7 @@ gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
skb_gro_reset_offset(skb);
- return napi_skb_finish(__napi_gro_receive(napi, skb), skb);
+ return napi_skb_finish(dev_gro_receive(napi, skb), skb);
}
EXPORT_SYMBOL(napi_gro_receive);
@@ -3866,7 +3866,7 @@ gro_result_t napi_gro_frags(struct napi_struct *napi)
if (!skb)
return GRO_DROP;
- return napi_frags_finish(napi, skb, __napi_gro_receive(napi, skb));
+ return napi_frags_finish(napi, skb, dev_gro_receive(napi, skb));
}
EXPORT_SYMBOL(napi_gro_frags);
^ permalink raw reply related
* Re: [PATCH] smsc75xx: only set mac address once on bind
From: Dan Williams @ 2012-12-10 23:00 UTC (permalink / raw)
To: Steve Glendinning; +Cc: netdev, Bjorn Mork
In-Reply-To: <1355137279-2695-1-git-send-email-steve.glendinning@shawell.net>
On Mon, 2012-12-10 at 11:01 +0000, Steve Glendinning wrote:
> This patch changes when we decide what the device's MAC address
> is from per ifconfig up to once when the device is connected.
>
> Without this patch, a manually forced device MAC is overwritten
> on ifconfig down/up. Also devices that have no EEPROM are
> assigned a new random address on ifconfig down/up instead of
> persisting the same one.
Does this mean that on devices without EEPROM, ifconfig XXX
down/ifconfig XXX up will generate a *new* random address? That seems a
bit odd; why wouldn't the first random address generated for the device
persist until either (a) changed by ifconfig or (b) device was
disconnected?
Dan
> Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
> Reported-by: Robert Cunningham <rcunningham@nsmsurveillance.com>
> Cc: Bjorn Mork <bjorn@mork.no>
> Cc: Dan Williams <dcbw@redhat.com>
> ---
> drivers/net/usb/smsc75xx.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
> index 1cbd936..251a335 100644
> --- a/drivers/net/usb/smsc75xx.c
> +++ b/drivers/net/usb/smsc75xx.c
> @@ -1054,8 +1054,6 @@ static int smsc75xx_reset(struct usbnet *dev)
>
> netif_dbg(dev, ifup, dev->net, "PHY reset complete\n");
>
> - smsc75xx_init_mac_address(dev);
> -
> ret = smsc75xx_set_mac_address(dev);
> if (ret < 0) {
> netdev_warn(dev->net, "Failed to set mac address\n");
> @@ -1422,6 +1420,14 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
> dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_RXCSUM;
>
> + ret = smsc75xx_wait_ready(dev, 0);
> + if (ret < 0) {
> + netdev_warn(dev->net, "device not ready in smsc75xx_bind\n");
> + return ret;
> + }
> +
> + smsc75xx_init_mac_address(dev);
> +
> /* Init all registers */
> ret = smsc75xx_reset(dev);
> if (ret < 0) {
^ permalink raw reply
* RE: [PATCH net-next] bnx2x: use netdev_alloc_frag()
From: Dmitry Kravkov @ 2012-12-10 22:57 UTC (permalink / raw)
To: Eric Dumazet, David Miller; +Cc: netdev, Eilon Greenstein
In-Reply-To: <1355177766.27891.68.camel@edumazet-glaptop>
> -----Original Message-----
> From: Eric Dumazet [mailto:eric.dumazet@gmail.com]
> Sent: Tuesday, December 11, 2012 12:16 AM
> To: David Miller
> Cc: netdev; Eilon Greenstein; Dmitry Kravkov
> Subject: [PATCH net-next] bnx2x: use netdev_alloc_frag()
>
> From: Eric Dumazet <edumazet@google.com>
>
> Using netdev_alloc_frag() instead of kmalloc() permits better GRO or
> TCP coalescing behavior, as skb_gro_receive() doesn't have to fallback
> to frag_list overhead.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Dmitry Kravkov <dmitry@broadcom.com>
> Cc: Eilon Greenstein <eilong@broadcom.com>
Thanks a lot, Eric!
Acked-by: Dmitry Kravkov <dmitry@broadcom.com>
^ permalink raw reply
* RE: [PATCH] net: fix a race in gro_cell_poll()
From: Dmitry Kravkov @ 2012-12-10 22:46 UTC (permalink / raw)
To: Eric Dumazet, David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <1355178723.27891.85.camel@edumazet-glaptop>
> -----Original Message-----
> From: Eric Dumazet [mailto:eric.dumazet@gmail.com]
> Sent: Tuesday, December 11, 2012 12:32 AM
> To: Dmitry Kravkov; David Miller
> Cc: netdev@vger.kernel.org
> Subject: [PATCH] net: fix a race in gro_cell_poll()
>
> From: Eric Dumazet <edumazet@google.com>
>
> Dmitry Kravkov reported packet drops for GRE packets since GRO support
> was added.
>
> There is a race in gro_cell_poll() because we call napi_complete()
> without any synchronization with a concurrent gro_cells_receive()
>
> Once bug was triggered, we queued packets but did not schedule NAPI
> poll.
>
> We can fix this issue using the spinlock protected the napi_skbs queue,
> as we have to hold it to perform skb dequeue anyway.
>
> As we open-code skb_dequeue(), we no longer need to mask IRQS, as both
> producer and consumer run under BH context.
>
> Bug added in commit c9e6bc644e (net: add gro_cells infrastructure)
>
> Reported-by: Dmitry Kravkov <dmitry@broadcom.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
>
> David: I could reproduce the bug Dmitry reported, and have
> verified this patch fixes the issue.
>
> include/net/gro_cells.h | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h
> index 4fd8a4b..e5062c9 100644
> --- a/include/net/gro_cells.h
> +++ b/include/net/gro_cells.h
> @@ -17,7 +17,6 @@ struct gro_cells {
>
> static inline void gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
> {
> - unsigned long flags;
> struct gro_cell *cell = gcells->cells;
> struct net_device *dev = skb->dev;
>
> @@ -35,32 +34,37 @@ static inline void gro_cells_receive(struct gro_cells
> *gcells, struct sk_buff *s
> return;
> }
>
> - spin_lock_irqsave(&cell->napi_skbs.lock, flags);
> + /* We run in BH context */
> + spin_lock(&cell->napi_skbs.lock);
>
> __skb_queue_tail(&cell->napi_skbs, skb);
> if (skb_queue_len(&cell->napi_skbs) == 1)
> napi_schedule(&cell->napi);
>
> - spin_unlock_irqrestore(&cell->napi_skbs.lock, flags);
> + spin_unlock(&cell->napi_skbs.lock);
> }
>
> +/* called unser BH context */
> static inline int gro_cell_poll(struct napi_struct *napi, int budget)
> {
> struct gro_cell *cell = container_of(napi, struct gro_cell, napi);
> struct sk_buff *skb;
> int work_done = 0;
>
> + spin_lock(&cell->napi_skbs.lock);
> while (work_done < budget) {
> - skb = skb_dequeue(&cell->napi_skbs);
> + skb = __skb_dequeue(&cell->napi_skbs);
> if (!skb)
> break;
> -
> + spin_unlock(&cell->napi_skbs.lock);
> napi_gro_receive(napi, skb);
> work_done++;
> + spin_lock(&cell->napi_skbs.lock);
> }
>
> if (work_done < budget)
> napi_complete(napi);
> + spin_unlock(&cell->napi_skbs.lock);
> return work_done;
> }
>
>
My scenario is working, now
Thanks Eric.
Tested-by: Dmitry Kravkov <dmitry@broadcom.com>
^ permalink raw reply
* Re: [RFC PATCH v2 3/3] tun: fix LSM/SELinux labeling of tun/tap devices
From: Paul Moore @ 2012-12-10 22:43 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: netdev, linux-security-module, selinux, jasowang
In-Reply-To: <20121210175035.GA31856@redhat.com>
On Monday, December 10, 2012 07:50:35 PM Michael S. Tsirkin wrote:
> On Mon, Dec 10, 2012 at 12:33:49PM -0500, Paul Moore wrote:
> > On Monday, December 10, 2012 07:26:56 PM Michael S. Tsirkin wrote:
> > > On Mon, Dec 10, 2012 at 12:04:35PM -0500, Paul Moore wrote:
> > > > On Friday, December 07, 2012 02:25:16 PM Michael S. Tsirkin wrote:
> > > > > On Thu, Dec 06, 2012 at 04:09:51PM -0500, Paul Moore wrote:
> > > > > > On Thursday, December 06, 2012 10:57:16 PM Michael S. Tsirkin
wrote:
> > > > > > > On Thu, Dec 06, 2012 at 11:56:45AM -0500, Paul Moore wrote:
> > > > > > > > The SETQUEUE/tun_socket:create_queue permissions do not yet
> > > > > > > > exist
> > > > > > > > in any released SELinux policy as we are just now adding them
> > > > > > > > with
> > > > > > > > this patchset. With current policies loaded into a kernel with
> > > > > > > > this patchset applied the SETQUEUE/tun_socket:create_queue
> > > > > > > > permission would be treated according to the policy's unknown
> > > > > > > > permission setting.
> > > > > > >
> > > > > > > OK I think we need to rethink what we are doing here: what you
> > > > > > > sent
> > > > > > > addresses the problem as stated but I think we mis-stated it.
> > > > > > > Let
> > > > > > > me try to restate the problem: it is not just selinux problem.
> > > > > > > Let's
> > > > > > > assume qemu wants to use tun, I (libvirt) don't want to run it
> > > > > > > as
> > > > > > > root.
> > > > > > >
> > > > > > > 1. TUNSETIFF: I can open tun, attach an fd and pass it to qemu.
> > > > > > > Now, qemu does not invoke TUNSETIFF so it can run without
> > > > > > > kernel priveledges.
> > > > > >
> > > > > > Correct me if I'm wrong, but I believe libvirt does this while
> > > > > > running
> > > > > > as root. Assuming that is the case, why not simply
> > > > > > setuid()/setgid()
> > > > > > to the same credentials as the QEMU instance before creating the
> > > > > > TUN
> > > > > > device? You can always (re)configure the device afterwards while
> > > > > > running as root/CAP_NET_ADMIN.
> > > > >
> > > > > We want isolation between qemu instances.
> > > >
> > > > Understood, I agree.
> > > >
> > > > Achieving separation via SELinux is easily done, with libvirt/sVirt
> > > > already doing this for us automatically in most cases; the only thing
> > > > we
> > > > will want to do is make sure the SELinux policy is aware of the new
> > > > permission.
> > > >
> > > > Achieving separation via DAC should also be easily done, simply run
> > > > each
> > > > QEMU instance with a separate UID and/or GID.
> > > >
> > > > > Giving qemu right to open tun and SETIFF would give it rights
> > > > > to access any tun device.
> > > >
> > > > I'm quickly looked at tun_chr_open() again and I don't see any special
> > > > rights/privileges required, the same for tun_chr_ioctl() and
> > > > __tun_chr_ioctl(). Looking at tun_set_queue() I see we call
> > > > tun_not_capable() which does a simple DAC check; it must have the same
> > > > UID/GID or have CAP_NET_ADMIN.
> > > >
> > > > I'm having a hard time seeing the problem you are describing; help me
> > > > understand.
> > >
> > > The issue is guest controls the number of queues in use.
> > > So qemu would be required to be allowed to call tun_set_queue.
> > > If we allow this we have a problem as one qemu will be
> > > able to access any tun.
> >
> > QEMU can call tun_set_queue() as long as it satisfies tun_not_capable(),
> > which from a practical point of view means that the TUN device was
> > created with the same UID/GID as the QEMU instance. If you want TUN
> > device separation between QEMU instances using DAC you need to run each
> > QEMU instance with a different UID/GID (which you should be doing anyway
> > if you want DAC enforced general separation).
> >
> > I believe I've stated this point several times now and I don't feel you've
> > addressed it properly.
>
> Look at how it works at the moment:
> a priveledged libvirt server calls tun_set_iff
> and passes the fd to qemu which is not priveledged.
>
> The result is isolation between qemu instances without
> need to create uid per qemu instance.
Okay, good. That is my understanding.
> How do we create multiple queues? It makes sense to
> follow this model and pass in fds for individual queues.
Okay.
> However they need to be disabled initially
> so libvirt can not do tun_set_queue for us.
Unrelated question: why do the queues need to be disabled initially? Is this
to prevent traffic from being queued up? Some other reason? I'm just curious
as to the reason ...
> When qemu later calls tun_set_queue it will fail which means we
> can't utilize multiqueue.
I still don't understand why in the multiqueue case libvirt doesn't just
change it's effective UID/GID when creating the TUN device, or just use the
TUNSETOWNER/TUNSETGROUP commands. This would solve the problem you describe
above and - at least to me - seems like a better solution conceptually.
Help me understand why you believe that will not work.
Do you not want to give ownership of the TUN device to QEMU? That would be
the only reason I can think of, but all of your comments that I can recall
have been about isolation between QEMU instances and not access control
between a QEMU instance and its assigned TUN device.
> My solution is an unpriveledged variant
> of tun_set_queue that only enables/disables
> a queue without attach/detach.
--
paul moore
security and virtualization @ redhat
^ permalink raw reply
* [PATCH] net: fix a race in gro_cell_poll()
From: Eric Dumazet @ 2012-12-10 22:32 UTC (permalink / raw)
To: Dmitry Kravkov, David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <1355176551.27891.57.camel@edumazet-glaptop>
From: Eric Dumazet <edumazet@google.com>
Dmitry Kravkov reported packet drops for GRE packets since GRO support
was added.
There is a race in gro_cell_poll() because we call napi_complete()
without any synchronization with a concurrent gro_cells_receive()
Once bug was triggered, we queued packets but did not schedule NAPI
poll.
We can fix this issue using the spinlock protected the napi_skbs queue,
as we have to hold it to perform skb dequeue anyway.
As we open-code skb_dequeue(), we no longer need to mask IRQS, as both
producer and consumer run under BH context.
Bug added in commit c9e6bc644e (net: add gro_cells infrastructure)
Reported-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
David: I could reproduce the bug Dmitry reported, and have
verified this patch fixes the issue.
include/net/gro_cells.h | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h
index 4fd8a4b..e5062c9 100644
--- a/include/net/gro_cells.h
+++ b/include/net/gro_cells.h
@@ -17,7 +17,6 @@ struct gro_cells {
static inline void gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
{
- unsigned long flags;
struct gro_cell *cell = gcells->cells;
struct net_device *dev = skb->dev;
@@ -35,32 +34,37 @@ static inline void gro_cells_receive(struct gro_cells *gcells, struct sk_buff *s
return;
}
- spin_lock_irqsave(&cell->napi_skbs.lock, flags);
+ /* We run in BH context */
+ spin_lock(&cell->napi_skbs.lock);
__skb_queue_tail(&cell->napi_skbs, skb);
if (skb_queue_len(&cell->napi_skbs) == 1)
napi_schedule(&cell->napi);
- spin_unlock_irqrestore(&cell->napi_skbs.lock, flags);
+ spin_unlock(&cell->napi_skbs.lock);
}
+/* called unser BH context */
static inline int gro_cell_poll(struct napi_struct *napi, int budget)
{
struct gro_cell *cell = container_of(napi, struct gro_cell, napi);
struct sk_buff *skb;
int work_done = 0;
+ spin_lock(&cell->napi_skbs.lock);
while (work_done < budget) {
- skb = skb_dequeue(&cell->napi_skbs);
+ skb = __skb_dequeue(&cell->napi_skbs);
if (!skb)
break;
-
+ spin_unlock(&cell->napi_skbs.lock);
napi_gro_receive(napi, skb);
work_done++;
+ spin_lock(&cell->napi_skbs.lock);
}
if (work_done < budget)
napi_complete(napi);
+ spin_unlock(&cell->napi_skbs.lock);
return work_done;
}
^ permalink raw reply related
* [GIT] Networking
From: David Miller @ 2012-12-10 22:31 UTC (permalink / raw)
To: torvalds; +Cc: akpm, netdev, linux-kernel
1) Netlink socket dumping had several missing verifications and
checks.
In particular, address comparisons in the request byte code
interpreter could access past the end of the address in the
inet_request_sock.
Also, address family and address prefix lengths were not
validated properly at all.
This means arbitrary applications can read past the end of
certain kernel data structures.
Fixes from Neal Cardwell.
2) ip_check_defrag() operates in contexts where we're in the
process of, or about to, input the packet into the real
protocols (specifically macvlan and AF_PACKET snooping).
Unfortunately, it does a pskb_may_pull() which can modify
the backing packet data which is not legal if the SKB is
shared. It very much can be shared in this context.
Deal with the possibility that the SKB is segmented by
using skb_copy_bits().
Fix from Johannes Berg based upon a report by Eric Leblond.
Please pull, thanks a lot!
The following changes since commit ed23ec4f0a510528e0ffe415f9394107418ae854:
mm: vmscan: fix inappropriate zone congestion clearing (2012-12-08 08:41:18 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git master
for you to fetch changes up to 1bf3751ec90cc3174e01f0d701e8449ce163d113:
ipv4: ip_check_defrag must not modify skb before unsharing (2012-12-10 13:51:44 -0500)
----------------------------------------------------------------
Johannes Berg (1):
ipv4: ip_check_defrag must not modify skb before unsharing
Neal Cardwell (4):
inet_diag: fix oops for IPv4 AF_INET6 TCP SYN-RECV state
inet_diag: validate byte code to prevent oops in inet_diag_bc_run()
inet_diag: avoid unsafe and nonsensical prefix matches in inet_diag_bc_run()
inet_diag: validate port comparison byte code to prevent unsafe reads
net/ipv4/inet_diag.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
net/ipv4/ip_fragment.c | 19 ++++++-------
2 files changed, 131 insertions(+), 42 deletions(-)
^ permalink raw reply
* Re: [RFC PATCH v2 3/3] tun: fix LSM/SELinux labeling of tun/tap devices
From: Paul Moore @ 2012-12-10 22:21 UTC (permalink / raw)
To: Eric Paris
Cc: Michael S. Tsirkin, Linux Netdev List, LSM List, SE-Linux,
jasowang
In-Reply-To: <CACLa4pu6UCpzKfscVoEPzLySHitta1yTqPa7cA0d=xUj5ws6HA@mail.gmail.com>
On Monday, December 10, 2012 01:42:12 PM Eric Paris wrote:
> Let me abstract a little here Paul. Lets say user A starts an
> unclassified process and a top secret process. SELinux policy darn
> well better be able to enforce that they can not attach to the same
> tun.
>
> Am I missing something here?
Relax, all the SELinux enforced separation still exists, and works. We're
just fixing the LSM/SELinux stuff that was broken with the multiqueue addition
and adding a new SELinux permission to control access to the new queue
command.
What we are currently discussing is DAC only. While Michael have different
opinions on how to solve the DAC issues, we agree that SELinux works
correctly.
--
paul moore
security and virtualization @ redhat
^ permalink raw reply
* [PATCH net-next] bnx2x: use netdev_alloc_frag()
From: Eric Dumazet @ 2012-12-10 22:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Eilon Greenstein, Dmitry Kravkov
From: Eric Dumazet <edumazet@google.com>
Using netdev_alloc_frag() instead of kmalloc() permits better GRO or
TCP coalescing behavior, as skb_gro_receive() doesn't have to fallback
to frag_list overhead.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Dmitry Kravkov <dmitry@broadcom.com>
Cc: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 43 ++++++++++----
2 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 9a3b81e..e8d4db1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -489,7 +489,7 @@ struct bnx2x_fastpath {
u32 ustorm_rx_prods_offset;
u32 rx_buf_size;
-
+ u32 rx_frag_size; /* 0 if kmalloced(), or rx_buf_size + NET_SKB_PAD */
dma_addr_t status_blk_mapping;
enum bnx2x_tpa_mode_t mode;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 67baddd..c9f8ae0 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -552,6 +552,23 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
return 0;
}
+static void bnx2x_frag_free(const struct bnx2x_fastpath *fp, void *data)
+{
+ if (fp->rx_frag_size)
+ put_page(virt_to_head_page(data));
+ else
+ kfree(data);
+}
+
+static void *bnx2x_frag_alloc(const struct bnx2x_fastpath *fp)
+{
+ if (fp->rx_frag_size)
+ return netdev_alloc_frag(fp->rx_frag_size);
+
+ return kmalloc(fp->rx_buf_size + NET_SKB_PAD, GFP_ATOMIC);
+}
+
+
static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
struct bnx2x_agg_info *tpa_info,
u16 pages,
@@ -574,15 +591,14 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
goto drop;
/* Try to allocate the new data */
- new_data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, GFP_ATOMIC);
-
+ new_data = bnx2x_frag_alloc(fp);
/* Unmap skb in the pool anyway, as we are going to change
pool entry status to BNX2X_TPA_STOP even if new skb allocation
fails. */
dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping),
fp->rx_buf_size, DMA_FROM_DEVICE);
if (likely(new_data))
- skb = build_skb(data, 0);
+ skb = build_skb(data, fp->rx_frag_size);
if (likely(skb)) {
#ifdef BNX2X_STOP_ON_ERROR
@@ -619,7 +635,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
return;
}
- kfree(new_data);
+ bnx2x_frag_free(fp, new_data);
drop:
/* drop the packet and keep the buffer in the bin */
DP(NETIF_MSG_RX_STATUS,
@@ -635,7 +651,7 @@ static int bnx2x_alloc_rx_data(struct bnx2x *bp,
struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index];
dma_addr_t mapping;
- data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, GFP_ATOMIC);
+ data = bnx2x_frag_alloc(fp);
if (unlikely(data == NULL))
return -ENOMEM;
@@ -643,7 +659,7 @@ static int bnx2x_alloc_rx_data(struct bnx2x *bp,
fp->rx_buf_size,
DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
- kfree(data);
+ bnx2x_frag_free(fp, data);
BNX2X_ERR("Can't map rx data\n");
return -ENOMEM;
}
@@ -845,9 +861,9 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
dma_unmap_addr(rx_buf, mapping),
fp->rx_buf_size,
DMA_FROM_DEVICE);
- skb = build_skb(data, 0);
+ skb = build_skb(data, fp->rx_frag_size);
if (unlikely(!skb)) {
- kfree(data);
+ bnx2x_frag_free(fp, data);
bnx2x_fp_qstats(bp, fp)->
rx_skb_alloc_failed++;
goto next_rx;
@@ -1145,7 +1161,7 @@ static void bnx2x_free_tpa_pool(struct bnx2x *bp,
dma_unmap_single(&bp->pdev->dev,
dma_unmap_addr(first_buf, mapping),
fp->rx_buf_size, DMA_FROM_DEVICE);
- kfree(data);
+ bnx2x_frag_free(fp, data);
first_buf->data = NULL;
}
}
@@ -1190,8 +1206,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
struct sw_rx_bd *first_buf =
&tpa_info->first_buf;
- first_buf->data = kmalloc(fp->rx_buf_size + NET_SKB_PAD,
- GFP_ATOMIC);
+ first_buf->data = bnx2x_frag_alloc(fp);
if (!first_buf->data) {
BNX2X_ERR("Failed to allocate TPA skb pool for queue[%d] - disabling TPA on this queue!\n",
j);
@@ -1323,7 +1338,7 @@ static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp)
fp->rx_buf_size, DMA_FROM_DEVICE);
rx_buf->data = NULL;
- kfree(data);
+ bnx2x_frag_free(fp, data);
}
}
@@ -1782,6 +1797,10 @@ static void bnx2x_set_rx_buf_size(struct bnx2x *bp)
mtu +
BNX2X_FW_RX_ALIGN_END;
/* Note : rx_buf_size doesnt take into account NET_SKB_PAD */
+ if (fp->rx_buf_size + NET_SKB_PAD <= PAGE_SIZE)
+ fp->rx_frag_size = fp->rx_buf_size + NET_SKB_PAD;
+ else
+ fp->rx_frag_size = 0;
}
}
^ permalink raw reply related
* Re: [PATCH net-next] doc: Tighten-up and clarify description of tcp_fin_timeout
From: David Miller @ 2012-12-10 22:14 UTC (permalink / raw)
To: raj; +Cc: netdev
In-Reply-To: <20121210213300.9D6BB29003EA@tardy>
From: raj@tardy.usa.hp.com (Rick Jones)
Date: Mon, 10 Dec 2012 13:33:00 -0800 (PST)
> From: Rick Jones <rick.jones2@hp.com>
>
> The description for tcp_fin_timeout should be tigher and more clear.
>
> In addition to being tighter, we should make the spelling of the
> state name consistent with what utilities report, remove the now
> dated reference to 2.2 and put the default in the consistent place.
>
> Signed-off-by: Rick Jones <rick.jones2@hp.com>
Applied, thanks Rick.
^ permalink raw reply
* Re: [net-next 1/7] bna: Code Cleanup and Enhancements
From: David Miller @ 2012-12-10 22:13 UTC (permalink / raw)
To: rmody; +Cc: netdev, bhutchings, David.Laight, adapter_linux_open_src_team
In-Reply-To: <1355175725-19202-2-git-send-email-rmody@brocade.com>
From: Rasesh Mody <rmody@brocade.com>
Date: Mon, 10 Dec 2012 13:41:59 -0800
> - skb = unmap_array[unmap_cons].skb;
> - BUG_ON(!(skb));
> - unmap_array[unmap_cons].skb = NULL;
> + curr_ua = &unmap_array[unmap_cons];
> +
> + skb = curr_ua->skb;
> + BUG_ON(!(skb));\
^^^
Really?
Please carefully review your own work before submitting it for
inclusion. When you have erroneous things like this in the
very first patch it reflects very poorly upon the quality of
your work.
^ permalink raw reply
* RE: ipgre rss is broken since gro
From: Eric Dumazet @ 2012-12-10 21:55 UTC (permalink / raw)
To: Dmitry Kravkov; +Cc: netdev@vger.kernel.org
In-Reply-To: <504C9EFCA2D0054393414C9CB605C37F1BFC32A1@SJEXCHMB06.corp.ad.broadcom.com>
On Mon, 2012-12-10 at 19:20 +0000, Dmitry Kravkov wrote:
> Yep, this resolved the issue - Interface is functional after 3 and 100 TCP connections. Thanks
>
>
I guess its only lowering probability of the race.
Could you try instead the following patch ?
I'll address the queue_mapping separately for net-next
Thanks
diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h
index 4fd8a4b..e5062c9 100644
--- a/include/net/gro_cells.h
+++ b/include/net/gro_cells.h
@@ -17,7 +17,6 @@ struct gro_cells {
static inline void gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
{
- unsigned long flags;
struct gro_cell *cell = gcells->cells;
struct net_device *dev = skb->dev;
@@ -35,32 +34,37 @@ static inline void gro_cells_receive(struct gro_cells *gcells, struct sk_buff *s
return;
}
- spin_lock_irqsave(&cell->napi_skbs.lock, flags);
+ /* We run in BH context */
+ spin_lock(&cell->napi_skbs.lock);
__skb_queue_tail(&cell->napi_skbs, skb);
if (skb_queue_len(&cell->napi_skbs) == 1)
napi_schedule(&cell->napi);
- spin_unlock_irqrestore(&cell->napi_skbs.lock, flags);
+ spin_unlock(&cell->napi_skbs.lock);
}
+/* called unser BH context */
static inline int gro_cell_poll(struct napi_struct *napi, int budget)
{
struct gro_cell *cell = container_of(napi, struct gro_cell, napi);
struct sk_buff *skb;
int work_done = 0;
+ spin_lock(&cell->napi_skbs.lock);
while (work_done < budget) {
- skb = skb_dequeue(&cell->napi_skbs);
+ skb = __skb_dequeue(&cell->napi_skbs);
if (!skb)
break;
-
+ spin_unlock(&cell->napi_skbs.lock);
napi_gro_receive(napi, skb);
work_done++;
+ spin_lock(&cell->napi_skbs.lock);
}
if (work_done < budget)
napi_complete(napi);
+ spin_unlock(&cell->napi_skbs.lock);
return work_done;
}
^ permalink raw reply related
* [net-next 6/7] bna: Firmware update
From: Rasesh Mody @ 2012-12-10 21:42 UTC (permalink / raw)
To: davem, netdev
Cc: bhutchings, David.Laight, adapter_linux_open_src_team,
Rasesh Mody
In-Reply-To: <1355175725-19202-1-git-send-email-rmody@brocade.com>
Change Details:
- Added Stats clear counter to the bfi_enet_stats_mac structure and
ethtool stats
- Modified the firmware naming convention to contain the firmware image
version (3.1.0.0). The new convention is
<firmware-image>-<firmware-version>.bin The change will enforce loading
only compatible firmware with this driver and also avoid over-writing
the old firmware image in-order to load new version driver as the
firmware names used to be the same.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/ethernet/brocade/bna/bfi_enet.h | 1 +
drivers/net/ethernet/brocade/bna/bnad_ethtool.c | 1 +
drivers/net/ethernet/brocade/bna/cna.h | 4 ++--
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/brocade/bna/bfi_enet.h b/drivers/net/ethernet/brocade/bna/bfi_enet.h
index eef6e1f..7d10e33 100644
--- a/drivers/net/ethernet/brocade/bna/bfi_enet.h
+++ b/drivers/net/ethernet/brocade/bna/bfi_enet.h
@@ -787,6 +787,7 @@ struct bfi_enet_stats_bpc {
/* MAC Rx Statistics */
struct bfi_enet_stats_mac {
+ u64 stats_clr_cnt; /* times this stats cleared */
u64 frame_64; /* both rx and tx counter */
u64 frame_65_127; /* both rx and tx counter */
u64 frame_128_255; /* both rx and tx counter */
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index 40e1e84..455b5a2 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -102,6 +102,7 @@ static const char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = {
"rx_unmap_q_alloc_failed",
"rxbuf_alloc_failed",
+ "mac_stats_clr_cnt",
"mac_frame_64",
"mac_frame_65_127",
"mac_frame_128_255",
diff --git a/drivers/net/ethernet/brocade/bna/cna.h b/drivers/net/ethernet/brocade/bna/cna.h
index 32e8f17..14ca931 100644
--- a/drivers/net/ethernet/brocade/bna/cna.h
+++ b/drivers/net/ethernet/brocade/bna/cna.h
@@ -37,8 +37,8 @@
extern char bfa_version[];
-#define CNA_FW_FILE_CT "ctfw.bin"
-#define CNA_FW_FILE_CT2 "ct2fw.bin"
+#define CNA_FW_FILE_CT "ctfw-3.1.0.0.bin"
+#define CNA_FW_FILE_CT2 "ct2fw-3.1.0.0.bin"
#define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */
#pragma pack(1)
--
1.7.1
^ permalink raw reply related
* [net-next 4/7] bna: Rx Page Based Allocation
From: Rasesh Mody @ 2012-12-10 21:42 UTC (permalink / raw)
To: davem, netdev
Cc: bhutchings, David.Laight, adapter_linux_open_src_team,
Rasesh Mody
In-Reply-To: <1355175725-19202-1-git-send-email-rmody@brocade.com>
Change Details:
Enhanced support for GRO. Page-base allocation method for Rx buffers is
used in GRO. Skb allocation has been removed in Rx path to use always warm-cache
skbs provided by napi_get_frags.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/ethernet/brocade/bna/bnad.c | 318 ++++++++++++++++++++++++------
drivers/net/ethernet/brocade/bna/bnad.h | 19 ++
2 files changed, 273 insertions(+), 64 deletions(-)
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index da5470a..22d52ef 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -266,53 +266,181 @@ bnad_msix_tx(int irq, void *data)
return IRQ_HANDLED;
}
+static inline void
+bnad_rxq_alloc_uninit(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_rx_unmap_q *unmap_q = rcb->unmap_q;
+
+ unmap_q->reuse_pi = -1;
+ unmap_q->alloc_order = -1;
+ unmap_q->map_size = 0;
+ unmap_q->type = BNAD_RXBUF_NONE;
+}
+
+/* Default is page-based allocation. Multi-buffer support - TBD */
+static int
+bnad_rxq_alloc_init(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_rx_unmap_q *unmap_q = rcb->unmap_q;
+ int mtu, order;
+
+ bnad_rxq_alloc_uninit(bnad, rcb);
+
+ mtu = bna_enet_mtu_get(&bnad->bna.enet);
+ order = get_order(mtu);
+
+ if (bna_is_small_rxq(rcb->id)) {
+ unmap_q->alloc_order = 0;
+ unmap_q->map_size = rcb->rxq->buffer_size;
+ } else {
+ unmap_q->alloc_order = order;
+ unmap_q->map_size =
+ (rcb->rxq->buffer_size > 2048) ?
+ PAGE_SIZE << order : 2048;
+ }
+
+ BUG_ON(((PAGE_SIZE << order) % unmap_q->map_size));
+
+ unmap_q->type = BNAD_RXBUF_PAGE;
+
+ return 0;
+}
+
+static inline void
+bnad_rxq_cleanup_page(struct bnad *bnad, struct bnad_rx_unmap *unmap)
+{
+ if (!unmap->page)
+ return;
+
+ dma_unmap_page(&bnad->pcidev->dev,
+ dma_unmap_addr(&unmap->vector, dma_addr),
+ unmap->vector.len, DMA_FROM_DEVICE);
+ put_page(unmap->page);
+ unmap->page = NULL;
+ dma_unmap_addr_set(&unmap->vector, dma_addr, 0);
+ unmap->vector.len = 0;
+}
+
+static inline void
+bnad_rxq_cleanup_skb(struct bnad *bnad, struct bnad_rx_unmap *unmap)
+{
+ if (!unmap->skb)
+ return;
+
+ dma_unmap_single(&bnad->pcidev->dev,
+ dma_unmap_addr(&unmap->vector, dma_addr),
+ unmap->vector.len, DMA_FROM_DEVICE);
+ dev_kfree_skb_any(unmap->skb);
+ unmap->skb = NULL;
+ dma_unmap_addr_set(&unmap->vector, dma_addr, 0);
+ unmap->vector.len = 0;
+}
+
static void
bnad_rxq_cleanup(struct bnad *bnad, struct bna_rcb *rcb)
{
- struct bnad_rx_unmap *unmap_q = rcb->unmap_q;
- struct sk_buff *skb;
+ struct bnad_rx_unmap_q *unmap_q = rcb->unmap_q;
int i;
for (i = 0; i < rcb->q_depth; i++) {
- struct bnad_rx_unmap *unmap = &unmap_q[i];
+ struct bnad_rx_unmap *unmap = &unmap_q->unmap[i];
- skb = unmap->skb;
- if (!skb)
- continue;
+ if (BNAD_RXBUF_IS_PAGE(unmap_q->type))
+ bnad_rxq_cleanup_page(bnad, unmap);
+ else
+ bnad_rxq_cleanup_skb(bnad, unmap);
+ }
+ bnad_rxq_alloc_uninit(bnad, rcb);
+}
- unmap->skb = NULL;
- dma_unmap_single(&bnad->pcidev->dev,
- dma_unmap_addr(&unmap->vector, dma_addr),
- unmap->vector.len, DMA_FROM_DEVICE);
- dma_unmap_addr_set(&unmap->vector, dma_addr, 0);
- unmap->vector.len = 0;
- dev_kfree_skb_any(skb);
+static u32
+bnad_rxq_refill_page(struct bnad *bnad, struct bna_rcb *rcb, u32 nalloc)
+{
+ u32 alloced, prod, q_depth;
+ struct bnad_rx_unmap_q *unmap_q = rcb->unmap_q;
+ struct bnad_rx_unmap *unmap, *prev;
+ struct bna_rxq_entry *rxent;
+ struct page *page;
+ u32 page_offset, alloc_size;
+ dma_addr_t dma_addr;
+
+ prod = rcb->producer_index;
+ q_depth = rcb->q_depth;
+
+ alloc_size = PAGE_SIZE << unmap_q->alloc_order;
+ alloced = 0;
+
+ while (nalloc--) {
+ unmap = &unmap_q->unmap[prod];
+
+ if (unmap_q->reuse_pi < 0) {
+ page = alloc_pages(GFP_ATOMIC | __GFP_COMP,
+ unmap_q->alloc_order);
+ page_offset = 0;
+ } else {
+ prev = &unmap_q->unmap[unmap_q->reuse_pi];
+ page = prev->page;
+ page_offset = prev->page_offset + unmap_q->map_size;
+ get_page(page);
+ }
+
+ if (unlikely(!page)) {
+ BNAD_UPDATE_CTR(bnad, rxbuf_alloc_failed);
+ rcb->rxq->rxbuf_alloc_failed++;
+ goto finishing;
+ }
+
+ dma_addr = dma_map_page(&bnad->pcidev->dev, page, page_offset,
+ unmap_q->map_size, DMA_FROM_DEVICE);
+
+ unmap->page = page;
+ unmap->page_offset = page_offset;
+ dma_unmap_addr_set(&unmap->vector, dma_addr, dma_addr);
+ unmap->vector.len = unmap_q->map_size;
+ page_offset += unmap_q->map_size;
+
+ if (page_offset < alloc_size)
+ unmap_q->reuse_pi = prod;
+ else
+ unmap_q->reuse_pi = -1;
+
+ rxent = &((struct bna_rxq_entry *)rcb->sw_q)[prod];
+ BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr);
+ BNA_QE_INDX_INC(prod, q_depth);
+ alloced++;
}
+
+finishing:
+ if (likely(alloced)) {
+ rcb->producer_index = prod;
+ smp_mb();
+ if (likely(test_bit(BNAD_RXQ_POST_OK, &rcb->flags)))
+ bna_rxq_prod_indx_doorbell(rcb);
+ }
+
+ return alloced;
}
-/* Allocate and post BNAD_RXQ_REFILL_THRESHOLD_SHIFT buffers at a time */
-static void
-bnad_rxq_post(struct bnad *bnad, struct bna_rcb *rcb)
+static u32
+bnad_rxq_refill_skb(struct bnad *bnad, struct bna_rcb *rcb, u32 nalloc)
{
- u32 to_alloc, alloced, prod, q_depth, buff_sz;
- struct bnad_rx_unmap *unmap_q = rcb->unmap_q;
+ u32 alloced, prod, q_depth, buff_sz;
+ struct bnad_rx_unmap_q *unmap_q = rcb->unmap_q;
struct bnad_rx_unmap *unmap;
struct bna_rxq_entry *rxent;
struct sk_buff *skb;
dma_addr_t dma_addr;
buff_sz = rcb->rxq->buffer_size;
- alloced = 0;
- to_alloc = BNA_QE_FREE_CNT(rcb, rcb->q_depth);
- if (!(to_alloc >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT))
- return;
-
prod = rcb->producer_index;
q_depth = rcb->q_depth;
- while (to_alloc--) {
- skb = netdev_alloc_skb_ip_align(bnad->netdev,
- buff_sz);
+ alloced = 0;
+ while (nalloc--) {
+ unmap = &unmap_q->unmap[prod];
+
+ skb = netdev_alloc_skb_ip_align(bnad->netdev, buff_sz);
+
if (unlikely(!skb)) {
BNAD_UPDATE_CTR(bnad, rxbuf_alloc_failed);
rcb->rxq->rxbuf_alloc_failed++;
@@ -320,13 +448,13 @@ bnad_rxq_post(struct bnad *bnad, struct bna_rcb *rcb)
}
dma_addr = dma_map_single(&bnad->pcidev->dev, skb->data,
buff_sz, DMA_FROM_DEVICE);
- rxent = &((struct bna_rxq_entry *)rcb->sw_q)[prod];
- BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr);
- unmap = &unmap_q[prod];
unmap->skb = skb;
dma_unmap_addr_set(&unmap->vector, dma_addr, dma_addr);
unmap->vector.len = buff_sz;
+
+ rxent = &((struct bna_rxq_entry *)rcb->sw_q)[prod];
+ BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr);
BNA_QE_INDX_INC(prod, q_depth);
alloced++;
}
@@ -338,6 +466,24 @@ finishing:
if (likely(test_bit(BNAD_RXQ_POST_OK, &rcb->flags)))
bna_rxq_prod_indx_doorbell(rcb);
}
+
+ return alloced;
+}
+
+static inline void
+bnad_rxq_post(struct bnad *bnad, struct bna_rcb *rcb)
+{
+ struct bnad_rx_unmap_q *unmap_q = rcb->unmap_q;
+ u32 to_alloc;
+
+ to_alloc = BNA_QE_FREE_CNT(rcb, rcb->q_depth);
+ if (!(to_alloc >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT))
+ return;
+
+ if (BNAD_RXBUF_IS_PAGE(unmap_q->type))
+ bnad_rxq_refill_page(bnad, rcb, to_alloc);
+ else
+ bnad_rxq_refill_skb(bnad, rcb, to_alloc);
}
#define flags_cksum_prot_mask (BNA_CQ_EF_IPV4 | BNA_CQ_EF_L3_CKSUM_OK | \
@@ -354,17 +500,62 @@ finishing:
#define flags_udp6 (BNA_CQ_EF_IPV6 | \
BNA_CQ_EF_UDP | BNA_CQ_EF_L4_CKSUM_OK)
+static inline struct sk_buff *
+bnad_cq_prepare_skb(struct bnad_rx_ctrl *rx_ctrl,
+ struct bnad_rx_unmap_q *unmap_q,
+ struct bnad_rx_unmap *unmap,
+ u32 length, u32 flags)
+{
+ struct bnad *bnad = rx_ctrl->bnad;
+ struct sk_buff *skb;
+
+ if (BNAD_RXBUF_IS_PAGE(unmap_q->type)) {
+ skb = napi_get_frags(&rx_ctrl->napi);
+ if (unlikely(!skb))
+ return NULL;
+
+ dma_unmap_page(&bnad->pcidev->dev,
+ dma_unmap_addr(&unmap->vector, dma_addr),
+ unmap->vector.len, DMA_FROM_DEVICE);
+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
+ unmap->page, unmap->page_offset, length);
+ skb->len += length;
+ skb->data_len += length;
+ skb->truesize += length;
+
+ unmap->page = NULL;
+ unmap->vector.len = 0;
+
+ return skb;
+ }
+
+ skb = unmap->skb;
+ BUG_ON(!skb);
+
+ dma_unmap_single(&bnad->pcidev->dev,
+ dma_unmap_addr(&unmap->vector, dma_addr),
+ unmap->vector.len, DMA_FROM_DEVICE);
+
+ skb_put(skb, length);
+
+ skb->protocol = eth_type_trans(skb, bnad->netdev);
+
+ unmap->skb = NULL;
+ unmap->vector.len = 0;
+ return skb;
+}
+
static u32
bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
{
- struct bna_cq_entry *cq, *cmpl, *next_cmpl;
+ struct bna_cq_entry *cq, *cmpl;
struct bna_rcb *rcb = NULL;
- struct bnad_rx_unmap *unmap_q, *unmap;
- unsigned int packets = 0;
+ struct bnad_rx_unmap_q *unmap_q;
+ struct bnad_rx_unmap *unmap;
struct sk_buff *skb;
- u32 flags, masked_flags;
struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
- struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
+ struct bnad_rx_ctrl *rx_ctrl = ccb->ctrl;
+ u32 packets = 0, length = 0, flags, masked_flags;
prefetch(bnad->netdev);
@@ -373,6 +564,8 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
while (cmpl->valid && (packets < budget)) {
packets++;
+ flags = ntohl(cmpl->flags);
+ length = ntohs(cmpl->length);
BNA_UPDATE_PKT_CNT(pkt_rt, ntohs(cmpl->length));
if (bna_is_small_rxq(cmpl->rxq_id))
@@ -381,32 +574,25 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
rcb = ccb->rcb[0];
unmap_q = rcb->unmap_q;
- unmap = &unmap_q[rcb->consumer_index];
+ unmap = &unmap_q->unmap[rcb->consumer_index];
- skb = unmap->skb;
- BUG_ON(!(skb));
- unmap->skb = NULL;
- dma_unmap_single(&bnad->pcidev->dev,
- dma_unmap_addr(&unmap->vector, dma_addr),
- unmap->vector.len, DMA_FROM_DEVICE);
- unmap->vector.len = 0;
- BNA_QE_INDX_INC(rcb->consumer_index, rcb->q_depth);
- BNA_QE_INDX_INC(ccb->producer_index, ccb->q_depth);
- next_cmpl = &cq[ccb->producer_index];
+ if (unlikely(flags & (BNA_CQ_EF_MAC_ERROR |
+ BNA_CQ_EF_FCS_ERROR |
+ BNA_CQ_EF_TOO_LONG))) {
+ if (BNAD_RXBUF_IS_PAGE(unmap_q->type))
+ bnad_rxq_cleanup_page(bnad, unmap);
+ else
+ bnad_rxq_cleanup_skb(bnad, unmap);
- prefetch(next_cmpl);
-
- flags = ntohl(cmpl->flags);
- if (unlikely
- (flags &
- (BNA_CQ_EF_MAC_ERROR | BNA_CQ_EF_FCS_ERROR |
- BNA_CQ_EF_TOO_LONG))) {
- dev_kfree_skb_any(skb);
rcb->rxq->rx_packets_with_error++;
goto next;
}
- skb_put(skb, ntohs(cmpl->length));
+ skb = bnad_cq_prepare_skb(ccb->ctrl, unmap_q, unmap,
+ length, flags);
+
+ if (unlikely(!skb))
+ break;
masked_flags = flags & flags_cksum_prot_mask;
@@ -421,22 +607,24 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
skb_checksum_none_assert(skb);
rcb->rxq->rx_packets++;
- rcb->rxq->rx_bytes += skb->len;
- skb->protocol = eth_type_trans(skb, bnad->netdev);
+ rcb->rxq->rx_bytes += length;
if (flags & BNA_CQ_EF_VLAN)
__vlan_hwaccel_put_tag(skb, ntohs(cmpl->vlan_tag));
- if (skb->ip_summed == CHECKSUM_UNNECESSARY)
- napi_gro_receive(&rx_ctrl->napi, skb);
+ if (BNAD_RXBUF_IS_PAGE(unmap_q->type))
+ napi_gro_frags(&rx_ctrl->napi);
else
netif_receive_skb(skb);
next:
cmpl->valid = 0;
- cmpl = next_cmpl;
+ BNA_QE_INDX_INC(rcb->consumer_index, rcb->q_depth);
+ BNA_QE_INDX_INC(ccb->producer_index, ccb->q_depth);
+ cmpl = &cq[ccb->producer_index];
}
+ napi_gro_flush(&rx_ctrl->napi, false);
if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
bna_ib_ack_disable_irq(ccb->i_dbell, packets);
@@ -956,8 +1144,7 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
struct bna_ccb *ccb;
struct bna_rcb *rcb;
struct bnad_rx_ctrl *rx_ctrl;
- int i;
- int j;
+ int i, j;
for (i = 0; i < BNAD_MAX_RXP_PER_RX; i++) {
rx_ctrl = &rx_info->rx_ctrl[i];
@@ -972,6 +1159,7 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
if (!rcb)
continue;
+ bnad_rxq_alloc_init(bnad, rcb);
set_bit(BNAD_RXQ_STARTED, &rcb->flags);
set_bit(BNAD_RXQ_POST_OK, &rcb->flags);
bnad_rxq_post(bnad, rcb);
@@ -1861,9 +2049,11 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
/* Fill Unmap Q memory requirements */
BNAD_FILL_UNMAPQ_MEM_REQ(&res_info[BNA_RX_RES_MEM_T_UNMAPQ],
- rx_config->num_paths + ((rx_config->rxp_type == BNA_RXP_SINGLE)
- ? 0 : rx_config->num_paths), (bnad->rxq_depth *
- sizeof(struct bnad_rx_unmap)));
+ rx_config->num_paths +
+ ((rx_config->rxp_type == BNA_RXP_SINGLE) ?
+ 0 : rx_config->num_paths),
+ ((bnad->rxq_depth * sizeof(struct bnad_rx_unmap)) +
+ sizeof(struct bnad_rx_unmap_q)));
/* Allocate resource */
err = bnad_rx_res_alloc(bnad, res_info, rx_id);
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index db132c9..134d534 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -233,10 +233,29 @@ struct bnad_rx_vector {
};
struct bnad_rx_unmap {
+ struct page *page;
+ u32 page_offset;
struct sk_buff *skb;
struct bnad_rx_vector vector;
};
+enum bnad_rxbuf_type {
+ BNAD_RXBUF_NONE = 0,
+ BNAD_RXBUF_SKB = 1,
+ BNAD_RXBUF_PAGE = 2,
+ BNAD_RXBUF_MULTI = 3
+};
+
+#define BNAD_RXBUF_IS_PAGE(_type) ((_type) == BNAD_RXBUF_PAGE)
+
+struct bnad_rx_unmap_q {
+ int reuse_pi;
+ int alloc_order;
+ u32 map_size;
+ enum bnad_rxbuf_type type;
+ struct bnad_rx_unmap unmap[0];
+};
+
/* Bit mask values for bnad->cfg_flags */
#define BNAD_CF_DIM_ENABLED 0x01 /* DIM */
#define BNAD_CF_PROMISC 0x02
--
1.7.1
^ permalink raw reply related
* [net-next 5/7] bna: Add RX State
From: Rasesh Mody @ 2012-12-10 21:42 UTC (permalink / raw)
To: davem, netdev
Cc: bhutchings, David.Laight, adapter_linux_open_src_team,
Rasesh Mody
In-Reply-To: <1355175725-19202-1-git-send-email-rmody@brocade.com>
Change Details:
- BNA state machine for Rx in start_wait state moves it to stop_wait on
receipt of RX_E_STOP. In Rx stop_wait state, on receipt of
RX_E_STARTED event does enet stop
RX_E_STOPPED event does rx_cleanup_cbfn
rx_cleanup_cbfn in this case is called without post_cbfn. post_cbfn
happens only after RX_E_STARTED event is received in start_wait. Without
doing post_cbfn, NAPI remains disabled and in cleanup we try to disable
again causing endless wait. ifconfig process and other workers can thus
get stuck.
- Introducing start_stop_wait state for Rx. This state handles the case of
if post_cbfn is not done simply do stop without the cleanup.
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/ethernet/brocade/bna/bna_tx_rx.c | 27 +++++++++++++++++++++++++-
1 files changed, 26 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/brocade/bna/bna_tx_rx.c b/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
index 4df6d4b..ea6f4a0 100644
--- a/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
+++ b/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
@@ -1355,6 +1355,8 @@ bfa_fsm_state_decl(bna_rx, stopped,
struct bna_rx, enum bna_rx_event);
bfa_fsm_state_decl(bna_rx, start_wait,
struct bna_rx, enum bna_rx_event);
+bfa_fsm_state_decl(bna_rx, start_stop_wait,
+ struct bna_rx, enum bna_rx_event);
bfa_fsm_state_decl(bna_rx, rxf_start_wait,
struct bna_rx, enum bna_rx_event);
bfa_fsm_state_decl(bna_rx, started,
@@ -1432,7 +1434,7 @@ static void bna_rx_sm_start_wait(struct bna_rx *rx,
{
switch (event) {
case RX_E_STOP:
- bfa_fsm_set_state(rx, bna_rx_sm_stop_wait);
+ bfa_fsm_set_state(rx, bna_rx_sm_start_stop_wait);
break;
case RX_E_FAIL:
@@ -1488,6 +1490,29 @@ bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
}
+static void
+bna_rx_sm_start_stop_wait_entry(struct bna_rx *rx)
+{
+}
+
+static void
+bna_rx_sm_start_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
+{
+ switch (event) {
+ case RX_E_FAIL:
+ case RX_E_STOPPED:
+ bfa_fsm_set_state(rx, bna_rx_sm_stopped);
+ break;
+
+ case RX_E_STARTED:
+ bna_rx_enet_stop(rx);
+ break;
+
+ default:
+ bfa_sm_fault(event);
+ }
+}
+
void
bna_rx_sm_started_entry(struct bna_rx *rx)
{
--
1.7.1
^ permalink raw reply related
* [net-next 7/7] bna: Driver Version Updated to 3.1.2.1
From: Rasesh Mody @ 2012-12-10 21:42 UTC (permalink / raw)
To: davem, netdev
Cc: bhutchings, David.Laight, adapter_linux_open_src_team,
Rasesh Mody
In-Reply-To: <1355175725-19202-1-git-send-email-rmody@brocade.com>
Signed-off-by: Rasesh Mody <rmody@brocade.com>
---
drivers/net/ethernet/brocade/bna/bnad.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index 134d534..72ba586 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -71,7 +71,7 @@ struct bnad_rx_ctrl {
#define BNAD_NAME "bna"
#define BNAD_NAME_LEN 64
-#define BNAD_VERSION "3.0.23.0"
+#define BNAD_VERSION "3.1.2.1"
#define BNAD_MAILBOX_MSIX_INDEX 0
#define BNAD_MAILBOX_MSIX_VECTORS 1
--
1.7.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