* Re: [net-next 14/17] i40e: implement ethtool RSS config
From: Eric Dumazet @ 2014-11-22 18:22 UTC (permalink / raw)
To: Jeff Kirsher; +Cc: davem, Mitch Williams, netdev, nhorman, sassmann, jogreene
In-Reply-To: <1416635708-4765-16-git-send-email-jeffrey.t.kirsher@intel.com>
On Fri, 2014-11-21 at 21:55 -0800, Jeff Kirsher wrote:
> From: Mitch Williams <mitch.a.williams@intel.com>
>
> Support ethtool methods for getting and setting the RSS look-up table.
>
> Change-ID: I52707fb371fc11fe9fd4c287e08542cde38f79d4
> Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
> Tested-by: Jim Young <jamesx.m.young@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 104 +++++++++++++++++++++++++
> 1 file changed, 104 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> index fcd815d..f9f68ea 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> @@ -2237,6 +2237,106 @@ static int i40e_set_channels(struct net_device *dev,
> return -EINVAL;
> }
>
> +#define I40E_HLUT_ARRAY_SIZE ((I40E_PFQF_HLUT_MAX_INDEX + 1) * 4)
> +#define I40E_HKEY_ARRAY_SIZE ((I40E_PFQF_HKEY_MAX_INDEX * 1) * 4)
> +/**
> + * i40e_get_rxfh_key_size - get the RSS hash key size
> + * @netdev: network interface device structure
> + *
> + * Returns the table size.
> + **/
> +static u32 i40e_get_rxfh_key_size(struct net_device *netdev)
> +{
> + return I40E_HKEY_ARRAY_SIZE;
> +}
> +
> +/**
> + * i40e_get_rxfh_indir_size - get the rx flow hash indirection table size
> + * @netdev: network interface device structure
> + *
> + * Returns the table size.
> + **/
> +static u32 i40e_get_rxfh_indir_size(struct net_device *netdev)
> +{
> + return I40E_HLUT_ARRAY_SIZE;
> +}
> +
> +/**
> + * i40e_get_rxfh - get the rx flow hash indirection table
> + * @netdev: network interface device structure
> + * @indir: indirection table
> + * @key: hash key
> + *
> + * Reads the indirection table directly from the hardware. Always returns 0.
> + **/
> +static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
> +{
> + struct i40e_netdev_priv *np = netdev_priv(netdev);
> + struct i40e_vsi *vsi = np->vsi;
> + struct i40e_pf *pf = vsi->back;
> + struct i40e_hw *hw = &pf->hw;
> + u32 reg_val;
> + int i, j;
> +
> + for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
> + reg_val = rd32(hw, I40E_PFQF_HLUT(i));
> + indir[j++] = reg_val & 0xff;
> + indir[j++] = (reg_val >> 8) & 0xff;
> + indir[j++] = (reg_val >> 16) & 0xff;
> + indir[j++] = (reg_val >> 24) & 0xff;
> + }
> + if (key) {
> + for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
> + reg_val = rd32(hw, I40E_PFQF_HKEY(i));
> + key[j++] = (u8)(reg_val & 0xff);
> + key[j++] = (u8)((reg_val >> 8) & 0xff);
> + key[j++] = (u8)((reg_val >> 16) & 0xff);
> + key[j++] = (u8)((reg_val >> 24) & 0xff);
Nit:
put_unaligned_le32(reg_val, key + i * 4);
> + }
> + }
> + return 0;
> +}
> +
> +/**
> + * i40e_set_rxfh - set the rx flow hash indirection table
> + * @netdev: network interface device structure
> + * @indir: indirection table
> + * @key: hash key
> + *
> + * Returns -EINVAL if the table specifies an inavlid queue id, otherwise
> + * returns 0 after programming the table.
> + **/
> +static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
> + const u8 *key)
> +{
> + struct i40e_netdev_priv *np = netdev_priv(netdev);
> + struct i40e_vsi *vsi = np->vsi;
> + struct i40e_pf *pf = vsi->back;
> + struct i40e_hw *hw = &pf->hw;
> + u32 reg_val;
> + int i, j;
> +
> + if (indir) {
> + for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
> + reg_val = indir[j++];
Shouldn't you check the indir[X] values are in correct range ?
( seems to be between 0 and [pf->rss_size_max - 1] )
> + reg_val |= indir[j++] << 8;
> + reg_val |= indir[j++] << 16;
> + reg_val |= indir[j++] << 24;
> + wr32(hw, I40E_PFQF_HLUT(i), reg_val);
> + }
> + }
> + if (key) {
> + for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
> + reg_val = key[j++];
> + reg_val |= key[j++] << 8;
> + reg_val |= key[j++] << 16;
> + reg_val |= key[j++] << 24;
Nit:
reg_val = get_unaligned_le32(key + i * 4);
> + wr32(hw, I40E_PFQF_HKEY(i), reg_val);
> + }
> + }
^ permalink raw reply
* Re: Problem about Setting TCP Congestion Window to a Small Constant
From: Eric Dumazet @ 2014-11-22 17:50 UTC (permalink / raw)
To: wc8348; +Cc: netdev
In-Reply-To: <a7b958c622a1f1ebed77d4ce44109ceb.squirrel@webmail.cs.utexas.edu>
On Sat, 2014-11-22 at 10:29 -0600, wc8348@cs.utexas.edu wrote:
> Hi all,
> My name is Wenzhi Cui, a graduate student working on TCP congestion
> control in Linux Kernel. I have a problem about congestion control in
> linux kernel.
>
> Recently I am playing with TCP Congestion Control Protocol by setting
> the congestion window size to a constant, say 1, and measure the TCP
> flow throughput to see the relationship between cwnd size and
> transmission rate (on a stable environment).
>
> The problem is, when I am setting the snd_cwnd to 1, the real
> transmission rate is around 25MBps. However, since I am testing TCP
> on our department network with 1Gbps (which is 125MBps) bandwidth and
> 300 micro seconds Round trip time (measured by analyzing tcpdump
> trace). So the theoretical sending rate should be
> CWND * MSS / RTT = 1 * 1460 Byte / 300 us = around 5 MBps
> which is far less than the observed 25 MBps bandwidth. I have taken a look
> at tcp_cong.c, tcp_input output.c, etc. but I still cannot find the
> problem.
>
> Can somebody help me figure out what is missing, maybe what may
> affect the real TCP transmission other than CWND or what will happen
> when CWND is set to a very small constant?
You probably did something wrong ?
tcpdump will probably show that your cwnd must be bigger than 1.
(or rtt is way smaller than 300 usec, which sounds quite big to me)
^ permalink raw reply
* Re: [RFC] situation with csum_and_copy_... API
From: Linus Torvalds @ 2014-11-22 17:48 UTC (permalink / raw)
To: Al Viro
Cc: David Miller, Network Development, Linux Kernel Mailing List,
target-devel, Nicholas A. Bellinger, Christoph Hellwig
In-Reply-To: <20141122042856.GZ7996@ZenIV.linux.org.uk>
On Fri, Nov 21, 2014 at 8:28 PM, Al Viro <viro@zeniv.linux.org.uk> wrote:
> OK, here's the next bunch.
Looks like good patches to me. Not that I actually _tested_ it, or
even have a good test-case (yeah, that "historical" ATM fix? I don't
think anybody cares ;), but it all seemed sane.
Linus
^ permalink raw reply
* Re: Problem about Setting TCP Congestion Window to a Small Constant
From: John Heffner @ 2014-11-22 17:34 UTC (permalink / raw)
To: wc8348; +Cc: Netdev
In-Reply-To: <a7b958c622a1f1ebed77d4ce44109ceb.squirrel@webmail.cs.utexas.edu>
On Sat, Nov 22, 2014 at 11:29 AM, <wc8348@cs.utexas.edu> wrote:
> Hi all,
> My name is Wenzhi Cui, a graduate student working on TCP congestion
> control in Linux Kernel. I have a problem about congestion control in
> linux kernel.
>
> Recently I am playing with TCP Congestion Control Protocol by setting
> the congestion window size to a constant, say 1, and measure the TCP
> flow throughput to see the relationship between cwnd size and
> transmission rate (on a stable environment).
>
> The problem is, when I am setting the snd_cwnd to 1, the real
> transmission rate is around 25MBps. However, since I am testing TCP
> on our department network with 1Gbps (which is 125MBps) bandwidth and
> 300 micro seconds Round trip time (measured by analyzing tcpdump
> trace). So the theoretical sending rate should be
> CWND * MSS / RTT = 1 * 1460 Byte / 300 us = around 5 MBps
> which is far less than the observed 25 MBps bandwidth. I have taken a look
> at tcp_cong.c, tcp_input output.c, etc. but I still cannot find the
> problem.
>
> Can somebody help me figure out what is missing, maybe what may
> affect the real TCP transmission other than CWND or what will happen
> when CWND is set to a very small constant?
Looking at a tcptrace "outstanding data graph" may be illuminating.
-John
^ permalink raw reply
* Re: [PATCH] can: eliminate banner[] variable and switch to pr_info()
From: Marc Kleine-Budde @ 2014-11-22 16:59 UTC (permalink / raw)
To: Jeremiah Mahler, Oliver Hartkopp
Cc: David S. Miller, linux-can, netdev, linux-kernel
In-Reply-To: <1416642155-31816-1-git-send-email-jmmahler@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 801 bytes --]
On 11/22/2014 08:42 AM, Jeremiah Mahler wrote:
> Several CAN modules use a design pattern with a banner[] variable at the
> top which defines a string that is used once during init to print the
> banner. The string is also embedded with KERN_INFO which makes it
> printk() specific.
>
> Improve the code by eliminating the banner[] variable and moving the
> string to where it is printed. Then switch from printk(KERN_INFO to
> pr_info() for the lines that were changed.
Applied to can-next.
Thanks,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH] can: eliminate banner[] variable and switch to pr_info()
From: Oliver Hartkopp @ 2014-11-22 16:41 UTC (permalink / raw)
To: Jeremiah Mahler; +Cc: David S. Miller, linux-can, netdev, linux-kernel
In-Reply-To: <1416642155-31816-1-git-send-email-jmmahler@gmail.com>
On 22.11.2014 08:42, Jeremiah Mahler wrote:
> Several CAN modules use a design pattern with a banner[] variable at the
> top which defines a string that is used once during init to print the
> banner. The string is also embedded with KERN_INFO which makes it
> printk() specific.
>
> Improve the code by eliminating the banner[] variable and moving the
> string to where it is printed. Then switch from printk(KERN_INFO to
> pr_info() for the lines that were changed.
>
> Signed-off-by: Jeremiah Mahler <jmmahler@gmail.com>
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
Next time please only post on linux-can ML which is the first address for CAN
related stuff - as long as you don't feel it's a networking relevant issue.
But for almost editorial changes - which is not urgent - linux-can should be
enough.
Thanks,
Oliver
> ---
> net/can/af_can.c | 5 +----
> net/can/bcm.c | 4 +---
> net/can/raw.c | 4 +---
> 3 files changed, 3 insertions(+), 10 deletions(-)
>
> diff --git a/net/can/af_can.c b/net/can/af_can.c
> index ce82337..ac05be1 100644
> --- a/net/can/af_can.c
> +++ b/net/can/af_can.c
> @@ -64,9 +64,6 @@
>
> #include "af_can.h"
>
> -static __initconst const char banner[] = KERN_INFO
> - "can: controller area network core (" CAN_VERSION_STRING ")\n";
> -
> MODULE_DESCRIPTION("Controller Area Network PF_CAN core");
> MODULE_LICENSE("Dual BSD/GPL");
> MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>, "
> @@ -896,7 +893,7 @@ static __init int can_init(void)
> offsetof(struct can_frame, data) !=
> offsetof(struct canfd_frame, data));
>
> - printk(banner);
> + pr_info("can: controller area network core (" CAN_VERSION_STRING ")\n");
>
> memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list));
>
> diff --git a/net/can/bcm.c b/net/can/bcm.c
> index dcb75c0..9aa3f76 100644
> --- a/net/can/bcm.c
> +++ b/net/can/bcm.c
> @@ -78,8 +78,6 @@
> (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG))
>
> #define CAN_BCM_VERSION CAN_VERSION
> -static __initconst const char banner[] = KERN_INFO
> - "can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n";
>
> MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
> MODULE_LICENSE("Dual BSD/GPL");
> @@ -1615,7 +1613,7 @@ static int __init bcm_module_init(void)
> {
> int err;
>
> - printk(banner);
> + pr_info("can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n");
>
> err = can_proto_register(&bcm_can_proto);
> if (err < 0) {
> diff --git a/net/can/raw.c b/net/can/raw.c
> index 081e81f..e3250e2 100644
> --- a/net/can/raw.c
> +++ b/net/can/raw.c
> @@ -56,8 +56,6 @@
> #include <net/net_namespace.h>
>
> #define CAN_RAW_VERSION CAN_VERSION
> -static __initconst const char banner[] =
> - KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n";
>
> MODULE_DESCRIPTION("PF_CAN raw protocol");
> MODULE_LICENSE("Dual BSD/GPL");
> @@ -810,7 +808,7 @@ static __init int raw_module_init(void)
> {
> int err;
>
> - printk(banner);
> + pr_info("can: raw protocol (rev " CAN_RAW_VERSION ")\n");
>
> err = can_proto_register(&raw_can_proto);
> if (err < 0)
>
^ permalink raw reply
* Problem about Setting TCP Congestion Window to a Small Constant
From: wc8348 @ 2014-11-22 16:29 UTC (permalink / raw)
To: netdev
Hi all,
My name is Wenzhi Cui, a graduate student working on TCP congestion
control in Linux Kernel. I have a problem about congestion control in
linux kernel.
Recently I am playing with TCP Congestion Control Protocol by setting
the congestion window size to a constant, say 1, and measure the TCP
flow throughput to see the relationship between cwnd size and
transmission rate (on a stable environment).
The problem is, when I am setting the snd_cwnd to 1, the real
transmission rate is around 25MBps. However, since I am testing TCP
on our department network with 1Gbps (which is 125MBps) bandwidth and
300 micro seconds Round trip time (measured by analyzing tcpdump
trace). So the theoretical sending rate should be
CWND * MSS / RTT = 1 * 1460 Byte / 300 us = around 5 MBps
which is far less than the observed 25 MBps bandwidth. I have taken a look
at tcp_cong.c, tcp_input output.c, etc. but I still cannot find the
problem.
Can somebody help me figure out what is missing, maybe what may
affect the real TCP transmission other than CWND or what will happen
when CWND is set to a very small constant?
Thanks,
Wenzhi Cui
^ permalink raw reply
* [PATCH 0/6] fix error return code
From: Julia Lawall @ 2014-11-22 14:39 UTC (permalink / raw)
To: linux-rdma
Cc: kernel-janitors, linux-wireless, linux-kernel, linux-edac,
linux-atm-general, netdev, Dan Williams, linux-arm-kernel,
dmaengine
The complate semantic patch that finds this problem is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@ok exists@
identifier f,ret,i;
expression e;
constant c;
@@
// identify a function that returns a negative return value at least once.
f(...) {
... when any
(
return -c@i;
|
ret = -c@i;
... when != ret = e
return ret;
|
if (ret < 0) { ... return ret; }
)
... when any
}
@r exists@
identifier ret,ok.f,fn;
expression e1,e2,e3,e4,e5,e6,x;
statement S,S1;
position p1,p2,p3;
@@
// identify a case where the return variable is set to a non-negative value
// and then returned in error-handling code
f(...) {
... when any
(
if@p1 (\(ret < 0\|ret != 0\))
{ ... return ret; }
|
ret@p1 = 0
)
... when != \(ret = e1\|ret++\|ret--\|ret+=e1\|ret-=e1\)
when != &ret
when any
(
if (<+... ret = e5 ...+>) S1
|
if (<+... &ret ...+>) S1
|
if@p2(<+...x = fn(...)...+>)
{
... when != ret = e6
when forall
return@p3 ret;
}
|
break;
|
x = fn(...)
... when != \(ret = e4\|ret++\|ret--\|ret+=e4\|ret-=e4\)
when != &ret
(
if (<+... ret = e3 ...+>) S
|
if (<+... &ret ...+>) S
|
if@p2(<+...\(x != 0\|x < 0\|x == NULL\|IS_ERR(x)\)...+>)
{
... when != ret = e2
when forall
return@p3 ret;
}
)
)
... when any
}
@printer depends on r@
position p;
identifier ok.f,pr;
constant char [] c;
@@
f(...) { <...pr@p(...,c,...)...> }
@bad0 exists@
identifier r.ret,ok.f,g != {ERR_PTR,IS_ERR};
position p != printer.p;
@@
f(...) { ... when any
g@p(...,ret,...)
... when any
}
@bad depends on !bad0 exists@
position r.p1,r.p2;
statement S1,S2;
identifier r.ret;
expression e1;
@@
// ignore the above if there is some path where the variable is set to
// something else
(
if@p1 (\(ret < 0\|ret != 0\)) S1
|
ret@p1 = 0
)
... when any
\(ret = e1\|ret++\|ret--\|ret+=e1\|ret-=e1\|&ret\)
... when any
if@p2(...) S2
@bad1 depends on !bad0 && !bad exists@
position r.p2;
statement S2;
identifier r.ret;
expression e1;
constant c;
@@
ret = -c
... when != \(ret = e1\|ret++\|ret--\|ret+=e1\|ret-=e1\)
when != &ret
when any
if@p2(...) S2
@bad2 depends on !bad0 && !bad && !bad1 exists@
position r.p1,r.p2;
identifier r.ret;
expression e1;
statement S2;
constant c;
@@
// likewise ignore it if there has been an intervening return
ret@p1 = 0
... when != if (...) { ... ret = e1 ... return ret; }
when != if (...) { ... return -c; }
when any
if@p2(...) S2
@script:python depends on !bad0 && !bad && !bad1 && !bad2@
p1 << r.p1;
p2 << r.p2;
p3 << r.p3;
@@
cocci.print_main("",p1)
cocci.print_secs("",p2)
cocci.print_secs("",p3)
// </smpl>
^ permalink raw reply
* Re: FIX ME locking is implemented?
From: Kalle Valo @ 2014-11-22 14:41 UTC (permalink / raw)
To: nick; +Cc: linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <54709610.6020502@gmail.com>
nick <xerofoify@gmail.com> writes:
> I am wondering why the fix me in the code below still exists as this
> code is clearly being locked properly with a spin lock on the lock
> related to the created linked list in this code.
It would be nice to mention what driver and file you are referring to.
So this is from ath6kl_tx_queue_full() in
drivers/net/wireless/ath/ath6kl/txrx.c.
> /* FIXME: Locking */
> spin_lock_bh(&ar->list_lock);
> list_for_each_entry(vif, &ar->vif_list, list) {
> if (vif->nw_type == ADHOC_NETWORK ||
> action != HTC_SEND_FULL_DROP) {
> spin_unlock_bh(&ar->list_lock);
>
> set_bit(NETQ_STOPPED, &vif->flags);
> netif_stop_queue(vif->ndev);
>
> return action;
> }
> }
> spin_unlock_bh(&ar->list_lock);
Most probably someone just forgot to update the comment, patches welcome :)
--
Kalle Valo
^ permalink raw reply
* [PATCH 4/6] solos-pci: fix error return code
From: Julia Lawall @ 2014-11-22 14:39 UTC (permalink / raw)
To: Chas Williams; +Cc: kernel-janitors, linux-atm-general, netdev, linux-kernel
In-Reply-To: <1416667159-9808-1-git-send-email-Julia.Lawall@lip6.fr>
From: Julia Lawall <Julia.Lawall@lip6.fr>
Return a negative error code on failure.
A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@@
identifier ret; expression e1,e2;
@@
(
if (\(ret < 0\|ret != 0\))
{ ... return ret; }
|
ret = 0
)
... when != ret = e1
when != &ret
*if(...)
{
... when != ret = e2
when forall
return ret;
}
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
drivers/atm/solos-pci.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 7652e8d..21b0bc6 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1225,11 +1225,13 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
card->config_regs = pci_iomap(dev, 0, CONFIG_RAM_SIZE);
if (!card->config_regs) {
dev_warn(&dev->dev, "Failed to ioremap config registers\n");
+ err = -ENOMEM;
goto out_release_regions;
}
card->buffers = pci_iomap(dev, 1, DATA_RAM_SIZE);
if (!card->buffers) {
dev_warn(&dev->dev, "Failed to ioremap data buffers\n");
+ err = -ENOMEM;
goto out_unmap_config;
}
^ permalink raw reply related
* Re: [RFC PATCH 1/4] rtnetlink: new flag NLM_F_HW_OFFLOAD to indicate kernel object offload to hardware
From: Thomas Graf @ 2014-11-22 12:29 UTC (permalink / raw)
To: Roopa Prabhu
Cc: jiri, sfeldma, jhs, bcrl, john.fastabend, stephen, linville,
nhorman, nicolas.dichtel, vyasevic, f.fainelli, buytenh, aviadr,
netdev, davem, Shrijeet Mukherjee, gospo
In-Reply-To: <546FD467.5030602@cumulusnetworks.com>
On 11/21/14 at 04:10pm, Roopa Prabhu wrote:
> On 11/21/14, 3:12 PM, Thomas Graf wrote:
> >On 11/21/14 at 02:49pm, roopa@cumulusnetworks.com wrote:
> >>diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
> >>index 1a85940..f78522d 100644
> >>--- a/include/uapi/linux/netlink.h
> >>+++ b/include/uapi/linux/netlink.h
> >>@@ -54,6 +54,8 @@ struct nlmsghdr {
> >> #define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
> >> #define NLM_F_ECHO 8 /* Echo this request */
> >> #define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */
> >>++#define NLM_F_KERNEL 32 /* This msg is only for the kernel */
> >>+#define NLM_F_HW_OFFLOAD 64 /* offload this msg to hw */
> >> /* Modifiers to GET request */
> >> #define NLM_F_ROOT 0x100 /* specify tree root */
> >The NLM_F_ flag space applies to all Netlink messages including non
> >networking bits and is reserved for flags vital to the functioning
> >of the Netlink protocol itself. I suggest you move this to a
> >RTNETLINK specific flags space.
>
> I did try to add it at a layer lower than the netlink header. But, nothing
> else fits so well as this :).
> I did not find a place where i could make it a global flag for just
> networking objects. As I mention in my patch description,
> If not here it will be a per subsystem flag/attribute. I can post a patch
> showing that approach as well.
Global variables have their appeal ;-) The issue I see with this
besides polluting a wide namespace is that it is not extendable.
We get a single bit and if a single bit is not enough we'll start
adding things in lower layers anyway (as you already do).
I think this should really be an IFF_ flag for net_device so its
state is exposed to user space as well.
^ permalink raw reply
* [PATCH net-next] ipv6: coding style improvements (remove assignment in if statements)
From: Ian Morris @ 2014-11-22 12:02 UTC (permalink / raw)
To: netdev; +Cc: Ian Morris
This change has no functional impact and simply addresses some coding
style issues detected by checkpatch. Specifically this change
adjusts "if" statements which also include the assignment of a
variable.
No changes to the resultant object files result as determined by objdiff.
Signed-off-by: Ian Morris <ipm@chirality.org.uk>
---
net/ipv6/addrconf.c | 12 ++++++++----
net/ipv6/ah6.c | 7 ++++---
net/ipv6/esp6.c | 3 ++-
net/ipv6/icmp.c | 3 ++-
net/ipv6/ip6_flowlabel.c | 6 +++++-
net/ipv6/ip6_input.c | 3 ++-
net/ipv6/ip6_output.c | 12 ++++++++----
net/ipv6/ip6_tunnel.c | 15 ++++++++-------
net/ipv6/ip6_vti.c | 4 ++--
net/ipv6/ip6mr.c | 3 +--
net/ipv6/ndisc.c | 7 ++++---
net/ipv6/reassembly.c | 3 ++-
net/ipv6/sit.c | 7 ++++---
net/ipv6/udp.c | 9 ++++++---
14 files changed, 58 insertions(+), 36 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 251fcb4..9eac3a7 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2543,7 +2543,8 @@ static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
if (!dev)
return -ENODEV;
- if ((idev = __in6_dev_get(dev)) == NULL)
+ idev = __in6_dev_get(dev);
+ if (idev == NULL)
return -ENXIO;
read_lock_bh(&idev->lock);
@@ -2690,7 +2691,8 @@ static void init_loopback(struct net_device *dev)
ASSERT_RTNL();
- if ((idev = ipv6_find_idev(dev)) == NULL) {
+ idev = ipv6_find_idev(dev);
+ if (idev == NULL) {
pr_debug("%s: add_dev failed\n", __func__);
return;
}
@@ -2813,7 +2815,8 @@ static void addrconf_sit_config(struct net_device *dev)
* our v4 addrs in the tunnel
*/
- if ((idev = ipv6_find_idev(dev)) == NULL) {
+ idev = ipv6_find_idev(dev);
+ if (idev == NULL) {
pr_debug("%s: add_dev failed\n", __func__);
return;
}
@@ -2837,7 +2840,8 @@ static void addrconf_gre_config(struct net_device *dev)
ASSERT_RTNL();
- if ((idev = ipv6_find_idev(dev)) == NULL) {
+ idev = ipv6_find_idev(dev);
+ if (idev == NULL) {
pr_debug("%s: add_dev failed\n", __func__);
return;
}
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 8ab1989..a6727ad 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -353,7 +353,8 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
ahp = x->data;
ahash = ahp->ahash;
- if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
+ err = skb_cow_data(skb, 0, &trailer);
+ if (err < 0)
goto out;
nfrags = err;
@@ -559,8 +560,8 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
if (!pskb_may_pull(skb, ah_hlen))
goto out;
-
- if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
+ err = skb_cow_data(skb, 0, &trailer);
+ if (err < 0)
goto out;
nfrags = err;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index d2c2d74..e48f2c7 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -345,7 +345,8 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
goto out;
}
- if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) {
+ nfrags = skb_cow_data(skb, 0, &trailer);
+ if (nfrags < 0) {
ret = -EINVAL;
goto out;
}
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 39b3ff9..d674152 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -243,7 +243,8 @@ int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
struct icmp6hdr *icmp6h;
int err = 0;
- if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
+ skb = skb_peek(&sk->sk_write_queue);
+ if (skb == NULL)
goto out;
icmp6h = icmp6_hdr(skb);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 7221021..2f780cb 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -654,7 +654,11 @@ release:
goto done;
err = -ENOMEM;
- if (sfl1 == NULL || (err = mem_check(sk)) != 0)
+ if (sfl1 == NULL)
+ goto done;
+
+ err = mem_check(sk);
+ if (err != 0)
goto done;
fl1 = fl_intern(net, fl, freq.flr_label);
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index a3084ab..aacdcb4 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -220,7 +220,8 @@ resubmit:
nexthdr = skb_network_header(skb)[nhoff];
raw = raw6_local_deliver(skb, nexthdr);
- if ((ipprot = rcu_dereference(inet6_protos[nexthdr])) != NULL) {
+ ipprot = rcu_dereference(inet6_protos[nexthdr]);
+ if (ipprot != NULL) {
int ret;
if (ipprot->flags & INET6_PROTO_FINAL) {
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 916d2a1..ce69a12 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -898,7 +898,8 @@ static int ip6_dst_lookup_tail(struct sock *sk,
if (*dst == NULL)
*dst = ip6_route_output(net, sk, fl6);
- if ((err = (*dst)->error))
+ err = (*dst)->error;
+ if (err)
goto out_err_release;
if (ipv6_addr_any(&fl6->saddr)) {
@@ -946,7 +947,8 @@ static int ip6_dst_lookup_tail(struct sock *sk,
memcpy(&fl_gw6, fl6, sizeof(struct flowi6));
memset(&fl_gw6.daddr, 0, sizeof(struct in6_addr));
*dst = ip6_route_output(net, sk, &fl_gw6);
- if ((err = (*dst)->error))
+ err = (*dst)->error;
+ if (err)
goto out_err_release;
}
}
@@ -1054,7 +1056,8 @@ static inline int ip6_ufo_append_data(struct sock *sk,
* device, so create one single skb packet containing complete
* udp datagram
*/
- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
+ skb = skb_peek_tail(&sk->sk_write_queue);
+ if (skb == NULL) {
skb = sock_alloc_send_skb(sk,
hh_len + fragheaderlen + transhdrlen + 20,
(flags & MSG_DONTWAIT), &err);
@@ -1534,7 +1537,8 @@ int ip6_push_pending_frames(struct sock *sk)
unsigned char proto = fl6->flowi6_proto;
int err = 0;
- if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
+ skb = __skb_dequeue(&sk->sk_write_queue);
+ if (skb == NULL)
goto out;
tail_skb = &(skb_shinfo(skb)->frag_list);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index e2b6cfb..92b3da5 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -501,8 +501,8 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
processing of the error. */
rcu_read_lock();
- if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->daddr,
- &ipv6h->saddr)) == NULL)
+ t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->daddr, &ipv6h->saddr);
+ if (t == NULL)
goto out;
tproto = ACCESS_ONCE(t->parms.proto);
@@ -550,7 +550,8 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
mtu = IPV6_MIN_MTU;
t->dev->mtu = mtu;
- if ((len = sizeof(*ipv6h) + ntohs(ipv6h->payload_len)) > mtu) {
+ len = sizeof(*ipv6h) + ntohs(ipv6h->payload_len);
+ if (len > mtu) {
rel_type = ICMPV6_PKT_TOOBIG;
rel_code = 0;
rel_info = mtu;
@@ -811,9 +812,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
int err;
rcu_read_lock();
-
- if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr,
- &ipv6h->daddr)) != NULL) {
+ t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, &ipv6h->daddr);
+ if (t != NULL) {
struct pcpu_sw_netstats *tstats;
tproto = ACCESS_ONCE(t->parms.proto);
@@ -1069,7 +1069,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
(skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
struct sk_buff *new_skb;
- if (!(new_skb = skb_realloc_headroom(skb, max_headroom)))
+ new_skb = skb_realloc_headroom(skb, max_headroom);
+ if (!new_skb)
goto tx_err_dst_release;
if (skb->sk)
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index ec84d03..8308216 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -287,8 +287,8 @@ static int vti6_rcv(struct sk_buff *skb)
const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
rcu_read_lock();
- if ((t = vti6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr,
- &ipv6h->daddr)) != NULL) {
+ t = vti6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, &ipv6h->daddr);
+ if (t != NULL) {
if (t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) {
rcu_read_unlock();
goto discard;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 7226697..7d7733a 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -2410,8 +2410,7 @@ static int mr6_msgsize(bool unresolved, int maxvif)
+ nla_total_size(0) /* RTA_MULTIPATH */
+ maxvif * NLA_ALIGN(sizeof(struct rtnexthop))
/* RTA_MFC_STATS */
- + nla_total_size(sizeof(struct rta_mfc_stats))
- ;
+ + nla_total_size(sizeof(struct rta_mfc_stats));
return len;
}
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 2c9f6bf..6828667 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -162,7 +162,8 @@ static void ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data)
memcpy(opt+2, data, data_len);
data_len += 2;
opt += data_len;
- if ((space -= data_len) > 0)
+ space -= data_len;
+ if (space > 0)
memset(opt, 0, space);
}
@@ -656,8 +657,8 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
if (skb && ipv6_chk_addr(dev_net(dev), &ipv6_hdr(skb)->saddr, dev, 1))
saddr = &ipv6_hdr(skb)->saddr;
-
- if ((probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES)) < 0) {
+ probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES);
+ if (probes < 0) {
if (!(neigh->nud_state & NUD_VALID)) {
ND_PRINTK(1, dbg,
"%s: trying to ucast probe in NUD_INVALID: %pI6\n",
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 51ab096..d7d70e6 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -429,7 +429,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
struct sk_buff *clone;
int i, plen = 0;
- if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL)
+ clone = alloc_skb(0, GFP_ATOMIC);
+ if (clone == NULL)
goto out_oom;
clone->next = head->next;
head->next = clone;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 660496d..213546b 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1241,7 +1241,8 @@ ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
goto done;
err = -ENOENT;
- if ((t = ipip6_tunnel_locate(net, &p, 0)) == NULL)
+ t = ipip6_tunnel_locate(net, &p, 0);
+ if (t == NULL)
goto done;
err = -EPERM;
if (t == netdev_priv(sitn->fb_tunnel_dev))
@@ -1836,8 +1837,8 @@ static int __net_init sit_init_net(struct net *net)
goto err_dev_free;
ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn);
-
- if ((err = register_netdev(sitn->fb_tunnel_dev)))
+ err = register_netdev(sitn->fb_tunnel_dev);
+ if (err)
goto err_reg_dev;
t = netdev_priv(sitn->fb_tunnel_dev);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 0ba3de4..33a0b09 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -357,7 +357,8 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
struct sock *sk;
const struct ipv6hdr *iph = ipv6_hdr(skb);
- if (unlikely(sk = skb_steal_sock(skb)))
+ sk = skb_steal_sock(skb);
+ if (unlikely(sk))
return sk;
return __udp6_lib_lookup(dev_net(skb_dst(skb)->dev), &iph->saddr, sport,
&iph->daddr, dport, inet6_iif(skb),
@@ -1026,7 +1027,8 @@ static int udp_v6_push_pending_frames(struct sock *sk)
fl6 = &inet->cork.fl.u.ip6;
/* Grab the skbuff where UDP header space exists. */
- if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
+ skb = skb_peek(&sk->sk_write_queue);
+ if (skb == NULL)
goto out;
/*
@@ -1456,7 +1458,8 @@ int __net_init udp6_proc_init(struct net *net)
return udp_proc_register(net, &udp6_seq_afinfo);
}
-void udp6_proc_exit(struct net *net) {
+void udp6_proc_exit(struct net *net)
+{
udp_proc_unregister(net, &udp6_seq_afinfo);
}
#endif /* CONFIG_PROC_FS */
--
1.9.1
^ permalink raw reply related
* [PATCH] net/mlx4: Fix EEH recovery failure
From: Gavin Shan @ 2014-11-22 10:56 UTC (permalink / raw)
To: netdev; +Cc: amirv, davem, Gavin Shan
The patch fixes couple of EEH recovery failures on PPC PowerNV
platform:
* Release reserved memory regions in mlx4_pci_err_detected().
Otherwise, __mlx4_init_one() fails because of reserving
same memory regions recursively.
* Disable PCI device in mlx4_pci_err_detected(). Otherwise,
pci_enable_device() in __mlx4_init_one() doesn't enable
the PCI device because it's already in enabled state indicated
by struct pci_dev::enable_cnt.
* Don't clear struct mlx4_priv instance in mlx4_pci_err_detected().
Otherwise, __mlx4_init_one() runs into kernel crash because
of dereferencing to NULL pointer.
With the patch applied, EEH recovery for mlx4 adapter succeeds on PPC
PowerNV platform.
# lspci
0003:0f:00.0 Network controller: Mellanox Technologies \
MT27500 Family [ConnectX-3]
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
drivers/net/ethernet/mellanox/mlx4/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 90de6e1..e118ac9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2809,7 +2809,6 @@ static void mlx4_unload_one(struct pci_dev *pdev)
kfree(dev->caps.qp1_proxy);
kfree(dev->dev_vfs);
- memset(priv, 0, sizeof(*priv));
priv->pci_dev_data = pci_dev_data;
priv->removed = 1;
}
@@ -2900,6 +2899,8 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
mlx4_unload_one(pdev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
return state == pci_channel_io_perm_failure ?
PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
--
1.8.3.2
^ permalink raw reply related
* [net 3/3] igb: Fixes needed for surprise removal support
From: Jeff Kirsher @ 2014-11-22 7:52 UTC (permalink / raw)
To: davem
Cc: Carolyn Wyborny, netdev, nhorman, sassmann, jogreene,
Yanir Lubetkin, Jeff Kirsher
In-Reply-To: <1416642774-17077-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Carolyn Wyborny <carolyn.wyborny@intel.com>
This patch adds some checks in order to prevent panic's on surprise
removal of devices during S0, S3, S4. Without this patch, Thunderbolt
type device removal will panic the system.
Signed-off-by: Yanir Lubetkin <yanirx.lubetkin@intel.com>
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/igb/igb_main.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index a2d72a8..487cd9c 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1012,7 +1012,8 @@ static void igb_free_q_vector(struct igb_adapter *adapter, int v_idx)
/* igb_get_stats64() might access the rings on this vector,
* we must wait a grace period before freeing it.
*/
- kfree_rcu(q_vector, rcu);
+ if (q_vector)
+ kfree_rcu(q_vector, rcu);
}
/**
@@ -1792,8 +1793,10 @@ void igb_down(struct igb_adapter *adapter)
adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE;
for (i = 0; i < adapter->num_q_vectors; i++) {
- napi_synchronize(&(adapter->q_vector[i]->napi));
- napi_disable(&(adapter->q_vector[i]->napi));
+ if (adapter->q_vector[i]) {
+ napi_synchronize(&adapter->q_vector[i]->napi);
+ napi_disable(&adapter->q_vector[i]->napi);
+ }
}
@@ -3717,7 +3720,8 @@ static void igb_free_all_tx_resources(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_free_tx_resources(adapter->tx_ring[i]);
+ if (adapter->tx_ring[i])
+ igb_free_tx_resources(adapter->tx_ring[i]);
}
void igb_unmap_and_free_tx_resource(struct igb_ring *ring,
@@ -3782,7 +3786,8 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_clean_tx_ring(adapter->tx_ring[i]);
+ if (adapter->tx_ring[i])
+ igb_clean_tx_ring(adapter->tx_ring[i]);
}
/**
@@ -3819,7 +3824,8 @@ static void igb_free_all_rx_resources(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_free_rx_resources(adapter->rx_ring[i]);
+ if (adapter->rx_ring[i])
+ igb_free_rx_resources(adapter->rx_ring[i]);
}
/**
@@ -3874,7 +3880,8 @@ static void igb_clean_all_rx_rings(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_ring(adapter->rx_ring[i]);
+ if (adapter->rx_ring[i])
+ igb_clean_rx_ring(adapter->rx_ring[i]);
}
/**
@@ -7404,6 +7411,8 @@ static int igb_resume(struct device *dev)
pci_restore_state(pdev);
pci_save_state(pdev);
+ if (!pci_device_is_present(pdev))
+ return -ENODEV;
err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
--
1.9.3
^ permalink raw reply related
* [net 2/3] ixgbe: fix use after free adapter->state test in ixgbe_remove/ixgbe_probe
From: Jeff Kirsher @ 2014-11-22 7:52 UTC (permalink / raw)
To: davem
Cc: Daniel Borkmann, netdev, nhorman, sassmann, jogreene, stable,
Mark Rustad, Jeff Kirsher
In-Reply-To: <1416642774-17077-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Daniel Borkmann <dborkman@redhat.com>
While working on a different issue, I noticed an annoying use
after free bug on my machine when unloading the ixgbe driver:
[ 8642.318797] ixgbe 0000:02:00.1: removed PHC on p2p2
[ 8642.742716] ixgbe 0000:02:00.1: complete
[ 8642.743784] BUG: unable to handle kernel paging request at ffff8807d3740a90
[ 8642.744828] IP: [<ffffffffa01c77dc>] ixgbe_remove+0xfc/0x1b0 [ixgbe]
[ 8642.745886] PGD 20c6067 PUD 81c1f6067 PMD 81c15a067 PTE 80000007d3740060
[ 8642.746956] Oops: 0002 [#1] SMP DEBUG_PAGEALLOC
[ 8642.748039] Modules linked in: [...]
[ 8642.752929] CPU: 1 PID: 1225 Comm: rmmod Not tainted 3.18.0-rc2+ #49
[ 8642.754203] Hardware name: Supermicro X10SLM-F/X10SLM-F, BIOS 1.1b 11/01/2013
[ 8642.755505] task: ffff8807e34d3fe0 ti: ffff8807b7204000 task.ti: ffff8807b7204000
[ 8642.756831] RIP: 0010:[<ffffffffa01c77dc>] [<ffffffffa01c77dc>] ixgbe_remove+0xfc/0x1b0 [ixgbe]
[...]
[ 8642.774335] Stack:
[ 8642.775805] ffff8807ee824098 ffff8807ee824098 ffffffffa01f3000 ffff8807ee824000
[ 8642.777326] ffff8807b7207e18 ffffffff8137720f ffff8807ee824098 ffff8807ee824098
[ 8642.778848] ffffffffa01f3068 ffff8807ee8240f8 ffff8807b7207e38 ffffffff8144180f
[ 8642.780365] Call Trace:
[ 8642.781869] [<ffffffff8137720f>] pci_device_remove+0x3f/0xc0
[ 8642.783395] [<ffffffff8144180f>] __device_release_driver+0x7f/0xf0
[ 8642.784876] [<ffffffff814421f8>] driver_detach+0xb8/0xc0
[ 8642.786352] [<ffffffff814414a9>] bus_remove_driver+0x59/0xe0
[ 8642.787783] [<ffffffff814429d0>] driver_unregister+0x30/0x70
[ 8642.789202] [<ffffffff81375c65>] pci_unregister_driver+0x25/0xa0
[ 8642.790657] [<ffffffffa01eb38e>] ixgbe_exit_module+0x1c/0xc8e [ixgbe]
[ 8642.792064] [<ffffffff810f93a2>] SyS_delete_module+0x132/0x1c0
[ 8642.793450] [<ffffffff81012c61>] ? do_notify_resume+0x61/0xa0
[ 8642.794837] [<ffffffff816d2029>] system_call_fastpath+0x12/0x17
The issue is that test_and_set_bit() done on adapter->state is being
performed *after* the netdevice has been freed via free_netdev().
When netdev is being allocated on initialization time, it allocates
a private area, here struct ixgbe_adapter, that resides after the
net_device structure. In ixgbe_probe(), the device init routine,
we set up the adapter after alloc_etherdev_mq() on the private area
and add a reference for the pci_dev as well via pci_set_drvdata().
Both in the error path of ixgbe_probe(), but also on module unload
when ixgbe_remove() is being called, commit 41c62843eb6a ("ixgbe:
Fix rcu warnings induced by LER") accesses adapter after free_netdev().
The patch stores the result in a bool and thus fixes above oops on my
side.
Fixes: 41c62843eb6a ("ixgbe: Fix rcu warnings induced by LER")
Cc: stable <stable@vger.kernel.org>
Cc: Mark Rustad <mark.d.rustad@intel.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 7acde46..82ffe8b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7979,6 +7979,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int i, err, pci_using_dac, expected_gts;
unsigned int indices = MAX_TX_QUEUES;
u8 part_str[IXGBE_PBANUM_LENGTH];
+ bool disable_dev = false;
#ifdef IXGBE_FCOE
u16 device_caps;
#endif
@@ -8369,13 +8370,14 @@ err_sw_init:
iounmap(adapter->io_addr);
kfree(adapter->mac_table);
err_ioremap:
+ disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state);
free_netdev(netdev);
err_alloc_etherdev:
pci_release_selected_regions(pdev,
pci_select_bars(pdev, IORESOURCE_MEM));
err_pci_reg:
err_dma:
- if (!adapter || !test_and_set_bit(__IXGBE_DISABLED, &adapter->state))
+ if (!adapter || disable_dev)
pci_disable_device(pdev);
return err;
}
@@ -8393,6 +8395,7 @@ static void ixgbe_remove(struct pci_dev *pdev)
{
struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *netdev = adapter->netdev;
+ bool disable_dev;
ixgbe_dbg_adapter_exit(adapter);
@@ -8442,11 +8445,12 @@ static void ixgbe_remove(struct pci_dev *pdev)
e_dev_info("complete\n");
kfree(adapter->mac_table);
+ disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state);
free_netdev(netdev);
pci_disable_pcie_error_reporting(pdev);
- if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state))
+ if (disable_dev)
pci_disable_device(pdev);
}
--
1.9.3
^ permalink raw reply related
* [net 1/3] ixgbe: Correctly disable VLAN filter in promiscuous mode
From: Jeff Kirsher @ 2014-11-22 7:52 UTC (permalink / raw)
To: davem
Cc: Vlad Yasevich, netdev, nhorman, sassmann, jogreene, stable,
Jacob Keller, Vladislav Yasevich, Jeff Kirsher
From: Vlad Yasevich <vyasevich@gmail.com>
IXGBE adapter seems to require that VLAN filtering be enabled if
VMDQ or SRIOV are enabled. When those functions are disabled,
VLAN filtering may be disabled in promiscuous mode.
Prior to commit a9b8943ee129 ("ixgbe: remove vlan_filter_disable
and enable functions")
The logic was correct. However, after the commit the logic
got reversed and VLAN filtered in now turned on when VMDQ/SRIOV
is disabled.
This patch changes the condition to enable hw vlan filtered
when VMDQ or SRIOV is enabled.
Fixes: a9b8943ee129 ("ixgbe: remove vlan_filter_disable and enable functions")
Cc: stable <stable@vger.kernel.org>
CC: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
Acked-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index d2df4e3..7acde46 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3936,8 +3936,8 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
* if SR-IOV and VMDQ are disabled - otherwise ensure
* that hardware VLAN filters remain enabled.
*/
- if (!(adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED |
- IXGBE_FLAG_SRIOV_ENABLED)))
+ if (adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED |
+ IXGBE_FLAG_SRIOV_ENABLED))
vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
} else {
if (netdev->flags & IFF_ALLMULTI) {
--
1.9.3
^ permalink raw reply related
* [PATCH] can: eliminate banner[] variable and switch to pr_info()
From: Jeremiah Mahler @ 2014-11-22 7:42 UTC (permalink / raw)
To: Oliver Hartkopp
Cc: David S. Miller, linux-can, netdev, linux-kernel, Jeremiah Mahler
Several CAN modules use a design pattern with a banner[] variable at the
top which defines a string that is used once during init to print the
banner. The string is also embedded with KERN_INFO which makes it
printk() specific.
Improve the code by eliminating the banner[] variable and moving the
string to where it is printed. Then switch from printk(KERN_INFO to
pr_info() for the lines that were changed.
Signed-off-by: Jeremiah Mahler <jmmahler@gmail.com>
---
net/can/af_can.c | 5 +----
net/can/bcm.c | 4 +---
net/can/raw.c | 4 +---
3 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index ce82337..ac05be1 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -64,9 +64,6 @@
#include "af_can.h"
-static __initconst const char banner[] = KERN_INFO
- "can: controller area network core (" CAN_VERSION_STRING ")\n";
-
MODULE_DESCRIPTION("Controller Area Network PF_CAN core");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>, "
@@ -896,7 +893,7 @@ static __init int can_init(void)
offsetof(struct can_frame, data) !=
offsetof(struct canfd_frame, data));
- printk(banner);
+ pr_info("can: controller area network core (" CAN_VERSION_STRING ")\n");
memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list));
diff --git a/net/can/bcm.c b/net/can/bcm.c
index dcb75c0..9aa3f76 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -78,8 +78,6 @@
(CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG))
#define CAN_BCM_VERSION CAN_VERSION
-static __initconst const char banner[] = KERN_INFO
- "can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n";
MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
MODULE_LICENSE("Dual BSD/GPL");
@@ -1615,7 +1613,7 @@ static int __init bcm_module_init(void)
{
int err;
- printk(banner);
+ pr_info("can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n");
err = can_proto_register(&bcm_can_proto);
if (err < 0) {
diff --git a/net/can/raw.c b/net/can/raw.c
index 081e81f..e3250e2 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -56,8 +56,6 @@
#include <net/net_namespace.h>
#define CAN_RAW_VERSION CAN_VERSION
-static __initconst const char banner[] =
- KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n";
MODULE_DESCRIPTION("PF_CAN raw protocol");
MODULE_LICENSE("Dual BSD/GPL");
@@ -810,7 +808,7 @@ static __init int raw_module_init(void)
{
int err;
- printk(banner);
+ pr_info("can: raw protocol (rev " CAN_RAW_VERSION ")\n");
err = can_proto_register(&raw_can_proto);
if (err < 0)
--
2.1.3
^ permalink raw reply related
* Re: [RFC] situation with csum_and_copy_... API
From: David Miller @ 2014-11-22 7:24 UTC (permalink / raw)
To: viro; +Cc: torvalds, netdev, linux-kernel, target-devel, nab, hch
In-Reply-To: <20141122042856.GZ7996@ZenIV.linux.org.uk>
From: Al Viro <viro@ZenIV.linux.org.uk>
Date: Sat, 22 Nov 2014 04:28:57 +0000
> OK, here's the next bunch. Sorry about the delay, iov_iter.c stuff
> took most of the day (and it's not included in this pile). Please, review.
I read over this stuff twice and this series looks fine to me.
Since this is the weekend... maybe wait until Monday for other feedback
then give me a pull request?
Thanks Al.
^ permalink raw reply
* [PATCH 1/1] fix return code from fib_rules_lookup()
From: Ani Sinha @ 2014-11-22 6:25 UTC (permalink / raw)
To: davem, maze, edumazet; +Cc: netdev, fruggeri, ani
fib_lookup() api returns two different types of error
codes. When no custom FIB rules are installed and
lookup fails, it returns ENETUNREACH. However, when
custom rules are installed, __fib_lookup() calls
fib_rules_lookup() which returns ESRCH when the rule
lookup fails. This patch makes both code paths return
identical error codes under lookup failure.
Signed-off-by: Ani Sinha <ani@arista.com>
---
net/core/fib_rules.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 185c341..ab8e732 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -242,7 +242,7 @@ jumped:
}
}
- err = -ESRCH;
+ err = -ENETUNREACH;
out:
rcu_read_unlock();
--
1.7.4.4
^ permalink raw reply related
* Re: [net-next 01/17] i40e: Remove unneeded break statement
From: Jeff Kirsher @ 2014-11-22 5:58 UTC (permalink / raw)
To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene
In-Reply-To: <1416635708-4765-2-git-send-email-jeffrey.t.kirsher@intel.com>
[-- Attachment #1: Type: text/plain, Size: 728 bytes --]
On Fri, 2014-11-21 at 21:54 -0800, Jeff Kirsher wrote:
> From: Shannon Nelson <shannon.nelson@intel.com>
>
> This case statement is empty and the fall through just breaks out
> so remove the break and let it fall through to break out.
>
> Change-ID: I1b5ba9870d5245ca80bfca6e7f5f089e2eb8ccb0
> Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_main.c | 2 --
> 1 file changed, 2 deletions(-)
Disregard this patch, I fixed a mis-spelled word in the patch, but
forgot to cleanup (ie remove) this patch from the group of patches to be
sent. I have already sent out the "fixed" patch in the series.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* [net-next 17/17] i40e: Bump i40e version to 1.2.2 and i40evf version to 1.0.6
From: Jeff Kirsher @ 2014-11-22 5:55 UTC (permalink / raw)
To: davem; +Cc: Catherine Sullivan, netdev, nhorman, sassmann, jogreene,
Jeff Kirsher
In-Reply-To: <1416635708-4765-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Catherine Sullivan <catherine.sullivan@intel.com>
Bump version.
Change-ID: I4264e81dcfb57ec46a3ede54b0a6cb25b497d3cb
Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 4 ++--
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index a7090f4..59bacc2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -38,8 +38,8 @@ static const char i40e_driver_string[] =
#define DRV_KERN "-k"
#define DRV_VERSION_MAJOR 1
-#define DRV_VERSION_MINOR 1
-#define DRV_VERSION_BUILD 23
+#define DRV_VERSION_MINOR 2
+#define DRV_VERSION_BUILD 2
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 62456f8..cabaf59 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -36,7 +36,7 @@ char i40evf_driver_name[] = "i40evf";
static const char i40evf_driver_string[] =
"Intel(R) XL710/X710 Virtual Function Network Driver";
-#define DRV_VERSION "1.0.5"
+#define DRV_VERSION "1.0.6"
const char i40evf_driver_version[] = DRV_VERSION;
static const char i40evf_copyright[] =
"Copyright (c) 2013 - 2014 Intel Corporation.";
--
1.9.3
^ permalink raw reply related
* [net-next 15/17] i40e: increase ARQ size
From: Jeff Kirsher @ 2014-11-22 5:55 UTC (permalink / raw)
To: davem; +Cc: Mitch Williams, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1416635708-4765-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Mitch Williams <mitch.a.williams@intel.com>
The ARQ needs to have at least as many entries as VFs, or the VFs will
get errors from the FW when they send messages to the PF. Since we don't
know how many VFs we'll end up with, just set up 128 descriptors.
Change-ID: I04ae3d1c7faf09110eb782214e9c05aeb62a6c59
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index 464342a..fc50f64 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -87,7 +87,7 @@
#define I40E_MINIMUM_FCOE 1 /* minimum number of QPs for FCoE */
#endif /* I40E_FCOE */
#define I40E_MAX_AQ_BUF_SIZE 4096
-#define I40E_AQ_LEN 32
+#define I40E_AQ_LEN 128
#define I40E_AQ_WORK_LIMIT 16
#define I40E_MAX_USER_PRIORITY 8
#define I40E_DEFAULT_MSG_ENABLE 4
--
1.9.3
^ permalink raw reply related
* [net-next 16/17] i40e: get pf_id from HW rather than PCI function
From: Jeff Kirsher @ 2014-11-22 5:55 UTC (permalink / raw)
To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1416635708-4765-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Shannon Nelson <shannon.nelson@intel.com>
Getting the pf_id from the function number was a good place to start,
but when the PF was setup in passthru mode, the PCI bus/device/function
was virtualized and the number in the VM is different from the number in
the bare metal. This caused HW configuration issues when the wrong pf_id
was used to set up the HMC and other structures. The PF_FUNC_RID register
has the real bus/device/function information as configured by the BIOS,
so use that for a better number. This works in NPAR mode as well.
Change-ID: I65e3dd6c97594890c2bad566b83cc670b1dae534
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Acked-by: Kevin Scott <kevin.c.scott@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_common.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index ec63bcb..3d741ee 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -550,7 +550,7 @@ struct i40e_rx_ptype_decoded i40e_ptype_lookup[] = {
i40e_status i40e_init_shared_code(struct i40e_hw *hw)
{
i40e_status status = 0;
- u32 reg;
+ u32 port, ari, func_rid;
i40e_set_mac_type(hw);
@@ -563,18 +563,17 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
hw->phy.get_link_info = true;
- /* Determine port number */
- reg = rd32(hw, I40E_PFGEN_PORTNUM);
- reg = ((reg & I40E_PFGEN_PORTNUM_PORT_NUM_MASK) >>
- I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT);
- hw->port = (u8)reg;
-
- /* Determine the PF number based on the PCI fn */
- reg = rd32(hw, I40E_GLPCI_CAPSUP);
- if (reg & I40E_GLPCI_CAPSUP_ARI_EN_MASK)
- hw->pf_id = (u8)((hw->bus.device << 3) | hw->bus.func);
+ /* Determine port number and PF number*/
+ port = (rd32(hw, I40E_PFGEN_PORTNUM) & I40E_PFGEN_PORTNUM_PORT_NUM_MASK)
+ >> I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT;
+ hw->port = (u8)port;
+ ari = (rd32(hw, I40E_GLPCI_CAPSUP) & I40E_GLPCI_CAPSUP_ARI_EN_MASK) >>
+ I40E_GLPCI_CAPSUP_ARI_EN_SHIFT;
+ func_rid = rd32(hw, I40E_PF_FUNC_RID);
+ if (ari)
+ hw->pf_id = (u8)(func_rid & 0xff);
else
- hw->pf_id = (u8)hw->bus.func;
+ hw->pf_id = (u8)(func_rid & 0x7);
status = i40e_init_nvm(hw);
return status;
--
1.9.3
^ permalink raw reply related
* [net-next 13/17] i40evf: refactor ethtool RSS handling
From: Jeff Kirsher @ 2014-11-22 5:55 UTC (permalink / raw)
To: davem; +Cc: Mitch Williams, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1416635708-4765-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Mitch Williams <mitch.a.williams@intel.com>
Add support for setting the RSS key as it is now implemented.
Change-ID: I9290ae3ea99d0e46053540650f95e24a24e453f1
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 66 ++++++++++++++++------
1 file changed, 50 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index 69a269b..ed0e4dc 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -608,6 +608,19 @@ static void i40evf_get_channels(struct net_device *netdev,
ch->combined_count = adapter->num_active_queues;
}
+#define I40EVF_HLUT_ARRAY_SIZE ((I40E_VFQF_HLUT_MAX_INDEX + 1) * 4)
+#define I40EVF_HKEY_ARRAY_SIZE ((I40E_VFQF_HKEY_MAX_INDEX * 1) * 4)
+/**
+ * i40evf_get_rxfh_key_size - get the RSS hash key size
+ * @netdev: network interface device structure
+ *
+ * Returns the table size.
+ **/
+static u32 i40evf_get_rxfh_key_size(struct net_device *netdev)
+{
+ return I40EVF_HKEY_ARRAY_SIZE;
+}
+
/**
* i40evf_get_rxfh_indir_size - get the rx flow hash indirection table size
* @netdev: network interface device structure
@@ -616,7 +629,7 @@ static void i40evf_get_channels(struct net_device *netdev,
**/
static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
{
- return (I40E_VFQF_HLUT_MAX_INDEX + 1) * 4;
+ return I40EVF_HLUT_ARRAY_SIZE;
}
/**
@@ -631,19 +644,28 @@ static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
{
struct i40evf_adapter *adapter = netdev_priv(netdev);
struct i40e_hw *hw = &adapter->hw;
- u32 hlut_val;
+ u32 reg_val;
int i, j;
for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
- hlut_val = rd32(hw, I40E_VFQF_HLUT(i));
- indir[j++] = hlut_val & 0xff;
- indir[j++] = (hlut_val >> 8) & 0xff;
- indir[j++] = (hlut_val >> 16) & 0xff;
- indir[j++] = (hlut_val >> 24) & 0xff;
+ reg_val = rd32(hw, I40E_VFQF_HLUT(i));
+ indir[j++] = reg_val & 0xff;
+ indir[j++] = (reg_val >> 8) & 0xff;
+ indir[j++] = (reg_val >> 16) & 0xff;
+ indir[j++] = (reg_val >> 24) & 0xff;
+ }
+
+ if (key) {
+ for (i = 0, j = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) {
+ reg_val = rd32(hw, I40E_VFQF_HKEY(i));
+ key[j++] = (u8)(reg_val & 0xff);
+ key[j++] = (u8)((reg_val >> 8) & 0xff);
+ key[j++] = (u8)((reg_val >> 16) & 0xff);
+ key[j++] = (u8)((reg_val >> 24) & 0xff);
+ }
}
return 0;
}
-
/**
* i40evf_set_rxfh - set the rx flow hash indirection table
* @netdev: network interface device structure
@@ -658,17 +680,27 @@ static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
{
struct i40evf_adapter *adapter = netdev_priv(netdev);
struct i40e_hw *hw = &adapter->hw;
- u32 hlut_val;
+ u32 reg_val;
int i, j;
- for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
- hlut_val = indir[j++];
- hlut_val |= indir[j++] << 8;
- hlut_val |= indir[j++] << 16;
- hlut_val |= indir[j++] << 24;
- wr32(hw, I40E_VFQF_HLUT(i), hlut_val);
+ if (indir) {
+ for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
+ reg_val = indir[j++];
+ reg_val |= indir[j++] << 8;
+ reg_val |= indir[j++] << 16;
+ reg_val |= indir[j++] << 24;
+ wr32(hw, I40E_VFQF_HLUT(i), reg_val);
+ }
+ }
+ if (key) {
+ for (i = 0, j = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) {
+ reg_val = key[j++];
+ reg_val |= key[j++] << 8;
+ reg_val |= key[j++] << 16;
+ reg_val |= key[j++] << 24;
+ wr32(hw, I40E_VFQF_HKEY(i), reg_val);
+ }
}
-
return 0;
}
@@ -687,10 +719,12 @@ static const struct ethtool_ops i40evf_ethtool_ops = {
.set_coalesce = i40evf_set_coalesce,
.get_rxnfc = i40evf_get_rxnfc,
.set_rxnfc = i40evf_set_rxnfc,
+ .get_rxfh_key_size = i40evf_get_rxfh_key_size,
.get_rxfh_indir_size = i40evf_get_rxfh_indir_size,
.get_rxfh = i40evf_get_rxfh,
.set_rxfh = i40evf_set_rxfh,
.get_channels = i40evf_get_channels,
+
};
/**
--
1.9.3
^ permalink raw reply related
* [net-next 14/17] i40e: implement ethtool RSS config
From: Jeff Kirsher @ 2014-11-22 5:55 UTC (permalink / raw)
To: davem; +Cc: Mitch Williams, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1416635708-4765-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Mitch Williams <mitch.a.williams@intel.com>
Support ethtool methods for getting and setting the RSS look-up table.
Change-ID: I52707fb371fc11fe9fd4c287e08542cde38f79d4
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 104 +++++++++++++++++++++++++
1 file changed, 104 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index fcd815d..f9f68ea 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -2237,6 +2237,106 @@ static int i40e_set_channels(struct net_device *dev,
return -EINVAL;
}
+#define I40E_HLUT_ARRAY_SIZE ((I40E_PFQF_HLUT_MAX_INDEX + 1) * 4)
+#define I40E_HKEY_ARRAY_SIZE ((I40E_PFQF_HKEY_MAX_INDEX * 1) * 4)
+/**
+ * i40e_get_rxfh_key_size - get the RSS hash key size
+ * @netdev: network interface device structure
+ *
+ * Returns the table size.
+ **/
+static u32 i40e_get_rxfh_key_size(struct net_device *netdev)
+{
+ return I40E_HKEY_ARRAY_SIZE;
+}
+
+/**
+ * i40e_get_rxfh_indir_size - get the rx flow hash indirection table size
+ * @netdev: network interface device structure
+ *
+ * Returns the table size.
+ **/
+static u32 i40e_get_rxfh_indir_size(struct net_device *netdev)
+{
+ return I40E_HLUT_ARRAY_SIZE;
+}
+
+/**
+ * i40e_get_rxfh - get the rx flow hash indirection table
+ * @netdev: network interface device structure
+ * @indir: indirection table
+ * @key: hash key
+ *
+ * Reads the indirection table directly from the hardware. Always returns 0.
+ **/
+static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+ u32 reg_val;
+ int i, j;
+
+ for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
+ reg_val = rd32(hw, I40E_PFQF_HLUT(i));
+ indir[j++] = reg_val & 0xff;
+ indir[j++] = (reg_val >> 8) & 0xff;
+ indir[j++] = (reg_val >> 16) & 0xff;
+ indir[j++] = (reg_val >> 24) & 0xff;
+ }
+ if (key) {
+ for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
+ reg_val = rd32(hw, I40E_PFQF_HKEY(i));
+ key[j++] = (u8)(reg_val & 0xff);
+ key[j++] = (u8)((reg_val >> 8) & 0xff);
+ key[j++] = (u8)((reg_val >> 16) & 0xff);
+ key[j++] = (u8)((reg_val >> 24) & 0xff);
+ }
+ }
+ return 0;
+}
+
+/**
+ * i40e_set_rxfh - set the rx flow hash indirection table
+ * @netdev: network interface device structure
+ * @indir: indirection table
+ * @key: hash key
+ *
+ * Returns -EINVAL if the table specifies an inavlid queue id, otherwise
+ * returns 0 after programming the table.
+ **/
+static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
+ const u8 *key)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+ u32 reg_val;
+ int i, j;
+
+ if (indir) {
+ for (i = 0, j = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++) {
+ reg_val = indir[j++];
+ reg_val |= indir[j++] << 8;
+ reg_val |= indir[j++] << 16;
+ reg_val |= indir[j++] << 24;
+ wr32(hw, I40E_PFQF_HLUT(i), reg_val);
+ }
+ }
+ if (key) {
+ for (i = 0, j = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
+ reg_val = key[j++];
+ reg_val |= key[j++] << 8;
+ reg_val |= key[j++] << 16;
+ reg_val |= key[j++] << 24;
+ wr32(hw, I40E_PFQF_HKEY(i), reg_val);
+ }
+ }
+ return 0;
+}
+
static const struct ethtool_ops i40e_ethtool_ops = {
.get_settings = i40e_get_settings,
.set_settings = i40e_set_settings,
@@ -2265,6 +2365,10 @@ static const struct ethtool_ops i40e_ethtool_ops = {
.get_ethtool_stats = i40e_get_ethtool_stats,
.get_coalesce = i40e_get_coalesce,
.set_coalesce = i40e_set_coalesce,
+ .get_rxfh_key_size = i40e_get_rxfh_key_size,
+ .get_rxfh_indir_size = i40e_get_rxfh_indir_size,
+ .get_rxfh = i40e_get_rxfh,
+ .set_rxfh = i40e_set_rxfh,
.get_channels = i40e_get_channels,
.set_channels = i40e_set_channels,
.get_ts_info = i40e_get_ts_info,
--
1.9.3
^ 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