* [PATCH v3] net/smsc911x: add device tree probe support
From: Shawn Guo @ 2011-07-30 18:26 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: patches-QSEj5FYQhm4dnm+yROfE0A,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Steve Glendinning,
David S. Miller,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1311587040-8988-1-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
It adds device tree probe support for smsc911x driver.
Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
Cc: Steve Glendinning <steve.glendinning-sdUf+H5yV5I@public.gmane.org>
Cc: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Reviewed-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
---
Changes since v2:
* Fix a typo in smsc911x.txt
Changes since v1:
* Instead of getting irq line from gpio number, it use irq domain
to keep platform_get_resource(IORESOURCE_IRQ) works for dt too.
* Use 'lan9115' the first model that smsc911x supports in the match
table
* Use reg-shift and reg-io-width which already used in of_serial for
shift and access size binding
Documentation/devicetree/bindings/net/smsc911x.txt | 38 +++++++++
drivers/net/smsc911x.c | 85 +++++++++++++++++---
2 files changed, 112 insertions(+), 11 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/smsc911x.txt
diff --git a/Documentation/devicetree/bindings/net/smsc911x.txt b/Documentation/devicetree/bindings/net/smsc911x.txt
new file mode 100644
index 0000000..adb5b57
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/smsc911x.txt
@@ -0,0 +1,38 @@
+* Smart Mixed-Signal Connectivity (SMSC) LAN911x/912x Controller
+
+Required properties:
+- compatible : Should be "smsc,lan<model>", "smsc,lan9115"
+- reg : Address and length of the io space for SMSC LAN
+- interrupts : Should contain SMSC LAN interrupt line
+- interrupt-parent : Should be the phandle for the interrupt controller
+ that services interrupts for this device
+- phy-mode : String, operation mode of the PHY interface.
+ Supported values are: "mii", "gmii", "sgmii", "tbi", "rmii",
+ "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi", "smii".
+
+Optional properties:
+- reg-shift : Specify the quantity to shift the register offsets by
+- reg-io-width : Specify the size (in bytes) of the IO accesses that
+ should be performed on the device. Valid value for SMSC LAN is
+ 2 or 4. If it's omitted or invalid, the size would be 2.
+- smsc,irq-active-high : Indicates the IRQ polarity is active-high
+- smsc,irq-push-pull : Indicates the IRQ type is push-pull
+- smsc,force-internal-phy : Forces SMSC LAN controller to use
+ internal PHY
+- smsc,force-external-phy : Forces SMSC LAN controller to use
+ external PHY
+- smsc,save-mac-address : Indicates that mac address needs to be saved
+ before resetting the controller
+- local-mac-address : 6 bytes, mac address
+
+Examples:
+
+lan9220@f4000000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0xf4000000 0x2000000>;
+ phy-mode = "mii";
+ interrupt-parent = <&gpio1>;
+ interrupts = <31>;
+ reg-io-width = <4>;
+ smsc,irq-push-pull;
+};
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index b9016a3..75c08a5 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -53,6 +53,10 @@
#include <linux/phy.h>
#include <linux/smsc911x.h>
#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_net.h>
#include "smsc911x.h"
#define SMSC_CHIPNAME "smsc911x"
@@ -2095,8 +2099,58 @@ static const struct smsc911x_ops shifted_smsc911x_ops = {
.tx_writefifo = smsc911x_tx_writefifo_shift,
};
+#ifdef CONFIG_OF
+static int __devinit smsc911x_probe_config_dt(
+ struct smsc911x_platform_config *config,
+ struct device_node *np)
+{
+ const char *mac;
+ u32 width = 0;
+
+ if (!np)
+ return -ENODEV;
+
+ config->phy_interface = of_get_phy_mode(np);
+
+ mac = of_get_mac_address(np);
+ if (mac)
+ memcpy(config->mac, mac, ETH_ALEN);
+
+ of_property_read_u32(np, "reg-shift", &config->shift);
+
+ of_property_read_u32(np, "reg-io-width", &width);
+ if (width == 4)
+ config->flags |= SMSC911X_USE_32BIT;
+
+ if (of_get_property(np, "smsc,irq-active-high", NULL))
+ config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
+
+ if (of_get_property(np, "smsc,irq-push-pull", NULL))
+ config->irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL;
+
+ if (of_get_property(np, "smsc,force-internal-phy", NULL))
+ config->flags |= SMSC911X_FORCE_INTERNAL_PHY;
+
+ if (of_get_property(np, "smsc,force-external-phy", NULL))
+ config->flags |= SMSC911X_FORCE_EXTERNAL_PHY;
+
+ if (of_get_property(np, "smsc,save-mac-address", NULL))
+ config->flags |= SMSC911X_SAVE_MAC_ADDRESS;
+
+ return 0;
+}
+#else
+static inline int smsc911x_probe_config_dt(
+ struct smsc911x_platform_config *config,
+ struct device_node *np)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_OF */
+
static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
struct net_device *dev;
struct smsc911x_data *pdata;
struct smsc911x_platform_config *config = pdev->dev.platform_data;
@@ -2107,13 +2161,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
pr_info("Driver version %s\n", SMSC_DRV_VERSION);
- /* platform data specifies irq & dynamic bus configuration */
- if (!pdev->dev.platform_data) {
- pr_warn("platform_data not provided\n");
- retval = -ENODEV;
- goto out_0;
- }
-
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"smsc911x-memory");
if (!res)
@@ -2152,9 +2199,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
pdata->ioaddr = ioremap_nocache(res->start, res_size);
- /* copy config parameters across to pdata */
- memcpy(&pdata->config, config, sizeof(pdata->config));
-
pdata->dev = dev;
pdata->msg_enable = ((1 << debug) - 1);
@@ -2164,10 +2208,22 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
goto out_free_netdev_2;
}
+ retval = smsc911x_probe_config_dt(&pdata->config, np);
+ if (retval && config) {
+ /* copy config parameters across to pdata */
+ memcpy(&pdata->config, config, sizeof(pdata->config));
+ retval = 0;
+ }
+
+ if (retval) {
+ SMSC_WARN(pdata, probe, "Error smsc911x config not found");
+ goto out_unmap_io_3;
+ }
+
/* assume standard, non-shifted, access to HW registers */
pdata->ops = &standard_smsc911x_ops;
/* apply the right access if shifting is needed */
- if (config->shift)
+ if (pdata->config.shift)
pdata->ops = &shifted_smsc911x_ops;
retval = smsc911x_init(dev);
@@ -2314,6 +2370,12 @@ static const struct dev_pm_ops smsc911x_pm_ops = {
#define SMSC911X_PM_OPS NULL
#endif
+static const struct of_device_id smsc911x_dt_ids[] = {
+ { .compatible = "smsc,lan9115", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
+
static struct platform_driver smsc911x_driver = {
.probe = smsc911x_drv_probe,
.remove = __devexit_p(smsc911x_drv_remove),
@@ -2321,6 +2383,7 @@ static struct platform_driver smsc911x_driver = {
.name = SMSC_CHIPNAME,
.owner = THIS_MODULE,
.pm = SMSC911X_PM_OPS,
+ .of_match_table = smsc911x_dt_ids,
},
};
--
1.7.4.1
^ permalink raw reply related
* (unknown)
From: Swiss Lotto Netherlands @ 2011-07-25 23:56 UTC (permalink / raw)
--
You have been awarded 850,000.00 Euros in the Swiss Lotto Netherlands. kindly
respond via mail: fiduswissnl@live.com
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
^ permalink raw reply
* Re: [PATCH] net: filter: Convert the BPF VM to threaded code
From: Francois Romieu @ 2011-07-30 9:55 UTC (permalink / raw)
To: Rui Ueyama; +Cc: Eric Dumazet, netdev
In-Reply-To: <CACKH++afaAaa7a6ViYjo_PjpF1bXYtOuJaa-4umEOSVgW1+g3w@mail.gmail.com>
Rui Ueyama <rui314@gmail.com> :
> The result of benchmark looks good.
So far the overall improvement is below 2% (upper bound, without calculator).
And the result of benchmark without tcpdump looks strange.
> A simple benchmark that sends 10M UDP
> packets to lo took 76.24 seconds on average on Core 2 Duo L7500@1.6GHz.when
> tcpdump is running. With this patch it took 75.41 seconds, which means we save
> 80ns for each packet on that processor.
You forgot to analyze the figures without tcpdump.
> I think converting the VM to threaded code is low hanging fruit, even
> if we'd have JIT compilers for popular architectures. Most of the lines
> in my patch are indentation change, so the actual change is not big.
Without further data nor plan for future / possible improvements, it
could be said a gratuitous rewrite too.
--
Ueimor
^ permalink raw reply
* Re: special handling before ndo_start_xmit() been invoked
From: jiangtao.jit @ 2011-07-30 8:24 UTC (permalink / raw)
To: Jiri Pirko; +Cc: netdev
In-Reply-To: <201107271848349537853@gmail.com>
Jiri:
1. do some filter rules implemented in an externl module
without NF_HOOK on a bridge
2. output skb through NIC and virtual net_devices
3. mirror a port
and so on.
2011-07-30
jiangtao.jit
发件人: Jiri Pirko
发送时间: 2011-07-29 03:38:03
收件人: jiangtao.jit
抄送: netdev
主题: Re: special handling before ndo_start_xmit() been invoked
What would you want to achieve with that?
Wed, Jul 27, 2011 at 12:48:37PM CEST, jiangtao.jit@gmail.com wrote:
>Hi all:
>
>in struct net_device
>there is a function pointer rx_handler_func_t __rcu *rx_handler
>it's very convenient to register a function in an externel module
>and do some special handlings
>
>so i think what about to add an tx_handler_func
>before ndo_start_xmit() been invoked
>and do some special things before transmit
>
>is it necessary or there is already some other better methods to achieve this goal ?
>Thank you all
>
>-------
>2011-07-27
>jiangtao.jit
>
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] sunrpc: use better NUMA affinities
From: Eric Dumazet @ 2011-07-30 6:23 UTC (permalink / raw)
To: NeilBrown
Cc: J. Bruce Fields, Greg Banks, Christoph Hellwig,
linux-nfs@vger.kernel.org, David Miller, linux-kernel, netdev
In-Reply-To: <20110730160610.0b751ffd@notabene.brown>
Le samedi 30 juillet 2011 à 16:06 +1000, NeilBrown a écrit :
> umount /proc/fs/nfsd
>
>
Thans a lot, this was the thing I missed !
^ permalink raw reply
* Re: [PATCH] net: filter: Convert the BPF VM to threaded code
From: Eric Dumazet @ 2011-07-30 6:20 UTC (permalink / raw)
To: Rui Ueyama; +Cc: netdev
In-Reply-To: <1312005899.2873.70.camel@edumazet-laptop>
Le samedi 30 juillet 2011 à 08:04 +0200, Eric Dumazet a écrit :
> We can remove one branch per BPF instruction with following patch :
>
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 36f975f..377f3ca 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -119,16 +119,14 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
> u32 tmp;
> int k;
>
> + fentry--;
> /*
> * Process array of filter instructions.
> */
> - for (;; fentry++) {
> -#if defined(CONFIG_X86_32)
> + for (;;) {
> #define K (fentry->k)
> -#else
> - const u32 K = fentry->k;
> -#endif
>
> + fentry++;
> switch (fentry->code) {
> case BPF_S_ALU_ADD_X:
> A += X;
>
>
BTW, I tried to add one unreachable() in the default: branch, and gcc
4.5.2 generates interesting code :
It still does the compare and test, but both branches ends on same
location :
348: 83 c3 08 add $0x8,%ebx
34b: 66 83 3b 37 cmpw $0x37,(%ebx)
34f: 76 07 jbe 358 <sk_run_filter+0x28>
351: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
358: 0f b7 03 movzwl (%ebx),%eax
35b: ff 24 85 34 01 00 00 jmp *0x134(,%eax,4)
On a 64bit build and gcc 4.1.2, it even generates an infinite loop
730: 66 83 3b 37 cmpw $0x37,(%rbx)
734: 76 02 jbe 738 <sk_run_filter+0x28>
736: eb fe jmp 736 <sk_run_filter+0x26>
738: 0f b7 03 movzwl (%rbx),%eax
73b: ff 24 c5 00 00 00 00 jmpq *0x0(,%rax,8)
diff --git a/net/core/filter.c b/net/core/filter.c
index 36f975f..89221e7 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -122,13 +122,11 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
/*
* Process array of filter instructions.
*/
- for (;; fentry++) {
-#if defined(CONFIG_X86_32)
+ fentry--;
+ for (;;) {
#define K (fentry->k)
-#else
- const u32 K = fentry->k;
-#endif
+ fentry++;
switch (fentry->code) {
case BPF_S_ALU_ADD_X:
A += X;
@@ -351,6 +349,7 @@ load_b:
continue;
}
default:
+ unreachable();
WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n",
fentry->code, fentry->jt,
fentry->jf, fentry->k);
^ permalink raw reply related
* Re: [PATCH] net: filter: Convert the BPF VM to threaded code
From: Eric Dumazet @ 2011-07-30 6:04 UTC (permalink / raw)
To: Rui Ueyama; +Cc: netdev
In-Reply-To: <CACKH++afaAaa7a6ViYjo_PjpF1bXYtOuJaa-4umEOSVgW1+g3w@mail.gmail.com>
Le vendredi 29 juillet 2011 à 22:09 -0700, Rui Ueyama a écrit :
> The result of benchmark looks good. A simple benchmark that sends 10M UDP
> packets to lo took 76.24 seconds on average on Core 2 Duo L7500@1.6GHz.when
> tcpdump is running. With this patch it took 75.41 seconds, which means we save
> 80ns for each packet on that processor.
>
> I think converting the VM to threaded code is low hanging fruit, even
> if we'd have
> JIT compilers for popular architectures. Most of the lines in my patch
> are indentation
> change, so the actual change is not big.
>
...
> Tcpdump I used is this: tcpdump -p -n -s -i lo net 192.168.2.0/24
>
Thanks for providing numbers. Was it on 32 or 64bit kernel ?
Have you done a test with a cold instruction cache ?
Your patch adds 540 bytes of code, so its a potential latency increase.
# size net/core/filter.o net/core/filter.o.old
text data bss dec hex filename
4243 0 0 4243 1093 net/core/filter.o
3703 24 0 3727 e8f net/core/filter.o.old
Each 'NEXT' translates to :
4db: 83 c3 08 add $0x8,%ebx
4de: 0f b7 03 movzwl (%ebx),%eax
4e1: 8b 04 85 00 02 00 00 mov 0x200(,%eax,4),%eax
4e8: ff e0 jmp *%eax
And this is on i386, expect more on cpus with 32bit fixed
instructions ...
We can remove one branch per BPF instruction with following patch :
diff --git a/net/core/filter.c b/net/core/filter.c
index 36f975f..377f3ca 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -119,16 +119,14 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
u32 tmp;
int k;
+ fentry--;
/*
* Process array of filter instructions.
*/
- for (;; fentry++) {
-#if defined(CONFIG_X86_32)
+ for (;;) {
#define K (fentry->k)
-#else
- const u32 K = fentry->k;
-#endif
+ fentry++;
switch (fentry->code) {
case BPF_S_ALU_ADD_X:
A += X;
^ permalink raw reply related
* Re: [PATCH] sunrpc: use better NUMA affinities
From: NeilBrown @ 2011-07-30 6:06 UTC (permalink / raw)
To: Eric Dumazet
Cc: J. Bruce Fields, Greg Banks, Christoph Hellwig,
linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, David Miller,
linux-kernel, netdev
In-Reply-To: <1311998914.2873.27.camel@edumazet-laptop>
On Sat, 30 Jul 2011 06:08:34 +0200 Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:
> Le vendredi 29 juillet 2011 à 19:48 -0400, J. Bruce Fields a écrit :
> > On Sat, Jul 30, 2011 at 09:30:25AM +1000, NeilBrown wrote:
> > >
> > > rpc.nfsd 0
> > >
> > > will stop all nfsd threads. Follow with
> > >
> > > exportfs -f
> > >
> > > and you should be done. I'm not 100% sure about the nfsv4 thread though -
> > > would need to check.
> >
> > Should be fine.
> >
>
> What are the needed steps to be able to unload nfsd module ?
>
> So far, I am unable to perform this without using -f option.
>
>
>
>
Kill all nfsd threads.
This can be done with 'kill' or 'rpc.nfsd 0' or
echo 0 > /proc/fs/nfsd/threads
kill mountd
killall rpc.mountd
kill idmapd
unexport everything.
This can be done with 'exportfs -f' and checked by
grep . /proc/net/rpc/*/content
this should only contain comments
unmount the 'nfsd' filesystem
umount /proc/fs/nfsd
rmmod nfsd
(it look me ages to remember idmapd - but
lsof /proc/net/rpc/*/*
gave it away)
NeilBrown
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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
* Re: [Bugme-new] [Bug 39372] New: Problems with HFSC Scheduler
From: Eric Dumazet @ 2011-07-30 5:22 UTC (permalink / raw)
To: Patrick McHardy, David Miller
Cc: Michal Soltys, Andrew Morton, netdev, bugme-daemon,
Jamal Hadi Salim, lucas.bocchi, 631945, 00bormoj, fdelawarde
In-Reply-To: <4E32BF87.6010909@trash.net>
Le vendredi 29 juillet 2011 à 16:11 +0200, Patrick McHardy a écrit :
> Yeah, that seems to be the correct fix, thanks for looking into this.
Thanks Patrick, here is the official patch submission then ;)
[PATCH] sch_sfq: fix sfq_enqueue()
commit 8efa88540635 (sch_sfq: avoid giving spurious NET_XMIT_CN signals)
forgot to call qdisc_tree_decrease_qlen() to signal upper levels that a
packet (from another flow) was dropped, leading to various problems.
With help from Michal Soltys and Michal Pokrywka, who did a bisection.
Bugzilla ref: https://bugzilla.kernel.org/show_bug.cgi?id=39372
Debian ref: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=631945
Reported-by: Lucas Bocchi <lucas.bocchi@gmail.com>
Reported-and-bisected-by: Michal Pokrywka <wolfmoon@o2.pl>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Michal Soltys <soltys@ziu.info>
Acked-by: Patrick McHardy <kaber@trash.net>
---
net/sched/sch_sfq.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 4536ee6..2a2d287 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
/* Return Congestion Notification only if we dropped a packet
* from this flow.
*/
- return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS;
+ if (qlen != slot->qlen)
+ return NET_XMIT_CN;
+
+ /* As we dropped a packet, better let upper stack know this */
+ qdisc_tree_decrease_qlen(sch, 1);
+ return NET_XMIT_SUCCESS;
}
static struct sk_buff *
^ permalink raw reply related
* Re: [PATCH] net: filter: Convert the BPF VM to threaded code
From: Rui Ueyama @ 2011-07-30 5:09 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1311931816.2843.3.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
The result of benchmark looks good. A simple benchmark that sends 10M UDP
packets to lo took 76.24 seconds on average on Core 2 Duo L7500@1.6GHz.when
tcpdump is running. With this patch it took 75.41 seconds, which means we save
80ns for each packet on that processor.
I think converting the VM to threaded code is low hanging fruit, even
if we'd have
JIT compilers for popular architectures. Most of the lines in my patch
are indentation
change, so the actual change is not big.
Vanilla kernel:
(without tcpdump)
ruiu@blue:~$ time ./udpflood 10000000
real 0m57.909s
user 0m1.368s
sys 0m56.484s
ruiu@blue:~$ time ./udpflood 10000000
real 0m57.686s
user 0m1.360s
sys 0m56.288s
ruiu@blue:~$ time ./udpflood 10000000
real 0m58.457s
user 0m1.300s
sys 0m57.116s
(with tcpdump)
ruiu@blue:~$ time ./udpflood 10000000
real 1m16.025s
user 0m1.464s
sys 1m14.505s
ruiu@blue:~$ time ./udpflood 10000000
real 1m15.860s
user 0m1.232s
sys 1m14.573s
ruiu@blue:~$ time ./udpflood 10000000
real 1m16.861s
user 0m1.504s
sys 1m15.301s
Kernel with the patch:
(without tcpdump)
ruiu@blue:~$ time ./udpflood 10000000
real 0m59.272s
user 0m1.308s
sys 0m57.924s
ruiu@blue:~$ time ./udpflood 10000000
real 0m59.624s
user 0m1.336s
sys 0m58.244s
ruiu@blue:~$ time ./udpflood 10000000
real 0m59.340s
user 0m1.240s
sys 0m58.056s
(with tcpdump)
ruiu@blue:~$ time ./udpflood 10000000
real 1m15.392s
user 0m1.372s
sys 1m13.965s
ruiu@blue:~$ time ./udpflood 10000000
real 1m15.352s
user 0m1.452s
sys 1m13.845s
ruiu@blue:~$ time ./udpflood 10000000
real 1m15.508s
user 0m1.464s
sys 1m13.989s
Tcpdump I used is this: tcpdump -p -n -s -i lo net 192.168.2.0/24
On Fri, Jul 29, 2011 at 2:30 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le vendredi 29 juillet 2011 à 01:10 -0700, Rui Ueyama a écrit :
>> Convert the BPF VM to threaded code to improve performance.
>>
>> The BPF VM is basically a big for loop containing a switch statement. That is
>> slow because for each instruction it checks the for loop condition and does the
>> conditional branch of the switch statement.
>>
>> This patch eliminates the conditional branch, by replacing it with jump table
>> using GCC's labels-as-values feature. The for loop condition check can also be
>> removed, because the filter code always end with a RET instruction.
>>
>
> Well...
>
>
>> +#define NEXT goto *jump_table[(++fentry)->code]
>> +
>> + /* Dispatch the first instruction */
>> + goto *jump_table[fentry->code];
>
> This is the killer, as this cannot be predicted by the cpu.
>
> Do you have benchmark results to provide ?
>
> We now have BPF JIT on x86_64 and powerpc, and possibly on MIPS and ARM
> on a near future.
>
>
>
>
^ permalink raw reply
* Re: PROBLEM: BUG (NULL ptr dereference in ipv4_dst_check)
From: Eric Dumazet @ 2011-07-30 5:00 UTC (permalink / raw)
To: David Miller; +Cc: synapse, netdev
In-Reply-To: <1311954208.2843.31.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Le vendredi 29 juillet 2011 à 17:43 +0200, Eric Dumazet a écrit :
> Oh well, we already use RCU in neigh_destroy(), so adding rcu would need
> to change all dst_get_neighbour() callers to be in one rcu_read_lock()
> section.
>
> I'll take a look, I suspect its mostly already done.
>
>
Here is the patch I finally cooked and tested.
Could you please test it as well Gergely ?
Thanks !
[PATCH] net: fix NULL dereferences in check_peer_redir()
Gergely Kalman reported crashes in check_peer_redir().
It appears commit f39925dbde778 (ipv4: Cache learned redirect
information in inetpeer.) added a race, leading to possible NULL ptr
dereference.
Since we can now change dst neighbour, we should make sure a reader can
safely use a neighbour.
Add RCU protection to dst neighbour, and make sure check_peer_redir()
can be called safely by different cpus in parallel.
As neighbours are already freed after one RCU grace period, this patch
should not add typical RCU penalty (cache cold effects)
Many thanks to Gergely for providing a pretty report pointing to the
bug.
Reported-by: Gergely Kalman <synapse@hippy.csoma.elte.hu>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/net/dst.h | 17 +++++++++++++----
net/ipv4/ip_output.c | 10 ++++++++--
net/ipv4/route.c | 14 ++++++++------
net/ipv6/addrconf.c | 2 +-
net/ipv6/ip6_fib.c | 2 +-
net/ipv6/ip6_output.c | 13 +++++++++++--
net/ipv6/route.c | 35 +++++++++++++++++++++++++----------
7 files changed, 67 insertions(+), 26 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 29e2557..13d507d 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -37,7 +37,7 @@ struct dst_entry {
unsigned long _metrics;
unsigned long expires;
struct dst_entry *path;
- struct neighbour *_neighbour;
+ struct neighbour __rcu *_neighbour;
#ifdef CONFIG_XFRM
struct xfrm_state *xfrm;
#else
@@ -88,12 +88,17 @@ struct dst_entry {
static inline struct neighbour *dst_get_neighbour(struct dst_entry *dst)
{
- return dst->_neighbour;
+ return rcu_dereference(dst->_neighbour);
+}
+
+static inline struct neighbour *dst_get_neighbour_raw(struct dst_entry *dst)
+{
+ return rcu_dereference_raw(dst->_neighbour);
}
static inline void dst_set_neighbour(struct dst_entry *dst, struct neighbour *neigh)
{
- dst->_neighbour = neigh;
+ rcu_assign_pointer(dst->_neighbour, neigh);
}
extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
@@ -382,8 +387,12 @@ static inline void dst_rcu_free(struct rcu_head *head)
static inline void dst_confirm(struct dst_entry *dst)
{
if (dst) {
- struct neighbour *n = dst_get_neighbour(dst);
+ struct neighbour *n;
+
+ rcu_read_lock();
+ n = dst_get_neighbour(dst);
neigh_confirm(n);
+ rcu_read_unlock();
}
}
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index ccaaa85..77d3ede 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -204,9 +204,15 @@ static inline int ip_finish_output2(struct sk_buff *skb)
skb = skb2;
}
+ rcu_read_lock();
neigh = dst_get_neighbour(dst);
- if (neigh)
- return neigh_output(neigh, skb);
+ if (neigh) {
+ int res = neigh_output(neigh, skb);
+
+ rcu_read_unlock();
+ return res;
+ }
+ rcu_read_unlock();
if (net_ratelimit())
printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 1730689..6afc4eb 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1628,16 +1628,18 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
{
struct rtable *rt = (struct rtable *) dst;
__be32 orig_gw = rt->rt_gateway;
- struct neighbour *n;
+ struct neighbour *n, *old_n;
dst_confirm(&rt->dst);
- neigh_release(dst_get_neighbour(&rt->dst));
- dst_set_neighbour(&rt->dst, NULL);
-
rt->rt_gateway = peer->redirect_learned.a4;
- rt_bind_neighbour(rt);
- n = dst_get_neighbour(&rt->dst);
+
+ n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
+ if (IS_ERR(n))
+ return PTR_ERR(n);
+ old_n = xchg(&rt->dst._neighbour, n);
+ if (old_n)
+ neigh_release(old_n);
if (!n || !(n->nud_state & NUD_VALID)) {
if (n)
neigh_event_send(n, NULL);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a55500c..f012ebd 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
* layer address of our nexhop router
*/
- if (dst_get_neighbour(&rt->dst) == NULL)
+ if (dst_get_neighbour_raw(&rt->dst) == NULL)
ifa->flags &= ~IFA_F_OPTIMISTIC;
ifa->idev = idev;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 54a4678..320d91d 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1455,7 +1455,7 @@ static int fib6_age(struct rt6_info *rt, void *arg)
RT6_TRACE("aging clone %p\n", rt);
return -1;
} else if ((rt->rt6i_flags & RTF_GATEWAY) &&
- (!(dst_get_neighbour(&rt->dst)->flags & NTF_ROUTER))) {
+ (!(dst_get_neighbour_raw(&rt->dst)->flags & NTF_ROUTER))) {
RT6_TRACE("purging route %p via non-router but gateway\n",
rt);
return -1;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 32e5339..4c882cf 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -135,10 +135,15 @@ static int ip6_finish_output2(struct sk_buff *skb)
skb->len);
}
+ rcu_read_lock();
neigh = dst_get_neighbour(dst);
- if (neigh)
- return neigh_output(neigh, skb);
+ if (neigh) {
+ int res = neigh_output(neigh, skb);
+ rcu_read_unlock();
+ return res;
+ }
+ rcu_read_unlock();
IP6_INC_STATS_BH(dev_net(dst->dev),
ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
kfree_skb(skb);
@@ -975,12 +980,14 @@ static int ip6_dst_lookup_tail(struct sock *sk,
* dst entry and replace it instead with the
* dst entry of the nexthop router
*/
+ rcu_read_lock();
n = dst_get_neighbour(*dst);
if (n && !(n->nud_state & NUD_VALID)) {
struct inet6_ifaddr *ifp;
struct flowi6 fl_gw6;
int redirect;
+ rcu_read_unlock();
ifp = ipv6_get_ifaddr(net, &fl6->saddr,
(*dst)->dev, 1);
@@ -1000,6 +1007,8 @@ static int ip6_dst_lookup_tail(struct sock *sk,
if ((err = (*dst)->error))
goto out_err_release;
}
+ } else {
+ rcu_read_unlock();
}
#endif
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index e8987da..9e69eb0 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -364,7 +364,7 @@ out:
#ifdef CONFIG_IPV6_ROUTER_PREF
static void rt6_probe(struct rt6_info *rt)
{
- struct neighbour *neigh = rt ? dst_get_neighbour(&rt->dst) : NULL;
+ struct neighbour *neigh;
/*
* Okay, this does not seem to be appropriate
* for now, however, we need to check if it
@@ -373,8 +373,10 @@ static void rt6_probe(struct rt6_info *rt)
* Router Reachability Probe MUST be rate-limited
* to no more than one per minute.
*/
+ rcu_read_lock();
+ neigh = rt ? dst_get_neighbour(&rt->dst) : NULL;
if (!neigh || (neigh->nud_state & NUD_VALID))
- return;
+ goto out;
read_lock_bh(&neigh->lock);
if (!(neigh->nud_state & NUD_VALID) &&
time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) {
@@ -387,8 +389,11 @@ static void rt6_probe(struct rt6_info *rt)
target = (struct in6_addr *)&neigh->primary_key;
addrconf_addr_solict_mult(target, &mcaddr);
ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL);
- } else
+ } else {
read_unlock_bh(&neigh->lock);
+ }
+out:
+ rcu_read_unlock();
}
#else
static inline void rt6_probe(struct rt6_info *rt)
@@ -412,8 +417,11 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif)
static inline int rt6_check_neigh(struct rt6_info *rt)
{
- struct neighbour *neigh = dst_get_neighbour(&rt->dst);
+ struct neighbour *neigh;
int m;
+
+ rcu_read_lock();
+ neigh = dst_get_neighbour(&rt->dst);
if (rt->rt6i_flags & RTF_NONEXTHOP ||
!(rt->rt6i_flags & RTF_GATEWAY))
m = 1;
@@ -430,6 +438,7 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
read_unlock_bh(&neigh->lock);
} else
m = 0;
+ rcu_read_unlock();
return m;
}
@@ -769,7 +778,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
rt->rt6i_dst.plen = 128;
rt->rt6i_flags |= RTF_CACHE;
rt->dst.flags |= DST_HOST;
- dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour(&ort->dst)));
+ dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_raw(&ort->dst)));
}
return rt;
}
@@ -803,7 +812,7 @@ restart:
dst_hold(&rt->dst);
read_unlock_bh(&table->tb6_lock);
- if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
+ if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
else if (!(rt->dst.flags & DST_HOST))
nrt = rt6_alloc_clone(rt, &fl6->daddr);
@@ -1587,7 +1596,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
dst_confirm(&rt->dst);
/* Duplicate redirect: silently ignore. */
- if (neigh == dst_get_neighbour(&rt->dst))
+ if (neigh == dst_get_neighbour_raw(&rt->dst))
goto out;
nrt = ip6_rt_copy(rt, dest);
@@ -1682,7 +1691,7 @@ again:
1. It is connected route. Action: COW
2. It is gatewayed route or NONEXTHOP route. Action: clone it.
*/
- if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
+ if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
nrt = rt6_alloc_cow(rt, daddr, saddr);
else
nrt = rt6_alloc_clone(rt, daddr);
@@ -2326,6 +2335,7 @@ static int rt6_fill_node(struct net *net,
struct nlmsghdr *nlh;
long expires;
u32 table;
+ struct neighbour *n;
if (prefix) { /* user wants prefix routes only */
if (!(rt->rt6i_flags & RTF_PREFIX_RT)) {
@@ -2414,8 +2424,11 @@ static int rt6_fill_node(struct net *net,
if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
goto nla_put_failure;
- if (dst_get_neighbour(&rt->dst))
- NLA_PUT(skb, RTA_GATEWAY, 16, &dst_get_neighbour(&rt->dst)->primary_key);
+ rcu_read_lock();
+ n = dst_get_neighbour(&rt->dst);
+ if (n)
+ NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key);
+ rcu_read_unlock();
if (rt->dst.dev)
NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
@@ -2608,12 +2621,14 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
#else
seq_puts(m, "00000000000000000000000000000000 00 ");
#endif
+ rcu_read_lock();
n = dst_get_neighbour(&rt->dst);
if (n) {
seq_printf(m, "%pi6", n->primary_key);
} else {
seq_puts(m, "00000000000000000000000000000000");
}
+ rcu_read_unlock();
seq_printf(m, " %08x %08x %08x %08x %8s\n",
rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
rt->dst.__use, rt->rt6i_flags,
^ permalink raw reply related
* [PATCH] net: add kerneldoc to skb_copy_bits()
From: Eric Dumazet @ 2011-07-30 4:37 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Since skb_copy_bits() is called from assembly, add a fat comment to make
clear we should think twice before changing its prototype.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/core/skbuff.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2beda82..d6c2958 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1369,8 +1369,21 @@ pull_pages:
}
EXPORT_SYMBOL(__pskb_pull_tail);
-/* Copy some data bits from skb to kernel buffer. */
-
+/**
+ * skb_copy_bits - copy bits from skb to kernel buffer
+ * @skb: source skb
+ * @offset: offset in source
+ * @to: destination buffer
+ * @len: number of bytes to copy
+ *
+ * Copy the specified number of bytes from the source skb to the
+ * destination buffer.
+ *
+ * CAUTION ! :
+ * If its prototype is ever changed,
+ * check arch/{*}/net/{*}.S files,
+ * since it is called from BPF assembly code.
+ */
int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
{
int start = skb_headlen(skb);
^ permalink raw reply related
* Re: [PATCH] sunrpc: use better NUMA affinities
From: Eric Dumazet @ 2011-07-30 4:08 UTC (permalink / raw)
To: J. Bruce Fields
Cc: NeilBrown, Greg Banks, Christoph Hellwig,
linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, David Miller,
linux-kernel, netdev
In-Reply-To: <20110729234857.GA30941-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
Le vendredi 29 juillet 2011 à 19:48 -0400, J. Bruce Fields a écrit :
> On Sat, Jul 30, 2011 at 09:30:25AM +1000, NeilBrown wrote:
> >
> > rpc.nfsd 0
> >
> > will stop all nfsd threads. Follow with
> >
> > exportfs -f
> >
> > and you should be done. I'm not 100% sure about the nfsv4 thread though -
> > would need to check.
>
> Should be fine.
>
What are the needed steps to be able to unload nfsd module ?
So far, I am unable to perform this without using -f option.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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
* Re: [RFC net-next PATCH 1/4] pci: Add flag indicating device has been assigned by KVM
From: Jeff Kirsher @ 2011-07-30 4:00 UTC (permalink / raw)
To: Konrad Rzeszutek Wilk
Cc: Rose, Gregory V, Ian Campbell, netdev@vger.kernel.org,
davem@davemloft.net, bhutchings@solarflare.com, Jesse Barnes,
linux-pci@vger.kernel.org
In-Reply-To: <20110729165446.GA6731@dumpdata.com>
On Fri, Jul 29, 2011 at 09:54, Konrad Rzeszutek Wilk
<konrad.wilk@oracle.com> wrote:
>> > > > On Wed, 2011-07-27 at 15:17 -0700, Greg Rose wrote:
>> > > > > Device drivers that create and destroy SR-IOV virtual functions via
>> > > > > calls to pci_enable_sriov() and pci_disable_sriov can cause
>> > catastrophic
>> > > > > failures if they attempt to destroy VFs while they are assigned to
>> > > > > guest virtual machines. By adding a flag for use by the KVM module
>> > > > > to indicate that a device is assigned a device driver can check that
>> > > > > flag and avoid destroying VFs while they are assigned and avoid
>> > system
>> > > > > failures.
>> OK, but I hope Xen can still use the dev_flag assignment bit.
>
> Yeah, I think the attached patch would do it, but I need to double check it.
> Do you have a git tree with this patchset?
Not yet, Greg was send these patches out as a RFC to make sure this
was the correct direction to go.
>
> Um, so you are fixing up ixgbe only - what about the cxgb4 and be driver?
> Shouldn't they also get some of this treatment?
>
Yes, Greg made changes to ixgbe to give an idea of what changes would
need to be made with the suggested changes. From the feedback Greg
received, there is definite changes needed. When Greg gets finished
with the necessary changes to the kernel/ethtool, we will have a
better idea of what changes are needed for the drivers.
--
Cheers,
Jeff
^ permalink raw reply
* [PATCH 2/2] ipg: Use const
From: Joe Perches @ 2011-07-30 2:38 UTC (permalink / raw)
To: Francois Romieu, Sorbica Shieh; +Cc: netdev, linux-kernel
In-Reply-To: <2ee87bfccbbb5cf1776df6751b65e4a3110019f4.1311993468.git.joe@perches.com>
Make a couple of declarations const to save some data space.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/ipg.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 3aefaad..b470281 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -70,7 +70,7 @@ MODULE_LICENSE("GPL");
* Variable record -- index by leading revision/length
* Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
*/
-static unsigned short DefaultPhyParam[] = {
+static const unsigned short DefaultPhyParam[] = {
/* 11/12/03 IP1000A v1-3 rev=0x40 */
/*--------------------------------------------------------------------------
(0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
@@ -88,7 +88,7 @@ static unsigned short DefaultPhyParam[] = {
0x0000
};
-static const char *ipg_brand_name[] = {
+static const char * const ipg_brand_name[] = {
"IC PLUS IP1000 1000/100/10 based NIC",
"Sundance Technology ST2021 based NIC",
"Tamarack Microelectronics TC9020/9021 based NIC",
@@ -1961,7 +1961,7 @@ static void ipg_set_phy_default_param(unsigned char rev,
{
unsigned short length;
unsigned char revision;
- unsigned short *phy_param;
+ const unsigned short *phy_param;
unsigned short address, value;
phy_param = &DefaultPhyParam[0];
--
1.7.6.131.g99019
^ permalink raw reply related
* [PATCH 1/2] ipg: Use current logging styles
From: Joe Perches @ 2011-07-30 2:38 UTC (permalink / raw)
To: Francois Romieu, Sorbica Shieh; +Cc: netdev, linux-kernel
Add and use pr_fmt, pr_<level> and netdev_<level>.
Convert printks with %[n].[n]x to %nx to be shorter
and clearer.
Consolidate printks to use a single printk rather
than continued printks without KERN_CONT.
Removed unnecessary trailing periods.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/ipg.c | 191 ++++++++++++++++++++++++++---------------------------
1 files changed, 95 insertions(+), 96 deletions(-)
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index d4aa40a..3aefaad 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -20,6 +20,9 @@
* http://www.icplus.com.tw
* jesse@icplus.com.tw
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <linux/interrupt.h>
@@ -118,23 +121,23 @@ static void ipg_dump_rfdlist(struct net_device *dev)
IPG_DEBUG_MSG("_dump_rfdlist\n");
- printk(KERN_INFO "rx_current = %2.2x\n", sp->rx_current);
- printk(KERN_INFO "rx_dirty = %2.2x\n", sp->rx_dirty);
- printk(KERN_INFO "RFDList start address = %16.16lx\n",
- (unsigned long) sp->rxd_map);
- printk(KERN_INFO "RFDListPtr register = %8.8x%8.8x\n",
- ipg_r32(IPG_RFDLISTPTR1), ipg_r32(IPG_RFDLISTPTR0));
+ netdev_info(dev, "rx_current = %02x\n", sp->rx_current);
+ netdev_info(dev, "rx_dirty = %02x\n", sp->rx_dirty);
+ netdev_info(dev, "RFDList start address = %016lx\n",
+ (unsigned long)sp->rxd_map);
+ netdev_info(dev, "RFDListPtr register = %08x%08x\n",
+ ipg_r32(IPG_RFDLISTPTR1), ipg_r32(IPG_RFDLISTPTR0));
for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
offset = (u32) &sp->rxd[i].next_desc - (u32) sp->rxd;
- printk(KERN_INFO "%2.2x %4.4x RFDNextPtr = %16.16lx\n", i,
- offset, (unsigned long) sp->rxd[i].next_desc);
+ netdev_info(dev, "%02x %04x RFDNextPtr = %016lx\n",
+ i, offset, (unsigned long)sp->rxd[i].next_desc);
offset = (u32) &sp->rxd[i].rfs - (u32) sp->rxd;
- printk(KERN_INFO "%2.2x %4.4x RFS = %16.16lx\n", i,
- offset, (unsigned long) sp->rxd[i].rfs);
+ netdev_info(dev, "%02x %04x RFS = %016lx\n",
+ i, offset, (unsigned long)sp->rxd[i].rfs);
offset = (u32) &sp->rxd[i].frag_info - (u32) sp->rxd;
- printk(KERN_INFO "%2.2x %4.4x frag_info = %16.16lx\n", i,
- offset, (unsigned long) sp->rxd[i].frag_info);
+ netdev_info(dev, "%02x %04x frag_info = %016lx\n",
+ i, offset, (unsigned long)sp->rxd[i].frag_info);
}
}
@@ -147,24 +150,24 @@ static void ipg_dump_tfdlist(struct net_device *dev)
IPG_DEBUG_MSG("_dump_tfdlist\n");
- printk(KERN_INFO "tx_current = %2.2x\n", sp->tx_current);
- printk(KERN_INFO "tx_dirty = %2.2x\n", sp->tx_dirty);
- printk(KERN_INFO "TFDList start address = %16.16lx\n",
- (unsigned long) sp->txd_map);
- printk(KERN_INFO "TFDListPtr register = %8.8x%8.8x\n",
- ipg_r32(IPG_TFDLISTPTR1), ipg_r32(IPG_TFDLISTPTR0));
+ netdev_info(dev, "tx_current = %02x\n", sp->tx_current);
+ netdev_info(dev, "tx_dirty = %02x\n", sp->tx_dirty);
+ netdev_info(dev, "TFDList start address = %016lx\n",
+ (unsigned long) sp->txd_map);
+ netdev_info(dev, "TFDListPtr register = %08x%08x\n",
+ ipg_r32(IPG_TFDLISTPTR1), ipg_r32(IPG_TFDLISTPTR0));
for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
offset = (u32) &sp->txd[i].next_desc - (u32) sp->txd;
- printk(KERN_INFO "%2.2x %4.4x TFDNextPtr = %16.16lx\n", i,
- offset, (unsigned long) sp->txd[i].next_desc);
+ netdev_info(dev, "%02x %04x TFDNextPtr = %016lx\n",
+ i, offset, (unsigned long)sp->txd[i].next_desc);
offset = (u32) &sp->txd[i].tfc - (u32) sp->txd;
- printk(KERN_INFO "%2.2x %4.4x TFC = %16.16lx\n", i,
- offset, (unsigned long) sp->txd[i].tfc);
+ netdev_info(dev, "%02x %04x TFC = %016lx\n",
+ i, offset, (unsigned long) sp->txd[i].tfc);
offset = (u32) &sp->txd[i].frag_info - (u32) sp->txd;
- printk(KERN_INFO "%2.2x %4.4x frag_info = %16.16lx\n", i,
- offset, (unsigned long) sp->txd[i].frag_info);
+ netdev_info(dev, "%02x %04x frag_info = %016lx\n",
+ i, offset, (unsigned long) sp->txd[i].frag_info);
}
}
#endif
@@ -480,6 +483,10 @@ static int ipg_config_autoneg(struct net_device *dev)
u32 mac_ctrl_val;
u32 asicctrl;
u8 phyctrl;
+ const char *speed;
+ const char *duplex;
+ const char *tx_desc;
+ const char *rx_desc;
IPG_DEBUG_MSG("_config_autoneg\n");
@@ -499,27 +506,27 @@ static int ipg_config_autoneg(struct net_device *dev)
*/
sp->tenmbpsmode = 0;
- printk(KERN_INFO "%s: Link speed = ", dev->name);
-
/* Determine actual speed of operation. */
switch (phyctrl & IPG_PC_LINK_SPEED) {
case IPG_PC_LINK_SPEED_10MBPS:
- printk("10Mbps.\n");
- printk(KERN_INFO "%s: 10Mbps operational mode enabled.\n",
- dev->name);
+ speed = "10Mbps";
sp->tenmbpsmode = 1;
break;
case IPG_PC_LINK_SPEED_100MBPS:
- printk("100Mbps.\n");
+ speed = "100Mbps";
break;
case IPG_PC_LINK_SPEED_1000MBPS:
- printk("1000Mbps.\n");
+ speed = "1000Mbps";
break;
default:
- printk("undefined!\n");
+ speed = "undefined!";
return 0;
}
+ netdev_info(dev, "Link speed = %s\n", speed);
+ if (sp->tenmbpsmode == 1)
+ netdev_info(dev, "10Mbps operational mode enabled\n");
+
if (phyctrl & IPG_PC_DUPLEX_STATUS) {
fullduplex = 1;
txflowcontrol = 1;
@@ -528,38 +535,41 @@ static int ipg_config_autoneg(struct net_device *dev)
/* Configure full duplex, and flow control. */
if (fullduplex == 1) {
+
/* Configure IPG for full duplex operation. */
- printk(KERN_INFO "%s: setting full duplex, ", dev->name);
+
+ duplex = "full";
mac_ctrl_val |= IPG_MC_DUPLEX_SELECT_FD;
if (txflowcontrol == 1) {
- printk("TX flow control");
+ tx_desc = "";
mac_ctrl_val |= IPG_MC_TX_FLOW_CONTROL_ENABLE;
} else {
- printk("no TX flow control");
+ tx_desc = "no ";
mac_ctrl_val &= ~IPG_MC_TX_FLOW_CONTROL_ENABLE;
}
if (rxflowcontrol == 1) {
- printk(", RX flow control.");
+ rx_desc = "";
mac_ctrl_val |= IPG_MC_RX_FLOW_CONTROL_ENABLE;
} else {
- printk(", no RX flow control.");
+ rx_desc = "no ";
mac_ctrl_val &= ~IPG_MC_RX_FLOW_CONTROL_ENABLE;
}
-
- printk("\n");
} else {
- /* Configure IPG for half duplex operation. */
- printk(KERN_INFO "%s: setting half duplex, "
- "no TX flow control, no RX flow control.\n", dev->name);
-
- mac_ctrl_val &= ~IPG_MC_DUPLEX_SELECT_FD &
- ~IPG_MC_TX_FLOW_CONTROL_ENABLE &
- ~IPG_MC_RX_FLOW_CONTROL_ENABLE;
+ duplex = "half";
+ tx_desc = "no ";
+ rx_desc = "no ";
+ mac_ctrl_val &= (~IPG_MC_DUPLEX_SELECT_FD &
+ ~IPG_MC_TX_FLOW_CONTROL_ENABLE &
+ ~IPG_MC_RX_FLOW_CONTROL_ENABLE);
}
+
+ netdev_info(dev, "setting %s duplex, %sTX, %sRX flow control\n",
+ duplex, tx_desc, rx_desc);
ipg_w32(mac_ctrl_val, MAC_CTRL);
+
return 0;
}
@@ -784,14 +794,13 @@ static int init_rfdlist(struct net_device *dev)
* A receive buffer was not ready, break the
* RFD list here.
*/
- IPG_DEBUG_MSG("Cannot allocate Rx buffer.\n");
+ IPG_DEBUG_MSG("Cannot allocate Rx buffer\n");
/* Just in case we cannot allocate a single RFD.
* Should not occur.
*/
if (i == 0) {
- printk(KERN_ERR "%s: No memory available"
- " for RFD list.\n", dev->name);
+ netdev_err(dev, "No memory available for RFD list\n");
return -ENOMEM;
}
}
@@ -838,7 +847,7 @@ static void init_tfdlist(struct net_device *dev)
sp->tx_dirty = 0;
/* Write the location of the TFDList to the IPG. */
- IPG_DDEBUG_MSG("Starting TFDListPtr = %8.8x\n",
+ IPG_DDEBUG_MSG("Starting TFDListPtr = %08x\n",
(u32) sp->txd_map);
ipg_w32((u32) sp->txd_map, TFD_LIST_PTR_0);
ipg_w32(0x00000000, TFD_LIST_PTR_1);
@@ -864,7 +873,7 @@ static void ipg_nic_txfree(struct net_device *dev)
struct sk_buff *skb = sp->tx_buff[dirty];
struct ipg_tx *txfd = sp->txd + dirty;
- IPG_DEBUG_MSG("TFC = %16.16lx\n", (unsigned long) txfd->tfc);
+ IPG_DEBUG_MSG("TFC = %016lx\n", (unsigned long) txfd->tfc);
/* Look at each TFD's TFC field beginning
* at the last freed TFD up to the current TFD.
@@ -906,10 +915,8 @@ static void ipg_tx_timeout(struct net_device *dev)
spin_lock_irq(&sp->lock);
/* Re-configure after DMA reset. */
- if (ipg_io_config(dev) < 0) {
- printk(KERN_INFO "%s: Error during re-configuration.\n",
- dev->name);
- }
+ if (ipg_io_config(dev) < 0)
+ netdev_info(dev, "Error during re-configuration\n");
init_tfdlist(dev);
@@ -938,7 +945,7 @@ static void ipg_nic_txcleanup(struct net_device *dev)
*/
u32 txstatusdword = ipg_r32(TX_STATUS);
- IPG_DEBUG_MSG("TxStatus = %8.8x\n", txstatusdword);
+ IPG_DEBUG_MSG("TxStatus = %08x\n", txstatusdword);
/* Check for Transmit errors. Error bits only valid if
* TX_COMPLETE bit in the TXSTATUS register is a 1.
@@ -953,20 +960,20 @@ static void ipg_nic_txcleanup(struct net_device *dev)
/* Transmit error, increment stat counters. */
if (txstatusdword & IPG_TS_TX_ERROR) {
- IPG_DEBUG_MSG("Transmit error.\n");
+ IPG_DEBUG_MSG("Transmit error\n");
sp->stats.tx_errors++;
}
/* Late collision, re-enable transmitter. */
if (txstatusdword & IPG_TS_LATE_COLLISION) {
- IPG_DEBUG_MSG("Late collision on transmit.\n");
+ IPG_DEBUG_MSG("Late collision on transmit\n");
ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) &
IPG_MC_RSVD_MASK, MAC_CTRL);
}
/* Maximum collisions, re-enable transmitter. */
if (txstatusdword & IPG_TS_TX_MAX_COLL) {
- IPG_DEBUG_MSG("Maximum collisions on transmit.\n");
+ IPG_DEBUG_MSG("Maximum collisions on transmit\n");
ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) &
IPG_MC_RSVD_MASK, MAC_CTRL);
}
@@ -975,16 +982,14 @@ static void ipg_nic_txcleanup(struct net_device *dev)
* transmitter.
*/
if (txstatusdword & IPG_TS_TX_UNDERRUN) {
- IPG_DEBUG_MSG("Transmitter underrun.\n");
+ IPG_DEBUG_MSG("Transmitter underrun\n");
sp->stats.tx_fifo_errors++;
ipg_reset(dev, IPG_AC_TX_RESET | IPG_AC_DMA |
IPG_AC_NETWORK | IPG_AC_FIFO);
/* Re-configure after DMA reset. */
if (ipg_io_config(dev) < 0) {
- printk(KERN_INFO
- "%s: Error during re-configuration.\n",
- dev->name);
+ netdev_info(dev, "Error during re-configuration\n");
}
init_tfdlist(dev);
@@ -1063,7 +1068,7 @@ static int ipg_nic_rxrestore(struct net_device *dev)
* Linux system).
*/
if (ipg_get_rxbuff(dev, entry) < 0) {
- IPG_DEBUG_MSG("Cannot allocate new Rx buffer.\n");
+ IPG_DEBUG_MSG("Cannot allocate new Rx buffer\n");
break;
}
@@ -1134,7 +1139,7 @@ static int ipg_nic_rx_check_error(struct net_device *dev)
(IPG_RFS_RXFIFOOVERRUN | IPG_RFS_RXRUNTFRAME |
IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR |
IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR))) {
- IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n",
+ IPG_DEBUG_MSG("Rx error, RFS = %016lx\n",
(unsigned long) rxfd->rfs);
/* Increment general receive error statistic. */
@@ -1142,13 +1147,13 @@ static int ipg_nic_rx_check_error(struct net_device *dev)
/* Increment detailed receive error statistics. */
if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) {
- IPG_DEBUG_MSG("RX FIFO overrun occurred.\n");
+ IPG_DEBUG_MSG("RX FIFO overrun occurred\n");
sp->stats.rx_fifo_errors++;
}
if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) {
- IPG_DEBUG_MSG("RX runt occurred.\n");
+ IPG_DEBUG_MSG("RX runt occurred\n");
sp->stats.rx_length_errors++;
}
@@ -1157,7 +1162,7 @@ static int ipg_nic_rx_check_error(struct net_device *dev)
*/
if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) {
- IPG_DEBUG_MSG("RX alignment error occurred.\n");
+ IPG_DEBUG_MSG("RX alignment error occurred\n");
sp->stats.rx_frame_errors++;
}
@@ -1404,7 +1409,7 @@ static int ipg_nic_rx(struct net_device *dev)
*/
if (framelen > sp->rxfrag_size) {
IPG_DEBUG_MSG
- ("RFS FrameLen > allocated fragment size.\n");
+ ("RFS FrameLen > allocated fragment size\n");
framelen = sp->rxfrag_size;
}
@@ -1414,7 +1419,7 @@ static int ipg_nic_rx(struct net_device *dev)
IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR |
IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR)))) {
- IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n",
+ IPG_DEBUG_MSG("Rx error, RFS = %016lx\n",
(unsigned long int) rxfd->rfs);
/* Increment general receive error statistic. */
@@ -1422,12 +1427,12 @@ static int ipg_nic_rx(struct net_device *dev)
/* Increment detailed receive error statistics. */
if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) {
- IPG_DEBUG_MSG("RX FIFO overrun occurred.\n");
+ IPG_DEBUG_MSG("RX FIFO overrun occurred\n");
sp->stats.rx_fifo_errors++;
}
if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) {
- IPG_DEBUG_MSG("RX runt occurred.\n");
+ IPG_DEBUG_MSG("RX runt occurred\n");
sp->stats.rx_length_errors++;
}
@@ -1437,7 +1442,7 @@ static int ipg_nic_rx(struct net_device *dev)
*/
if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) {
- IPG_DEBUG_MSG("RX alignment error occurred.\n");
+ IPG_DEBUG_MSG("RX alignment error occurred\n");
sp->stats.rx_frame_errors++;
}
@@ -1508,7 +1513,7 @@ static int ipg_nic_rx(struct net_device *dev)
rxfd = sp->rxd + entry;
- IPG_DEBUG_MSG("Frame requires multiple RFDs.\n");
+ IPG_DEBUG_MSG("Frame requires multiple RFDs\n");
/* An unexpected event, additional code needed to handle
* properly. So for the time being, just disregard the
@@ -1557,8 +1562,7 @@ static void ipg_reset_after_host_error(struct work_struct *work)
init_tfdlist(dev);
if (ipg_io_config(dev) < 0) {
- printk(KERN_INFO "%s: Cannot recover from PCI error.\n",
- dev->name);
+ netdev_info(dev, "Cannot recover from PCI error\n");
schedule_delayed_work(&sp->task, HZ);
}
}
@@ -1586,7 +1590,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
*/
status = ipg_r16(INT_STATUS_ACK);
- IPG_DEBUG_MSG("IntStatusAck = %4.4x\n", status);
+ IPG_DEBUG_MSG("IntStatusAck = %04x\n", status);
/* Shared IRQ of remove event. */
if (!(status & IPG_IS_RSVD_MASK))
@@ -1599,7 +1603,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
/* If RFDListEnd interrupt, restore all used RFDs. */
if (status & IPG_IS_RFD_LIST_END) {
- IPG_DEBUG_MSG("RFDListEnd Interrupt.\n");
+ IPG_DEBUG_MSG("RFDListEnd Interrupt\n");
/* The RFD list end indicates an RFD was encountered
* with a 0 NextPtr, or with an RFDDone bit set to 1
@@ -1661,21 +1665,20 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
/* If LinkEvent interrupt, resolve autonegotiation. */
if (status & IPG_IS_LINK_EVENT) {
if (ipg_config_autoneg(dev) < 0)
- printk(KERN_INFO "%s: Auto-negotiation error.\n",
- dev->name);
+ netdev_info(dev, "Auto-negotiation error\n");
}
/* If MACCtrlFrame interrupt, do nothing. */
if (status & IPG_IS_MAC_CTRL_FRAME)
- IPG_DEBUG_MSG("MACCtrlFrame interrupt.\n");
+ IPG_DEBUG_MSG("MACCtrlFrame interrupt\n");
/* If RxComplete interrupt, do nothing. */
if (status & IPG_IS_RX_COMPLETE)
- IPG_DEBUG_MSG("RxComplete interrupt.\n");
+ IPG_DEBUG_MSG("RxComplete interrupt\n");
/* If RxEarly interrupt, do nothing. */
if (status & IPG_IS_RX_EARLY)
- IPG_DEBUG_MSG("RxEarly interrupt.\n");
+ IPG_DEBUG_MSG("RxEarly interrupt\n");
out_enable:
/* Re-enable IPG interrupts. */
@@ -1749,8 +1752,7 @@ static int ipg_nic_open(struct net_device *dev)
rc = request_irq(pdev->irq, ipg_interrupt_handler, IRQF_SHARED,
dev->name, dev);
if (rc < 0) {
- printk(KERN_INFO "%s: Error when requesting interrupt.\n",
- dev->name);
+ netdev_info(dev, "Error when requesting interrupt\n");
goto out;
}
@@ -1770,8 +1772,7 @@ static int ipg_nic_open(struct net_device *dev)
rc = init_rfdlist(dev);
if (rc < 0) {
- printk(KERN_INFO "%s: Error during configuration.\n",
- dev->name);
+ netdev_info(dev, "Error during configuration\n");
goto err_free_tx_2;
}
@@ -1779,14 +1780,13 @@ static int ipg_nic_open(struct net_device *dev)
rc = ipg_io_config(dev);
if (rc < 0) {
- printk(KERN_INFO "%s: Error during configuration.\n",
- dev->name);
+ netdev_info(dev, "Error during configuration\n");
goto err_release_tfdlist_3;
}
/* Resolve autonegotiation. */
if (ipg_config_autoneg(dev) < 0)
- printk(KERN_INFO "%s: Auto-negotiation error.\n", dev->name);
+ netdev_info(dev, "Auto-negotiation error\n");
/* initialize JUMBO Frame control variable */
sp->jumbo.found_start = 0;
@@ -2222,7 +2222,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
if (rc < 0)
goto out;
- printk(KERN_INFO "%s: %s\n", pci_name(pdev), ipg_brand_name[i]);
+ pr_info("%s: %s\n", pci_name(pdev), ipg_brand_name[i]);
pci_set_master(pdev);
@@ -2230,8 +2230,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
if (rc < 0) {
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc < 0) {
- printk(KERN_ERR "%s: DMA config failed.\n",
- pci_name(pdev));
+ pr_err("%s: DMA config failed\n", pci_name(pdev));
goto err_disable_0;
}
}
@@ -2241,7 +2240,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
*/
dev = alloc_etherdev(sizeof(struct ipg_nic_private));
if (!dev) {
- printk(KERN_ERR "%s: alloc_etherdev failed\n", pci_name(pdev));
+ pr_err("%s: alloc_etherdev failed\n", pci_name(pdev));
rc = -ENOMEM;
goto err_disable_0;
}
@@ -2267,7 +2266,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
ioaddr = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
if (!ioaddr) {
- printk(KERN_ERR "%s cannot map MMIO\n", pci_name(pdev));
+ pr_err("%s: cannot map MMIO\n", pci_name(pdev));
rc = -EIO;
goto err_release_regions_2;
}
@@ -2289,7 +2288,7 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
if (rc < 0)
goto err_unmap_3;
- printk(KERN_INFO "Ethernet device registered as: %s\n", dev->name);
+ netdev_info(dev, "Ethernet device registered\n");
out:
return rc;
--
1.7.6.131.g99019
^ permalink raw reply related
* Re: [PATCH] Fix cdc-phonet build
From: David Miller @ 2011-07-30 0:45 UTC (permalink / raw)
To: chris2553; +Cc: netdev
In-Reply-To: <201107292149.58759.chris2553@googlemail.com>
From: Chris Clayton <chris2553@googlemail.com>
Date: Fri, 29 Jul 2011 21:49:58 +0100
> On Thursday 28 July 2011 06:41:17 David Miller wrote:
>> From: Chris Clayton <chris2553@googlemail.com>
>> Date: Tue, 26 Jul 2011 23:20:22 +0100
>>
>> > cdc-phonet does not presently build on linux-3.0 because there is no
>> > entry for it in drivers/net/Makefile. This patch adds that entry.
>> >
>> > Signed-off-by: Chris Clayton <chris2553@googlemail.com>
>>
>> Applied, thanks.
>
> Actually, I've just checked and the same problem exists in 2.6.39.3, so once the patch is Linus'
> tree, I guess it should go in stable too. Do you have that in hand, David or should I send to
> stable once the patch is applied to mainline?
I know it's also broken there, and I'll take care of submitting it to
-stable.
^ permalink raw reply
* Re: [PATCH RFC net-next] virtio_net: refill buffer right after being used
From: Mike Waychison @ 2011-07-29 23:58 UTC (permalink / raw)
To: Shirley Ma; +Cc: Rusty Russell, mst, kvm, virtualization, netdev
In-Reply-To: <1311980131.24300.30.camel@localhost.localdomain>
On Fri, Jul 29, 2011 at 3:55 PM, Shirley Ma <mashirle@us.ibm.com> wrote:
> Resubmit it with a typo fix.
>
> Signed-off-by: Shirley Ma <xma@us.ibm.com>
> ---
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 0c7321c..c8201d4 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -429,6 +429,22 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp)
> return err;
> }
>
> +static int fill_one(struct virtnet_info *vi, gfp_t gfp)
> +{
> + int err;
> +
> + if (vi->mergeable_rx_bufs)
> + err = add_recvbuf_mergeable(vi, gfp);
> + else if (vi->big_packets)
> + err = add_recvbuf_big(vi, gfp);
> + else
> + err = add_recvbuf_small(vi, gfp);
> +
> + if (err >= 0)
> + ++vi->num;
> + return err;
> +}
> +
> /* Returns false if we couldn't fill entirely (OOM). */
> static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
> {
> @@ -436,17 +452,10 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
> bool oom;
>
> do {
> - if (vi->mergeable_rx_bufs)
> - err = add_recvbuf_mergeable(vi, gfp);
> - else if (vi->big_packets)
> - err = add_recvbuf_big(vi, gfp);
> - else
> - err = add_recvbuf_small(vi, gfp);
> -
> + err = fill_one(vi, gfp);
> oom = err == -ENOMEM;
> if (err < 0)
> break;
> - ++vi->num;
> } while (err > 0);
> if (unlikely(vi->num > vi->max))
> vi->max = vi->num;
> @@ -506,13 +515,13 @@ again:
> receive_buf(vi->dev, buf, len);
> --vi->num;
> received++;
> - }
> -
> - if (vi->num < vi->max / 2) {
> - if (!try_fill_recv(vi, GFP_ATOMIC))
> + if (fill_one(vi, GFP_ATOMIC) < 0)
> schedule_delayed_work(&vi->refill, 0);
> }
>
> + /* notify buffers are refilled */
> + virtqueue_kick(vi->rvq);
> +
How does this reduce latency? We are doing the same amount of work
in both cases, and in both cases the newly available buffers are not
visible to the device until the virtqueue_kick..
> /* Out of packets? */
> if (received < budget) {
> napi_complete(napi);
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH] sunrpc: use better NUMA affinities
From: J. Bruce Fields @ 2011-07-29 23:48 UTC (permalink / raw)
To: NeilBrown
Cc: Greg Banks, Eric Dumazet, Christoph Hellwig,
linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, David Miller,
linux-kernel, netdev
In-Reply-To: <20110730093025.716f3f50-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org>
On Sat, Jul 30, 2011 at 09:30:25AM +1000, NeilBrown wrote:
> On Sat, 30 Jul 2011 06:34:44 +1000 Greg Banks <gnb-97jfqw80gc6171pxa8y+qA@public.gmane.org> wrote:
>
> >
> >
> > Sent from my iPhone
> >
> > On 30/07/2011, at 2:53, "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> >
> > > On Fri, Jul 29, 2011 at 12:48:36PM -0400, bfields wrote:
> > >> On Fri, Jul 29, 2011 at 11:30:05PM +1000, Greg Banks wrote:
> > >>>
> > >>>
> > >>> Sent from my iPhone
> > >>>
> > >>> On 29/07/2011, at 22:11, Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> > >>> wrote:
> > >>>
> > >>>> Le vendredi 29 juillet 2011 à 21:58 +1000, Greg Banks a écrit :
> > >>>>
> > >>>>>
> > >>>>> Sure, and a whole lot of the callsites are ("..._%d", cpu),
> > >>>>> hence the
> > >>>>> unfortune :(
> > >>>>
> > >>>> BTW, we could name nfsd threads differently :
> > >>>>
> > >>>> Currently, they all are named : "nfsd"
> > >>>>
> > >>>> If SVC_POOL_PERCPU is selected, we could name them :
> > >>>> nfsd_c0 -> nfsd_cN
> > >>>>
> > >>>> If SVC_POOL_PERNODE is selected, we could name them :
> > >>>> nfsd_n0 -> nfsd_nN
> > >>>>
> > >>>> That would help to check with "ps aux" which cpu/nodes are under
> > >>>> stress.
> > >>>>
> > >>>>
> > >>>
> > >>> I like it!
> > >>
> > >> Yup, patch welcomed.--b.
> > >
> > > (Annoying fact: some initscripts stop nfsd using a rough equivalent of
> > > "killall nfsd". So the name of the threads is arguably ABI. I think
> > > those initscripts are nuts and deserve what they get, but that may be
> > > because I'm forgetting the reason they do that.)
> > >
> >
> > We had this discussion in May-June 2008; it's because the nfsds were
> > once many many years ago userspace threads.
>
> Even when they became kernel threads, 'kill' was the only way to kill them -
> at first.
>
> >
> > The "killall nfsd" semantics in those scripts are awful and lead to
> > problems shutting down when there are lots of threads. It would
> > probably be an improvement to provide a better shutdown mechanism and
> > force distros to use it.
>
> rpc.nfsd 0
>
> will stop all nfsd threads. Follow with
>
> exportfs -f
>
> and you should be done. I'm not 100% sure about the nfsv4 thread though -
> would need to check.
Should be fine.
--b.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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
* [PATCH net-next 2/5] qlcnic: FW dump related changes
From: Anirban Chakraborty @ 2011-07-29 23:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Anirban Chakraborty
In-Reply-To: <1311982230-10543-1-git-send-email-anirban.chakraborty@qlogic.com>
o Added code to support FW reset without invoking the dump
o Fixed the return value of the dump data size if dump is not available.
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 1 +
drivers/net/qlcnic/qlcnic_ethtool.c | 22 +++++++++++++++++-----
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index baf646d..4200ef8 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -1344,6 +1344,7 @@ enum op_codes {
#define QLCNIC_FORCE_FW_DUMP_KEY 0xdeadfeed
#define QLCNIC_ENABLE_FW_DUMP 0xaddfeed
#define QLCNIC_DISABLE_FW_DUMP 0xbadfeed
+#define QLCNIC_FORCE_FW_RESET 0xdeaddead
struct qlcnic_dump_operations {
enum op_codes opcode;
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 72a723d..7c64f2f 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -1105,7 +1105,10 @@ qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
- dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
+ if (fw_dump->clr)
+ dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
+ else
+ dump->len = 0;
dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
dump->version = adapter->fw_version;
return 0;
@@ -1152,7 +1155,8 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
- if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) {
+ switch (val->flag) {
+ case QLCNIC_FORCE_FW_DUMP_KEY:
if (!fw_dump->enable) {
netdev_info(netdev, "FW dump not enabled\n");
return ret;
@@ -1164,17 +1168,25 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
}
netdev_info(netdev, "Forcing a FW dump\n");
qlcnic_dev_request_reset(adapter);
- } else if (val->flag == QLCNIC_DISABLE_FW_DUMP) {
+ break;
+ case QLCNIC_DISABLE_FW_DUMP:
if (fw_dump->enable) {
netdev_info(netdev, "Disabling FW dump\n");
fw_dump->enable = 0;
}
- } else if (val->flag == QLCNIC_ENABLE_FW_DUMP) {
+ break;
+ case QLCNIC_ENABLE_FW_DUMP:
if (!fw_dump->enable && fw_dump->tmpl_hdr) {
netdev_info(netdev, "Enabling FW dump\n");
fw_dump->enable = 1;
}
- } else {
+ break;
+ case QLCNIC_FORCE_FW_RESET:
+ netdev_info(netdev, "Forcing a FW reset\n");
+ qlcnic_dev_request_reset(adapter);
+ adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
+ break;
+ default:
if (val->flag > QLCNIC_DUMP_MASK_MAX ||
val->flag < QLCNIC_DUMP_MASK_MIN) {
netdev_info(netdev,
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 0/5] qlcnic: Fixes and debug support
From: Anirban Chakraborty @ 2011-07-29 23:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Anirban Chakraborty
In-Reply-To: <1311982230-10543-1-git-send-email-anirban.chakraborty@qlogic.com>
Please apply the series to net-next. Thanks.
-Anirban
^ permalink raw reply
* [PATCH net-next 3/5] qlcnic: Fix delay in reset path
From: Anirban Chakraborty @ 2011-07-29 23:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Sritej Velaga
In-Reply-To: <1311982230-10543-1-git-send-email-anirban.chakraborty@qlogic.com>
From: Sritej Velaga <sritej.velaga@qlogic.com>
Driver should not check for heart beat anymore when FW is hung, rather it
should restart the FW.
Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 1 +
drivers/net/qlcnic/qlcnic_init.c | 3 ++-
drivers/net/qlcnic/qlcnic_main.c | 5 +++++
3 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 4200ef8..5f0141b 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -911,6 +911,7 @@ struct qlcnic_ipaddr {
#define QLCNIC_PROMISC_DISABLED 0x800
#define QLCNIC_NEED_FLR 0x1000
#define QLCNIC_FW_RESET_OWNER 0x2000
+#define QLCNIC_FW_HANG 0x4000
#define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index ee8a398..3b6741e 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1056,7 +1056,8 @@ qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter)
int
qlcnic_need_fw_reset(struct qlcnic_adapter *adapter)
{
- if (qlcnic_check_fw_hearbeat(adapter)) {
+ if ((adapter->flags & QLCNIC_FW_HANG) ||
+ qlcnic_check_fw_hearbeat(adapter)) {
qlcnic_rom_lock_recovery(adapter);
return 1;
}
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 5ca1b56..248ebbd 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2682,6 +2682,7 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed)
qlcnic_api_unlock(adapter);
err:
adapter->fw_fail_cnt = 0;
+ adapter->flags &= ~QLCNIC_FW_HANG;
clear_bit(__QLCNIC_START_FW, &adapter->state);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
}
@@ -2859,6 +2860,7 @@ skip_ack_check:
(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
QLCDB(adapter, DRV, "Take FW dump\n");
qlcnic_dump_fw(adapter);
+ adapter->flags |= QLCNIC_FW_HANG;
}
rtnl_unlock();
@@ -3046,6 +3048,7 @@ attach:
done:
netif_device_attach(netdev);
adapter->fw_fail_cnt = 0;
+ adapter->flags &= ~QLCNIC_FW_HANG;
clear_bit(__QLCNIC_RESETTING, &adapter->state);
if (!qlcnic_clr_drv_state(adapter))
@@ -3090,6 +3093,8 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
if (++adapter->fw_fail_cnt < FW_FAIL_THRESH)
return 0;
+ adapter->flags |= QLCNIC_FW_HANG;
+
qlcnic_dev_request_reset(adapter);
if (auto_fw_reset)
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 1/5] qlcnic: Fix enviroment variable for udev event generation during FW dump
From: Anirban Chakraborty @ 2011-07-29 23:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Anirban Chakraborty
Driver was not generating the environment variable for the FW dump event correctly.
Fix it by formatting it properly.
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic_hw.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 4055c21..74e9d7b 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -1773,8 +1773,8 @@ int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
goto error;
} else {
fw_dump->clr = 1;
- snprintf(mesg, sizeof(mesg), "FW dump for device: %d\n",
- adapter->pdev->devfn);
+ snprintf(mesg, sizeof(mesg), "FW_DUMP=%s",
+ adapter->netdev->name);
dev_info(&adapter->pdev->dev, "Dump data, %d bytes captured\n",
fw_dump->size);
/* Send a udev event to notify availability of FW dump */
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 4/5] qlcnic: Move get template from probe to start fw
From: Anirban Chakraborty @ 2011-07-29 23:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Sritej Velaga
In-Reply-To: <1311982230-10543-1-git-send-email-anirban.chakraborty@qlogic.com>
From: Sritej Velaga <sritej.velaga@qlogic.com>
Place for gathering FW dump template has been moved to the FW restart path
so that the driver can check if a newer FW version is available and in that case
it replaces the existing FW dump template with the newer template.
Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic_main.c | 22 +++++++++++++++-------
1 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 248ebbd..d287a2b 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -643,8 +643,11 @@ static void get_brd_name(struct qlcnic_adapter *adapter, char *name)
static void
qlcnic_check_options(struct qlcnic_adapter *adapter)
{
- u32 fw_major, fw_minor, fw_build;
+ u32 fw_major, fw_minor, fw_build, prev_fw_version;
struct pci_dev *pdev = adapter->pdev;
+ struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
+
+ prev_fw_version = adapter->fw_version;
fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR);
fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR);
@@ -652,6 +655,17 @@ qlcnic_check_options(struct qlcnic_adapter *adapter)
adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
+ if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC) {
+ if (fw_dump->tmpl_hdr == NULL ||
+ adapter->fw_version > prev_fw_version) {
+ if (fw_dump->tmpl_hdr)
+ vfree(fw_dump->tmpl_hdr);
+ if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
+ dev_info(&pdev->dev,
+ "Supports FW dump capability\n");
+ }
+ }
+
dev_info(&pdev->dev, "firmware v%d.%d.%d\n",
fw_major, fw_minor, fw_build);
if (adapter->ahw->port_type == QLCNIC_XGBE) {
@@ -1610,12 +1624,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_decr_ref;
}
- /* Get FW dump template and store it */
- if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
- if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
- dev_info(&pdev->dev,
- "Supports FW dump capability\n");
-
if (qlcnic_read_mac_addr(adapter))
dev_warn(&pdev->dev, "failed to read mac addr\n");
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 5/5] qlcnic: Added debug info
From: Anirban Chakraborty @ 2011-07-29 23:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Sritej Velaga
In-Reply-To: <1311982230-10543-1-git-send-email-anirban.chakraborty@qlogic.com>
From: Sritej Velaga <sritej.velaga@qlogic.com>
Now printing states of essential registers once fw hang has been detected.
Bumped up the driver version to 5.0.22
Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 4 ++--
drivers/net/qlcnic/qlcnic_main.c | 13 ++++++++++++-
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 5f0141b..53c6e5d 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -36,8 +36,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 21
-#define QLCNIC_LINUX_VERSIONID "5.0.21"
+#define _QLCNIC_LINUX_SUBVERSION 22
+#define QLCNIC_LINUX_VERSIONID "5.0.22"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index d287a2b..ec8ef72 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -3109,7 +3109,18 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
dev_info(&netdev->dev, "firmware hang detected\n");
-
+ dev_info(&adapter->pdev->dev, "Dumping hw/fw registers\n"
+ "PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n"
+ "PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n"
+ "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n"
+ "PEG_NET_4_PC: 0x%x\n",
+ QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1),
+ QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS2),
+ QLCRD32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c),
+ QLCRD32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c),
+ QLCRD32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c),
+ QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c),
+ QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c));
detach:
adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state :
QLCNIC_DEV_NEED_RESET;
--
1.7.4.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