* Re: [PATCH] irq: Add node_affinity CPU masks for smarter irqbalance hints
From: Eric Dumazet @ 2009-11-25 10:30 UTC (permalink / raw)
To: Andi Kleen
Cc: David Miller, peter.p.waskiewicz.jr, peterz, arjan, yong.zhang0,
linux-kernel, arjan, netdev
In-Reply-To: <4B0C4624.9080607@gmail.com>
Eric Dumazet a écrit :
> Andi Kleen a écrit :
>> They are typically allocated with dma_alloc_coherent(), which does
>> allocate a continuous area. In theory you could do interleaving
>> with IOMMus, but just putting it on the same node as the device
>> is probably better.
>
> There are two parts, biggest one allocated with vmalloc()
> (to hold struct ixgbe_rx_buffer array, 32 bytes or more per entry),
> only used by driver (not adapter)
>
> and one allocated with pci_alloc_consistent()
> (to hold ixgbe_adv_tx_desc array, 16 bytes per entry)
>
> vmalloc() one could be spreaded on many nodes.
> I am not speaking about the pci_alloc_consistent() one :)
>
BTW, I found my Nehalem dev machine behaves strangly, defeating all
my NUMA tweaks. (This is an HP DL380 G6)
It has two sockets, populated with two E5530 @2.4GH.
Each cpu has 2x4GB RAM modules.
It claims having two memory nodes, but all cpus are on Node 0
dmesg | grep -i node
[ 0.000000] SRAT: PXM 0 -> APIC 0 -> Node 0
[ 0.000000] SRAT: PXM 0 -> APIC 1 -> Node 0
[ 0.000000] SRAT: PXM 0 -> APIC 2 -> Node 0
[ 0.000000] SRAT: PXM 0 -> APIC 3 -> Node 0
[ 0.000000] SRAT: PXM 0 -> APIC 4 -> Node 0
[ 0.000000] SRAT: PXM 0 -> APIC 5 -> Node 0
[ 0.000000] SRAT: PXM 0 -> APIC 6 -> Node 0
[ 0.000000] SRAT: PXM 0 -> APIC 7 -> Node 0
[ 0.000000] SRAT: Node 0 PXM 0 0-e0000000
[ 0.000000] SRAT: Node 0 PXM 0 100000000-220000000
[ 0.000000] SRAT: Node 1 PXM 1 220000000-420000000
[ 0.000000] Bootmem setup node 0 0000000000000000-0000000220000000
[ 0.000000] NODE_DATA [0000000000001000 - 0000000000004fff]
[ 0.000000] Bootmem setup node 1 0000000220000000-000000041ffff000
[ 0.000000] NODE_DATA [0000000220000000 - 0000000220003fff]
[ 0.000000] [ffffea0000000000-ffffea00087fffff] PMD -> [ffff880028600000-ffff8800305fffff] on node 0
[ 0.000000] [ffffea0008800000-ffffea00107fffff] PMD -> [ffff880220200000-ffff8802281fffff] on node 1
[ 0.000000] Movable zone start PFN for each node
[ 0.000000] early_node_map[5] active PFN ranges
[ 0.000000] On node 0 totalpages: 2094543
[ 0.000000] On node 1 totalpages: 2097151
[ 0.000000] NR_CPUS:16 nr_cpumask_bits:16 nr_cpu_ids:16 nr_node_ids:2
[ 0.000000] SLUB: Genslabs=14, HWalign=64, Order=0-3, MinObjects=0, CPUs=16, Nodes=2
[ 0.004756] Inode-cache hash table entries: 1048576 (order: 11, 8388608 bytes)
[ 0.007213] CPU 0/0x0 -> Node 0
[ 0.398104] CPU 1/0x10 -> Node 0
[ 0.557854] CPU 2/0x4 -> Node 0
[ 0.717606] CPU 3/0x14 -> Node 0
[ 0.877357] CPU 4/0x2 -> Node 0
[ 1.037109] CPU 5/0x12 -> Node 0
[ 1.196860] CPU 6/0x6 -> Node 0
[ 1.356611] CPU 7/0x16 -> Node 0
[ 1.516365] CPU 8/0x1 -> Node 0
[ 1.676114] CPU 9/0x11 -> Node 0
[ 1.835865] CPU 10/0x5 -> Node 0
[ 1.995616] CPU 11/0x15 -> Node 0
[ 2.155367] CPU 12/0x3 -> Node 0
[ 2.315119] CPU 13/0x13 -> Node 0
[ 2.474870] CPU 14/0x7 -> Node 0
[ 2.634621] CPU 15/0x17 -> Node 0
# cat /proc/buddyinfo
Node 0, zone DMA 2 2 2 1 1 1 1 0 1 1 3
Node 0, zone DMA32 5 11 4 5 4 12 1 4 4 5 834
Node 0, zone Normal 4109 120 98 153 67 35 21 15 11 10 109
Node 1, zone Normal 7 17 10 12 7 14 5 7 6 5 2004
This is with net-next-2.6, I'll try linux-2.6
^ permalink raw reply
* [PATCH 1/3] xfrm: Define new XFRM netlink auth attribute with specified truncation bits
From: Martin Willi @ 2009-11-25 10:29 UTC (permalink / raw)
To: Herbert Xu; +Cc: linux-crypto, netdev
In-Reply-To: <cover.1259142145.git.martin@strongswan.org>
The new XFRMA_ALG_AUTH_TRUNC attribute taking a xfrm_algo_auth as
argument allows the installation of authentication algorithms with
a truncation length specified in userspace, i.e. SHA256 with 128 bit
instead of 96 bit truncation.
Signed-off-by: Martin Willi <martin@strongswan.org>
---
include/linux/xfrm.h | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 2d4ec15..d28e853 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -96,6 +96,13 @@ struct xfrm_algo {
char alg_key[0];
};
+struct xfrm_algo_auth {
+ char alg_name[64];
+ unsigned int alg_key_len; /* in bits */
+ unsigned int alg_trunc_len; /* in bits */
+ char alg_key[0];
+};
+
struct xfrm_algo_aead {
char alg_name[64];
unsigned int alg_key_len; /* in bits */
@@ -283,6 +290,7 @@ enum xfrm_attr_type_t {
XFRMA_MIGRATE,
XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */
XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */
+ XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
--
1.6.3.3
^ permalink raw reply related
* [PATCH 0/3] xfrm: Custom truncation lengths for authentication algorithms
From: Martin Willi @ 2009-11-25 10:29 UTC (permalink / raw)
To: Herbert Xu; +Cc: linux-crypto, netdev
The following patchset adds support for defining truncation lengths
for authentication algorithms in userspace. The main purpose for this
is to support SHA256 in IPsec using the standardized 128 bit
instead of the currently used 96 bit truncation.
Martin Willi (3):
xfrm: Define new XFRM netlink auth attribute with specified
truncation bits
xfrm: Store aalg in xfrm_state with a user specified truncation
length
xfrm: Use the user specified truncation length in ESP and AH
include/linux/xfrm.h | 8 +++
include/net/xfrm.h | 12 ++++-
net/ipv4/ah4.c | 2 +-
net/ipv4/esp4.c | 2 +-
net/ipv6/ah6.c | 2 +-
net/ipv6/esp6.c | 2 +-
net/xfrm/xfrm_state.c | 2 +-
net/xfrm/xfrm_user.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++---
8 files changed, 145 insertions(+), 14 deletions(-)
^ permalink raw reply
* Re: [PATCH 1/1] Defer skb allocation for both mergeable buffers and big packets in virtio_net
From: Rusty Russell @ 2009-11-25 10:20 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Shirley Ma, Eric Dumazet, Avi Kivity, netdev, kvm, linux-kernel,
Hollis Blanchard
In-Reply-To: <20091125091530.GA6357@redhat.com>
On Wed, 25 Nov 2009 07:45:30 pm Michael S. Tsirkin wrote:
> Hmm, is it really worth it to save a header copy if it's linear? We are
> going to access it anyway, and it fits into one cacheline nicely. On
> the other hand we have more code making life harder for compiler and
> processor.
Not sure: I think there would be many places where it would be useful.
We do a similar thing in the kernel to inspect non-linear packets, and
it's served us well.
Cheers,
Rusty.
^ permalink raw reply
* [ethtool PATCH] ethtool: Add Direct Attach to the available connector ports
From: Jeff Kirsher @ 2009-11-25 10:13 UTC (permalink / raw)
To: jeff, davem, shemminger
Cc: netdev, gospo, Peter P Waskiewicz Jr, Jeff Kirsher
From: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>
This adds Direct Attach SFP+ types to the connector ports
for the GSET mode.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
ethtool-copy.h | 3 +++
ethtool.c | 6 ++++++
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/ethtool-copy.h b/ethtool-copy.h
index 3ca4e2c..7ea5a1b 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -402,6 +402,9 @@ struct ethtool_rxnfc {
#define PORT_MII 0x02
#define PORT_FIBRE 0x03
#define PORT_BNC 0x04
+#define PORT_DA 0x05
+#define PORT_NONE 0xef
+#define PORT_OTHER 0xff
/* Which transceiver to use. */
#define XCVR_INTERNAL 0x00
diff --git a/ethtool.c b/ethtool.c
index 0110682..5b77614 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -942,6 +942,12 @@ static int dump_ecmd(struct ethtool_cmd *ep)
case PORT_FIBRE:
fprintf(stdout, "FIBRE\n");
break;
+ case PORT_DA:
+ fprintf(stdout, "Direct Attach Copper\n");
+ break;
+ case PORT_NONE:
+ fprintf(stdout, "None\n");
+ break;
default:
fprintf(stdout, "Unknown! (%i)\n", ep->port);
break;
^ permalink raw reply related
* [net-next-2.6 PATCH 2/2] ixgbe: Display currently attached PHY through ethtool
From: Jeff Kirsher @ 2009-11-25 10:11 UTC (permalink / raw)
To: davem, jeff, shemminger
Cc: netdev, gospo, Peter P Waskiewicz Jr, Jeff Kirsher
In-Reply-To: <20091125101128.24430.89112.stgit@localhost.localdomain>
From: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>
This patch extends the ethtool interface to display what PHY
is currently connected to a NIC. The results can be viewed in
ethtool ethX output.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_ethtool.c | 50 +++++++++++++++++++++++++++++++++++++
1 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 84ab4db..ec59c53 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -205,6 +205,56 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->autoneg = AUTONEG_DISABLE;
}
+ /* Get PHY type */
+ switch (adapter->hw.phy.type) {
+ case ixgbe_phy_tn:
+ case ixgbe_phy_cu_unknown:
+ /* Copper 10G-BASET */
+ ecmd->port = PORT_TP;
+ break;
+ case ixgbe_phy_qt:
+ ecmd->port = PORT_FIBRE;
+ break;
+ case ixgbe_phy_nl:
+ case ixgbe_phy_tw_tyco:
+ case ixgbe_phy_tw_unknown:
+ case ixgbe_phy_sfp_ftl:
+ case ixgbe_phy_sfp_avago:
+ case ixgbe_phy_sfp_intel:
+ case ixgbe_phy_sfp_unknown:
+ switch (adapter->hw.phy.sfp_type) {
+ /* SFP+ devices, further checking needed */
+ case ixgbe_sfp_type_da_cu:
+ case ixgbe_sfp_type_da_cu_core0:
+ case ixgbe_sfp_type_da_cu_core1:
+ ecmd->port = PORT_DA;
+ break;
+ case ixgbe_sfp_type_sr:
+ case ixgbe_sfp_type_lr:
+ case ixgbe_sfp_type_srlr_core0:
+ case ixgbe_sfp_type_srlr_core1:
+ ecmd->port = PORT_FIBRE;
+ break;
+ case ixgbe_sfp_type_not_present:
+ ecmd->port = PORT_NONE;
+ break;
+ case ixgbe_sfp_type_unknown:
+ default:
+ ecmd->port = PORT_OTHER;
+ break;
+ }
+ break;
+ case ixgbe_phy_xaui:
+ ecmd->port = PORT_NONE;
+ break;
+ case ixgbe_phy_unknown:
+ case ixgbe_phy_generic:
+ case ixgbe_phy_sfp_unsupported:
+ default:
+ ecmd->port = PORT_OTHER;
+ break;
+ }
+
hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
if (link_up) {
ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
^ permalink raw reply related
* [net-next-2.6 PATCH 1/2] ethtool: Add Direct Attach support to connector port reporting
From: Jeff Kirsher @ 2009-11-25 10:11 UTC (permalink / raw)
To: davem, jeff, shemminger
Cc: netdev, gospo, Peter P Waskiewicz Jr, Jeff Kirsher
From: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>
This patch allows a base driver to specify Direct Attach as the
type of port through the ethtool interface.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
include/linux/ethtool.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index edd03b7..bcaa0e0 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -631,6 +631,8 @@ struct ethtool_ops {
#define PORT_MII 0x02
#define PORT_FIBRE 0x03
#define PORT_BNC 0x04
+#define PORT_DA 0x05
+#define PORT_NONE 0xef
#define PORT_OTHER 0xff
/* Which transceiver to use. */
^ permalink raw reply related
* Re: [PATCH net-next-2.6] ixgbe: Fix TX stats accounting
From: Jeff Kirsher @ 2009-11-25 9:38 UTC (permalink / raw)
To: Eric Dumazet
Cc: Peter P Waskiewicz Jr, robert@herjulf.net, Jesper Dangaard Brouer,
Linux Netdev List, David S. Miller
In-Reply-To: <4B0CF974.2070702@gmail.com>
On Wed, Nov 25, 2009 at 01:31, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Jeff Kirsher a écrit :
>>
>> Thanks Eric. I have added the patch to my tree for testing and review.
>>
>
> Thanks Jeff, a similar problem on RX stats should also be addressed.
>
> Is your tree public ?
>
Unfortunately we do not have a public tree at this time. I do welcome
any patches you want to submit.
--
Cheers,
Jeff
^ permalink raw reply
* Re: [PATCH net-next-2.6] ixgbe: Fix TX stats accounting
From: Eric Dumazet @ 2009-11-25 9:31 UTC (permalink / raw)
To: Jeff Kirsher
Cc: Peter P Waskiewicz Jr, robert@herjulf.net, Jesper Dangaard Brouer,
Linux Netdev List, David S. Miller
In-Reply-To: <9929d2390911242338m6c4b322dod7a8af4c3c386d56@mail.gmail.com>
Jeff Kirsher a écrit :
>
> Thanks Eric. I have added the patch to my tree for testing and review.
>
Thanks Jeff, a similar problem on RX stats should also be addressed.
Is your tree public ?
^ permalink raw reply
* [PATCH] don't wrap mlx4_remove_one in __devexit_p
From: Uwe Kleine-König @ 2009-11-25 9:23 UTC (permalink / raw)
To: linux-kernel
Cc: Roland Dreier, Yevgeny Petrilin, Yang Hongyang, Jack Morgenstein,
Eli Cohen, Andrew Morton, netdev, Franco Fichtner
In-Reply-To: <4B0CF685.6060208@lastsummer.de>
The function mlx4_remove_one is defined in .text, so there is no need to
wrap it with __devexit_p.
While at it add a trailing comma to the section initializer.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: Roland Dreier <rolandd@cisco.com>
Cc: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Cc: Yang Hongyang <yanghy@cn.fujitsu.com>
Cc: Jack Morgenstein <jackm@dev.mellanox.co.il>
Cc: Eli Cohen <eli@mellanox.co.il>
Cc: linux-kernel@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: netdev@vger.kernel.org
Cc: Franco Fichtner <franco@lastsummer.de>
---
drivers/net/mlx4/main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 291a505..acc2878 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -1293,7 +1293,7 @@ static struct pci_driver mlx4_driver = {
.name = DRV_NAME,
.id_table = mlx4_pci_table,
.probe = mlx4_init_one,
- .remove = __devexit_p(mlx4_remove_one)
+ .remove = mlx4_remove_one,
};
static int __init mlx4_verify_params(void)
^ permalink raw reply related
* Re: Diagnostic Monitoring Interface Monitoring (DOM) PATCH 0/5 for net-next-2.6
From: Jeff Kirsher @ 2009-11-25 9:19 UTC (permalink / raw)
To: Robert Olsson; +Cc: David Miller, netdev
In-Reply-To: <9929d2390911250018o777405ddk257605e7d0b16d17@mail.gmail.com>
On Wed, Nov 25, 2009 at 00:18, Jeff Kirsher <jeffrey.t.kirsher@intel.com> wrote:
> On Mon, Nov 23, 2009 at 14:45, Robert Olsson <robert@herjulf.net> wrote:
>>
>> Here are basic support to bring Diagnostic Monitoring Interface Monitoring (DOM)
>> to Linux this is more or less mandatory when building optical networks.
>>
>> Optical modules as SFP, SFP+, XFP, GBIC etc holds transceiver and link diagnostic
>> data needed to monitor and troubleshoot optical links, Talks to networks cards
>> via the I2C-bus (DOM lives in memory page 0xA2).
>>
>> In essential:
>>
>> Usage example: ethtool -D eth5
>>
>> Ext-Calbr: Avr RX-Power: Alarm & Warn: RX_LOS: Wavelength: 1310 nm
>> Alarms, warnings in beginning of line, Ie. AH = Alarm High, WL == Warn Low etc
>> Temp: 35.9 C Thresh: Lo: -12.0/-8.0 Hi: 103.0/110.0 C
>> Vcc: 3.33 V Thresh: Lo: 3.0/3.0 Hi: 3.7/4.0 V
>> Tx-Bias: 13.4 mA Thresh: Lo: 2.0/4.0 Hi: 70.0/84.0 mA
>> ALWL TX-pwr: -5.9 dBm ( 0.26 mW) Thresh: Lo: -4.0/-2.0 Hi: 7.0/8.2 dBm
>> AHWH RX-pwr: -5.0 dBm ( 0.31 mW) Thresh: Lo: -35.2/-28.0 Hi: -8.2/-6.0 dBm
>>
>> Read more in Documentation/networking/dom.txt
>>
>> It's tested with the igb driver, there is also a patch for the ixgbe driver but I
>> haven't any SFP+ with DOM support yet.
>>
>>
>> There are room for improvements an clean-ups.
>>
>> Cheers
>> --ro
>>
>
> Robert, to help get more eyes on this I have added it to my tree for
> internal testing and review.
>
FYI- This patch series is riddled with trailing whitespace, when I
imported that patches into my tree, I cleaned up all the whitespace
errors. After some internal testing and review, I can re-post the
entire series which has been cleaned up.
--
Cheers,
Jeff
^ permalink raw reply
* Re: [PATCH 10/38] don't wrap mlx4_remove_one in __devexit_p
From: Franco Fichtner @ 2009-11-25 9:19 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: linux-kernel, akpm, Roland Dreier, Yevgeny Petrilin,
Yang Hongyang, Jack Morgenstein, Eli Cohen, netdev
In-Reply-To: <1259096853-18909-10-git-send-email-u.kleine-koenig@pengutronix.de>
Uwe Kleine-König wrote:
> diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
> index 291a505..a581860 100644
> --- a/drivers/net/mlx4/main.c
> +++ b/drivers/net/mlx4/main.c
> @@ -1293,7 +1293,7 @@ static struct pci_driver mlx4_driver = {
> .name = DRV_NAME,
> .id_table = mlx4_pci_table,
> .probe = mlx4_init_one,
> - .remove = __devexit_p(mlx4_remove_one)
> + .remove = mlx4_remove_one
>
You may want to add the trailing comma while you're at it...
> };
>
> static int __init mlx4_verify_params(void)
>
f
^ permalink raw reply
* Re: [PATCH 1/1] Defer skb allocation for both mergeable buffers and big packets in virtio_net
From: Michael S. Tsirkin @ 2009-11-25 9:15 UTC (permalink / raw)
To: Rusty Russell
Cc: Shirley Ma, Eric Dumazet, Avi Kivity, netdev, kvm, linux-kernel,
Hollis Blanchard
In-Reply-To: <200911251042.06368.rusty@rustcorp.com.au>
On Wed, Nov 25, 2009 at 10:42:06AM +1030, Rusty Russell wrote:
> On Tue, 24 Nov 2009 10:07:54 pm Michael S. Tsirkin wrote:
> > On Tue, Nov 24, 2009 at 08:54:23AM +1030, Rusty Russell wrote:
> > > On Tue, 24 Nov 2009 02:37:01 am Shirley Ma wrote:
> > > > > > + skb = (struct sk_buff *)buf;
> > > > > This cast is unnecessary, but a comment would be nice:
> > > >
> > > > Without this cast there is a compile warning.
> > >
> > > Hi Shirley,
> > >
> > > Looks like buf is a void *, so no cast should be necessary. But I could
> > > be reading the patch wrong.
> > >
> > > > > However, I question whether making it 16 byte is the right thing: the
> > > > > ethernet header is 14 bytes long, so don't we want 8 bytes of padding?
> > > >
> > > > Because in QEMU it requires 10 bytes header in a separately, so one page
> > > > is used to share between virtio_net_hdr header which is 10 bytes head
> > > > and rest of data. So I put 6 bytes offset here between two buffers. I
> > > > didn't look at the reason why a seperate buf is used for virtio_net_hdr
> > > > in QEMU.
> > >
> > > It's a qemu bug. It insists the header be an element in the scatterlist by
> > > itself. Unfortunately we have to accommodate it.
> >
> > We do? Let's just fix this?
> > All we have to do is replace memcpy with proper iovec walk, correct?
> > Something like the followng (untested) patch? It's probably not too
> > late to put this in the next qemu release...
>
> You might want to implement a more generic helper which does:
>
> /* Return pointer into iovec if we can, otherwise copy into buf */
> void *pull_iovec(struct iovec *iov, int iovcnt, void *buf, size_t len)
> {
> unsigned int i;
> void *p;
>
> if (likely(iov_cnt && iov[0].iov_len >= len)) {
> /* Nice contiguous chunk. */
> void *p = iov[0].iov_base;
> iov[i].iov_base += len;
> iov[i].iov_len -= len;
> return p;
> }
>
> p = buf;
> for (i = 0; i < iov_cnt; i++) {
> size_t this_len = min(len, iov[i].iov_len);
> memcpy(p, iov[i].iov_base, this_len);
> len -= this_len;
> iov[i].iov_base += len;
> iov[i].iov_len -= len;
> if (len == 0)
> return buf;
> }
> /* BTW, we screwed your iovec. */
> return NULL;
> }
>
> Then use it in all the virtio drivers...
Hmm, is it really worth it to save a header copy if it's linear? We are
going to access it anyway, and it fits into one cacheline nicely. On
the other hand we have more code making life harder for compiler and
processor.
> Thanks!
> Rusty.
^ permalink raw reply
* Re: [tproxy] [HELP] Tproxy server Can't receive any client packet
From: KOVACS Krisztian @ 2009-11-25 8:30 UTC (permalink / raw)
To: 박제호
Cc: tproxy, netfilter-announce, netfilter, netdev, rnd, dylee
In-Reply-To: <d5cf4b4f0911222251u1589c66ar78810d5b9d87cb5e@mail.gmail.com>
Hi,
On Mon, 2009-11-23 at 15:51 +0900, 박제호 wrote:
> i have a problem in my transparent proxy test,
> i recently made up the testbed as below to run the tproxy patched
> apache proxy [mod_proxy],
> and i applied all iptables and routing rules with referencing the
> readme file [http://www.balabit.com/downloads/files/tproxy/README.txt,
> http://www.mjmwired.net/kernel/Documentation/networking/tproxy.txt]
> the proxy server listening the port 3128 and i checked there were no problem.
> but when the client tried to connect the web server,
> the packets reached to the box and i found the usage counts of filter
> rules in the mangle table incresed
> but my tproxy server could not receive any corresponding packet from the socket
>
> I want to know why my proxy server can't receive any packet through the socket,
> Do i need some more DNAT rules ?
Would you mind testing the setup with an unpatched upstream kernel, that
has tproxy built-in? (2.6.31, for example)
Also, please download the latest iptables from netfilter.org and try
using that. (No need for patching, tproxy support is in upstream.)
That would help a lot in identifying the source of the issue. Thanks in
advance.
Cheers,
Krisztian
^ permalink raw reply
* Re: [tproxy] [HELP] Tproxy server Can't receive any client packet
From: linuxpark @ 2009-11-25 8:54 UTC (permalink / raw)
To: KOVACS Krisztian
Cc: tproxy, netfilter-announce, netfilter, netdev, rnd, dylee
In-Reply-To: <1259137840.9191.7.camel@nienna.balabit>
Thanks your reply ~
i succeed in tproxy function of the apache server
--
kernel 2.6.31 (vannilla kernel)
iptables 1.4.3 (no patched)
apache 2.2.9 + patches (main socket routine of the apache, mod_tproxy.c)
--
KOVACS Krisztian 쓴 글:
> Hi,
>
> On Mon, 2009-11-23 at 15:51 +0900, 박제호 wrote:
>
>> i have a problem in my transparent proxy test,
>> i recently made up the testbed as below to run the tproxy patched
>> apache proxy [mod_proxy],
>> and i applied all iptables and routing rules with referencing the
>> readme file [http://www.balabit.com/downloads/files/tproxy/README.txt,
>> http://www.mjmwired.net/kernel/Documentation/networking/tproxy.txt]
>> the proxy server listening the port 3128 and i checked there were no problem.
>> but when the client tried to connect the web server,
>> the packets reached to the box and i found the usage counts of filter
>> rules in the mangle table incresed
>> but my tproxy server could not receive any corresponding packet from the socket
>>
>> I want to know why my proxy server can't receive any packet through the socket,
>> Do i need some more DNAT rules ?
>>
>
> Would you mind testing the setup with an unpatched upstream kernel, that
> has tproxy built-in? (2.6.31, for example)
>
> Also, please download the latest iptables from netfilter.org and try
> using that. (No need for patching, tproxy support is in upstream.)
>
> That would help a lot in identifying the source of the issue. Thanks in
> advance.
>
> Cheers,
> Krisztian
>
>
>
^ permalink raw reply
* Re: [patch]USB autosuspend for cdc-ether
From: Oliver Neukum @ 2009-11-25 8:39 UTC (permalink / raw)
To: Steve.Glendinning-sdUf+H5yV5I
Cc: David S. Miller, David Brownell, linux-usb-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz, Torgny Johansson
In-Reply-To: <OFCBC12A15.7006C53A-ON80257678.00524557-80257678.005373C0-sdUf+H5yV5I@public.gmane.org>
Am Dienstag, 24. November 2009 16:11:28 schrieb Steve.Glendinning-sdUf+H5yV5I@public.gmane.org:
> Interesting patch, I'm going to try and add support for this
> to smsc95xx.
>
> A few things I noticed:
>
Hi,
this version should fix what you mentioned.
Regards
Oliver
Signed-off-by: Oliver Neukum <oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org>
--
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 21e1ba1..ed55024 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -411,6 +411,12 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
return 0;
}
+static int cdc_manage_power(struct usbnet *dev, int on)
+{
+ dev->intf->needs_remote_wakeup = on;
+ return 0;
+}
+
static const struct driver_info cdc_info = {
.description = "CDC Ethernet Device",
.flags = FLAG_ETHER,
@@ -418,6 +424,7 @@ static const struct driver_info cdc_info = {
.bind = cdc_bind,
.unbind = usbnet_cdc_unbind,
.status = cdc_status,
+ .manage_power = cdc_manage_power,
};
/*-------------------------------------------------------------------------*/
@@ -610,6 +617,7 @@ static struct usb_driver cdc_driver = {
.disconnect = usbnet_disconnect,
.suspend = usbnet_suspend,
.resume = usbnet_resume,
+ .supports_autosuspend = 1,
};
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index ca5ca5a..50a48e2 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -353,7 +353,8 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
if (netif_running (dev->net)
&& netif_device_present (dev->net)
- && !test_bit (EVENT_RX_HALT, &dev->flags)) {
+ && !test_bit (EVENT_RX_HALT, &dev->flags)
+ && !test_bit (EVENT_DEV_ASLEEP, &dev->flags)) {
switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) {
case -EPIPE:
usbnet_defer_kevent (dev, EVENT_RX_HALT);
@@ -611,15 +612,39 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
/*-------------------------------------------------------------------------*/
// precondition: never called in_interrupt
+static void usbnet_terminate_urbs(struct usbnet *dev)
+{
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup);
+ DECLARE_WAITQUEUE (wait, current);
+ int temp;
+
+ /* ensure there are no more active urbs */
+ add_wait_queue(&unlink_wakeup, &wait);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ dev->wait = &unlink_wakeup;
+ temp = unlink_urbs(dev, &dev->txq) +
+ unlink_urbs(dev, &dev->rxq);
+
+ /* maybe wait for deletions to finish. */
+ while (!skb_queue_empty(&dev->rxq)
+ && !skb_queue_empty(&dev->txq)
+ && !skb_queue_empty(&dev->done)) {
+ schedule_timeout(UNLINK_TIMEOUT_MS);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (netif_msg_ifdown(dev))
+ devdbg(dev, "waited for %d urb completions",
+ temp);
+ }
+ set_current_state(TASK_RUNNING);
+ dev->wait = NULL;
+ remove_wait_queue(&unlink_wakeup, &wait);
+}
int usbnet_stop (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
struct driver_info *info = dev->driver_info;
- int temp;
int retval;
- DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup);
- DECLARE_WAITQUEUE (wait, current);
netif_stop_queue (net);
@@ -641,25 +666,8 @@ int usbnet_stop (struct net_device *net)
info->description);
}
- if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) {
- /* ensure there are no more active urbs */
- add_wait_queue(&unlink_wakeup, &wait);
- dev->wait = &unlink_wakeup;
- temp = unlink_urbs(dev, &dev->txq) +
- unlink_urbs(dev, &dev->rxq);
-
- /* maybe wait for deletions to finish. */
- while (!skb_queue_empty(&dev->rxq)
- && !skb_queue_empty(&dev->txq)
- && !skb_queue_empty(&dev->done)) {
- msleep(UNLINK_TIMEOUT_MS);
- if (netif_msg_ifdown(dev))
- devdbg(dev, "waited for %d urb completions",
- temp);
- }
- dev->wait = NULL;
- remove_wait_queue(&unlink_wakeup, &wait);
- }
+ if (!(info->flags & FLAG_AVOID_UNLINK_URBS))
+ usbnet_terminate_urbs(dev);
usb_kill_urb(dev->interrupt);
@@ -672,7 +680,10 @@ int usbnet_stop (struct net_device *net)
dev->flags = 0;
del_timer_sync (&dev->delay);
tasklet_kill (&dev->bh);
- usb_autopm_put_interface(dev->intf);
+ if (info->manage_power)
+ info->manage_power(dev, 0);
+ else
+ usb_autopm_put_interface(dev->intf);
return 0;
}
@@ -753,6 +764,12 @@ int usbnet_open (struct net_device *net)
// delay posting reads until we're fully open
tasklet_schedule (&dev->bh);
+ if (info->manage_power) {
+ retval = info->manage_power(dev, 1);
+ if (retval < 0)
+ goto done;
+ usb_autopm_put_interface(dev->intf);
+ }
return retval;
done:
usb_autopm_put_interface(dev->intf);
@@ -881,11 +898,16 @@ kevent (struct work_struct *work)
/* usb_clear_halt() needs a thread context */
if (test_bit (EVENT_TX_HALT, &dev->flags)) {
unlink_urbs (dev, &dev->txq);
+ status = usb_autopm_get_interface(dev->intf);
+ if (status < 0)
+ goto fail_pipe;
status = usb_clear_halt (dev->udev, dev->out);
+ usb_autopm_put_interface(dev->intf);
if (status < 0
&& status != -EPIPE
&& status != -ESHUTDOWN) {
if (netif_msg_tx_err (dev))
+fail_pipe:
deverr (dev, "can't clear tx halt, status %d",
status);
} else {
@@ -896,11 +918,16 @@ kevent (struct work_struct *work)
}
if (test_bit (EVENT_RX_HALT, &dev->flags)) {
unlink_urbs (dev, &dev->rxq);
+ status = usb_autopm_get_interface(dev->intf);
+ if (status < 0)
+ goto fail_halt;
status = usb_clear_halt (dev->udev, dev->in);
+ usb_autopm_put_interface(dev->intf);
if (status < 0
&& status != -EPIPE
&& status != -ESHUTDOWN) {
if (netif_msg_rx_err (dev))
+fail_halt:
deverr (dev, "can't clear rx halt, status %d",
status);
} else {
@@ -919,7 +946,12 @@ kevent (struct work_struct *work)
clear_bit (EVENT_RX_MEMORY, &dev->flags);
if (urb != NULL) {
clear_bit (EVENT_RX_MEMORY, &dev->flags);
+ status = usb_autopm_get_interface(dev->intf);
+ if (status < 0)
+ goto fail_lowmem;
rx_submit (dev, urb, GFP_KERNEL);
+ usb_autopm_put_interface(dev->intf);
+fail_lowmem:
tasklet_schedule (&dev->bh);
}
}
@@ -929,11 +961,18 @@ kevent (struct work_struct *work)
int retval = 0;
clear_bit (EVENT_LINK_RESET, &dev->flags);
+ status = usb_autopm_get_interface(dev->intf);
+ if (status < 0)
+ goto skip_reset;
if(info->link_reset && (retval = info->link_reset(dev)) < 0) {
+ usb_autopm_put_interface(dev->intf);
+skip_reset:
devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s",
retval,
dev->udev->bus->bus_name, dev->udev->devpath,
info->description);
+ } else {
+ usb_autopm_put_interface(dev->intf);
}
}
@@ -971,6 +1010,7 @@ static void tx_complete (struct urb *urb)
case -EPROTO:
case -ETIME:
case -EILSEQ:
+ usb_mark_last_busy(dev->udev);
if (!timer_pending (&dev->delay)) {
mod_timer (&dev->delay,
jiffies + THROTTLE_JIFFIES);
@@ -987,6 +1027,7 @@ static void tx_complete (struct urb *urb)
}
}
+ usb_autopm_put_interface_async(dev->intf);
urb->dev = NULL;
entry->state = tx_done;
defer_bh(dev, skb, &dev->txq);
@@ -1058,13 +1099,33 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
}
spin_lock_irqsave (&dev->txq.lock, flags);
+ retval = usb_autopm_get_interface_async(dev->intf);
+ if (retval < 0) {
+ spin_unlock_irqrestore (&dev->txq.lock, flags);
+ goto drop;
+ }
+
+#ifdef CONFIG_PM
+ /* if this triggers the device is still a sleep */
+ if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) {
+ /* transmission will be done in resume */
+ usb_anchor_urb(urb, &dev->deferred);
+ /* no use to process more packets */
+ netif_stop_queue(net);
+ spin_unlock_irqrestore(&dev->txq.lock, flags);
+ devdbg(dev, "Delaying transmission for resumption");
+ goto deferred;
+ }
+#endif
switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) {
case -EPIPE:
netif_stop_queue (net);
usbnet_defer_kevent (dev, EVENT_TX_HALT);
+ usb_autopm_put_interface_async(dev->intf);
break;
default:
+ usb_autopm_put_interface_async(dev->intf);
if (netif_msg_tx_err (dev))
devdbg (dev, "tx: submit urb err %d", retval);
break;
@@ -1088,6 +1149,7 @@ drop:
devdbg (dev, "> tx, len %d, type 0x%x",
length, skb->protocol);
}
+deferred:
return NETDEV_TX_OK;
}
EXPORT_SYMBOL_GPL(usbnet_start_xmit);
@@ -1255,6 +1317,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
dev->bh.func = usbnet_bh;
dev->bh.data = (unsigned long) dev;
INIT_WORK (&dev->kevent, kevent);
+ init_usb_anchor(&dev->deferred);
dev->delay.function = usbnet_bh;
dev->delay.data = (unsigned long) dev;
init_timer (&dev->delay);
@@ -1363,13 +1426,23 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
struct usbnet *dev = usb_get_intfdata(intf);
if (!dev->suspend_count++) {
+ spin_lock_irq(&dev->txq.lock);
+ /* don't autosuspend while transmitting */
+ if (dev->txq.qlen && (message.event & PM_EVENT_AUTO)) {
+ spin_unlock_irq(&dev->txq.lock);
+ return -EBUSY;
+ } else {
+ set_bit(EVENT_DEV_ASLEEP, &dev->flags);
+ spin_unlock_irq(&dev->txq.lock);
+ }
/*
* accelerate emptying of the rx and queues, to avoid
* having everything error out.
*/
netif_device_detach (dev->net);
- (void) unlink_urbs (dev, &dev->rxq);
- (void) unlink_urbs (dev, &dev->txq);
+ usbnet_terminate_urbs(dev);
+ usb_kill_urb(dev->interrupt);
+
/*
* reattach so runtime management can use and
* wake the device
@@ -1383,10 +1456,34 @@ EXPORT_SYMBOL_GPL(usbnet_suspend);
int usbnet_resume (struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
+ struct sk_buff *skb;
+ struct urb *res;
+ int retval;
+
+ if (!--dev->suspend_count) {
+ spin_lock_irq(&dev->txq.lock);
+ while ((res = usb_get_from_anchor(&dev->deferred))) {
+
+ printk(KERN_INFO"Called %s with delayed data\n", __func__);
+ skb = (struct sk_buff *)res->context;
+ retval = usb_submit_urb(res, GFP_ATOMIC);
+ if (retval < 0) {
+ dev_kfree_skb_any(skb);
+ usb_free_urb(res);
+ usb_autopm_put_interface_async(dev->intf);
+ } else {
+ dev->net->trans_start = jiffies;
+ __skb_queue_tail (&dev->txq, skb);
+ }
+ }
- if (!--dev->suspend_count)
+ smp_mb();
+ clear_bit(EVENT_DEV_ASLEEP, &dev->flags);
+ spin_unlock_irq(&dev->txq.lock);
+ if (!(dev->txq.qlen >= TX_QLEN(dev)))
+ netif_start_queue(dev->net);
tasklet_schedule (&dev->bh);
-
+ }
return 0;
}
EXPORT_SYMBOL_GPL(usbnet_resume);
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index f814730..e75ba0e 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -55,6 +55,7 @@ struct usbnet {
struct sk_buff_head done;
struct sk_buff_head rxq_pause;
struct urb *interrupt;
+ struct usb_anchor deferred;
struct tasklet_struct bh;
struct work_struct kevent;
@@ -65,6 +66,8 @@ struct usbnet {
# define EVENT_STS_SPLIT 3
# define EVENT_LINK_RESET 4
# define EVENT_RX_PAUSED 5
+# define EVENT_DEV_WAKING 6
+# define EVENT_DEV_ASLEEP 7
};
static inline struct usb_driver *driver_of(struct usb_interface *intf)
@@ -107,6 +110,9 @@ struct driver_info {
/* see if peer is connected ... can sleep */
int (*check_connect)(struct usbnet *);
+ /* (dis)activate runtime power management */
+ int (*manage_power)(struct usbnet *, int);
+
/* for status polling */
void (*status)(struct usbnet *, struct urb *);
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 5/7] via-velocity: Re-enable transmit scatter-gather support
From: Simon Kagstrom @ 2009-11-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, davej, shemminger, romieu
In-Reply-To: <20091123153133.2237b04c@marrow.netinsight.se>
The velocity hardware can handle up to 7 memory segments. This can be
turned on and off via ethtool. The support was removed in commit
83c98a8cd04dd0f848574370594886ba3bf56750
but is re-enabled and cleaned up here. It's off by default.
Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net>
---
ChangeLog:
* (David Miller) return NETDEV_TX_OK from the velocity_xmit
function. I'm still a bit unsure on what to actually return in
these cases (they are error cases), but other drivers seem to
return NETDEV_TX_OK, so that's what I went with.
drivers/net/via-velocity.c | 88 +++++++++++++++++++++++++++++---------------
1 files changed, 58 insertions(+), 30 deletions(-)
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 06a6d80..2ad25a9 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -9,7 +9,6 @@
*
* TODO
* rx_copybreak/alignment
- * Scatter gather
* More testing
*
* The changes are (c) Copyright 2004, Red Hat Inc. <alan@lxorguk.ukuu.org.uk>
@@ -1656,12 +1655,10 @@ out:
*/
static int velocity_init_td_ring(struct velocity_info *vptr)
{
- dma_addr_t curr;
int j;
/* Init the TD ring entries */
for (j = 0; j < vptr->tx.numq; j++) {
- curr = vptr->tx.pool_dma[j];
vptr->tx.infos[j] = kcalloc(vptr->options.numtx,
sizeof(struct velocity_td_info),
@@ -1727,21 +1724,27 @@ err_free_dma_rings_0:
* Release an transmit buffer. If the buffer was preallocated then
* recycle it, if not then unmap the buffer.
*/
-static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
+static void velocity_free_tx_buf(struct velocity_info *vptr,
+ struct velocity_td_info *tdinfo, struct tx_desc *td)
{
struct sk_buff *skb = tdinfo->skb;
- int i;
- int pktlen;
/*
* Don't unmap the pre-allocated tx_bufs
*/
if (tdinfo->skb_dma) {
+ int i;
- pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
for (i = 0; i < tdinfo->nskb_dma; i++) {
- pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], pktlen, PCI_DMA_TODEVICE);
- tdinfo->skb_dma[i] = 0;
+ size_t pktlen = max_t(size_t, skb->len, ETH_ZLEN);
+
+ /* For scatter-gather */
+ if (skb_shinfo(skb)->nr_frags > 0)
+ pktlen = max_t(size_t, pktlen,
+ td->td_buf[i].size & ~TD_QUEUE);
+
+ pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i],
+ le16_to_cpu(pktlen), PCI_DMA_TODEVICE);
}
}
dev_kfree_skb_irq(skb);
@@ -1943,7 +1946,7 @@ static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
stats->tx_packets++;
stats->tx_bytes += tdinfo->skb->len;
}
- velocity_free_tx_buf(vptr, tdinfo);
+ velocity_free_tx_buf(vptr, tdinfo, td);
vptr->tx.used[qnum]--;
}
vptr->tx.tail[qnum] = idx;
@@ -2543,14 +2546,27 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
struct velocity_td_info *tdinfo;
unsigned long flags;
int pktlen;
- __le16 len;
- int index;
+ int index, prev;
+ int i = 0;
if (skb_padto(skb, ETH_ZLEN))
goto out;
- pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
- len = cpu_to_le16(pktlen);
+ /* The hardware can handle at most 7 memory segments, so merge
+ * the skb if there are more */
+ if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ /* If it's still above 6 we can't do anything */
+ if (skb_shinfo(skb)->nr_frags > 6) {
+ dev_err(&vptr->pdev->dev,
+ "via-velocity: more than 6 frags, can't send.\n");
+ return NETDEV_TX_OK;
+ }
+ pktlen = skb_shinfo(skb)->nr_frags == 0 ?
+ max_t(unsigned int, skb->len, ETH_ZLEN) :
+ skb_headlen(skb);
spin_lock_irqsave(&vptr->lock, flags);
@@ -2567,11 +2583,24 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
*/
tdinfo->skb = skb;
tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
- td_ptr->tdesc0.len = len;
+ td_ptr->tdesc0.len = cpu_to_le16(pktlen);
td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
td_ptr->td_buf[0].pa_high = 0;
- td_ptr->td_buf[0].size = len;
- tdinfo->nskb_dma = 1;
+ td_ptr->td_buf[0].size = cpu_to_le16(pktlen);
+
+ /* Handle fragments */
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ tdinfo->skb_dma[i + 1] = pci_map_page(vptr->pdev, frag->page,
+ frag->page_offset, frag->size,
+ PCI_DMA_TODEVICE);
+
+ td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
+ td_ptr->td_buf[i + 1].pa_high = 0;
+ td_ptr->td_buf[i + 1].size = cpu_to_le16(frag->size);
+ }
+ tdinfo->nskb_dma = i + 1;
td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16;
@@ -2592,23 +2621,21 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
td_ptr->tdesc1.TCR |= (TCR0_UDPCK);
td_ptr->tdesc1.TCR |= TCR0_IPCK;
}
- {
- int prev = index - 1;
+ prev = index - 1;
+ if (prev < 0)
+ prev = vptr->options.numtx - 1;
+ td_ptr->tdesc0.len |= OWNED_BY_NIC;
+ vptr->tx.used[qnum]++;
+ vptr->tx.curr[qnum] = (index + 1) % vptr->options.numtx;
- if (prev < 0)
- prev = vptr->options.numtx - 1;
- td_ptr->tdesc0.len |= OWNED_BY_NIC;
- vptr->tx.used[qnum]++;
- vptr->tx.curr[qnum] = (index + 1) % vptr->options.numtx;
+ if (AVAIL_TD(vptr, qnum) < 1)
+ netif_stop_queue(dev);
- if (AVAIL_TD(vptr, qnum) < 1)
- netif_stop_queue(dev);
+ td_ptr = &(vptr->tx.rings[qnum][prev]);
+ td_ptr->td_buf[0].size |= TD_QUEUE;
+ mac_tx_queue_wake(vptr->mac_regs, qnum);
- td_ptr = &(vptr->tx.rings[qnum][prev]);
- td_ptr->td_buf[0].size |= TD_QUEUE;
- mac_tx_queue_wake(vptr->mac_regs, qnum);
- }
dev->trans_start = jiffies;
spin_unlock_irqrestore(&vptr->lock, flags);
out:
@@ -3398,6 +3425,7 @@ static const struct ethtool_ops velocity_ethtool_ops = {
.set_wol = velocity_ethtool_set_wol,
.get_msglevel = velocity_get_msglevel,
.set_msglevel = velocity_set_msglevel,
+ .set_sg = ethtool_op_set_sg,
.get_link = velocity_get_link,
.get_coalesce = velocity_get_coalesce,
.set_coalesce = velocity_set_coalesce,
--
1.6.0.4
^ permalink raw reply related
* Re: Diagnostic Monitoring Interface Monitoring (DOM) PATCH 0/5 for net-next-2.6
From: Jeff Kirsher @ 2009-11-25 8:18 UTC (permalink / raw)
To: Robert Olsson; +Cc: David Miller, netdev
In-Reply-To: <19211.4244.135603.458550@gargle.gargle.HOWL>
On Mon, Nov 23, 2009 at 14:45, Robert Olsson <robert@herjulf.net> wrote:
>
> Here are basic support to bring Diagnostic Monitoring Interface Monitoring (DOM)
> to Linux this is more or less mandatory when building optical networks.
>
> Optical modules as SFP, SFP+, XFP, GBIC etc holds transceiver and link diagnostic
> data needed to monitor and troubleshoot optical links, Talks to networks cards
> via the I2C-bus (DOM lives in memory page 0xA2).
>
> In essential:
>
> Usage example: ethtool -D eth5
>
> Ext-Calbr: Avr RX-Power: Alarm & Warn: RX_LOS: Wavelength: 1310 nm
> Alarms, warnings in beginning of line, Ie. AH = Alarm High, WL == Warn Low etc
> Temp: 35.9 C Thresh: Lo: -12.0/-8.0 Hi: 103.0/110.0 C
> Vcc: 3.33 V Thresh: Lo: 3.0/3.0 Hi: 3.7/4.0 V
> Tx-Bias: 13.4 mA Thresh: Lo: 2.0/4.0 Hi: 70.0/84.0 mA
> ALWL TX-pwr: -5.9 dBm ( 0.26 mW) Thresh: Lo: -4.0/-2.0 Hi: 7.0/8.2 dBm
> AHWH RX-pwr: -5.0 dBm ( 0.31 mW) Thresh: Lo: -35.2/-28.0 Hi: -8.2/-6.0 dBm
>
> Read more in Documentation/networking/dom.txt
>
> It's tested with the igb driver, there is also a patch for the ixgbe driver but I
> haven't any SFP+ with DOM support yet.
>
>
> There are room for improvements an clean-ups.
>
> Cheers
> --ro
>
Robert, to help get more eyes on this I have added it to my tree for
internal testing and review.
--
Cheers,
Jeff
^ permalink raw reply
* Re: linux-next: manual merge of the net tree with the net-current tree
From: Jeff Kirsher @ 2009-11-25 7:52 UTC (permalink / raw)
To: Stephen Rothwell
Cc: David Miller, netdev, linux-next, linux-kernel, Bruce Allan
In-Reply-To: <20091124141122.63e81c55.sfr@canb.auug.org.au>
On Mon, Nov 23, 2009 at 19:11, Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> Hi all,
>
> Today's linux-next merge of the net tree got a conflict in
> drivers/net/e1000e/ich8lan.c between commit
> 818f33313caab9be2a10458500dbed4a88c1b334 ("e1000e: do not initiate
> autonegotiation during OEM configuration") from the net-current tree and
> commit 94d8186a693284344ee5cb9734086c7a2370241a ("e1000e: cleanup ops
> function pointers") from the net tree.
>
> Just context changes. I fixed it up (see below) and can carry the fix for
> a while.
> --
> Cheers,
> Stephen Rothwell sfr@canb.auug.org.au
>
I am checking your merge changes to e1000e now, sorry for the delayed response.
--
Cheers,
Jeff
^ permalink raw reply
* [PATCH] net: convert /proc/net/rt_acct to seq_file
From: Alexey Dobriyan @ 2009-11-25 7:45 UTC (permalink / raw)
To: davem; +Cc: netdev
Rewrite statistics accumulation to be in terms of structure fields,
not raw u32 additions. Keep them in same order, though.
This is the last user of create_proc_read_entry() in net/,
please NAK all new ones as well as all new ->write_proc, ->read_proc and
create_proc_entry() users. Cc me if there are problems. :-)
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
net/ipv4/route.c | 68 ++++++++++++++++++++++++++-----------------------------
1 file changed, 33 insertions(+), 35 deletions(-)
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -513,43 +513,42 @@ static const struct file_operations rt_cpu_seq_fops = {
};
#ifdef CONFIG_NET_CLS_ROUTE
-static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data)
-{
- unsigned int i;
-
- if ((offset & 3) || (length & 3))
- return -EIO;
-
- if (offset >= sizeof(struct ip_rt_acct) * 256) {
- *eof = 1;
- return 0;
- }
-
- if (offset + length >= sizeof(struct ip_rt_acct) * 256) {
- length = sizeof(struct ip_rt_acct) * 256 - offset;
- *eof = 1;
+static int rt_acct_proc_show(struct seq_file *m, void *v)
+{
+ struct ip_rt_acct *dst, *src;
+ unsigned int i, j;
+
+ dst = kcalloc(256, sizeof(struct ip_rt_acct), GFP_KERNEL);
+ if (!dst)
+ return -ENOMEM;
+
+ for_each_possible_cpu(i) {
+ src = (struct ip_rt_acct *)per_cpu_ptr(ip_rt_acct, i);
+ for (j = 0; j < 256; j++) {
+ dst[j].o_bytes += src[j].o_bytes;
+ dst[j].o_packets += src[j].o_packets;
+ dst[j].i_bytes += src[j].i_bytes;
+ dst[j].i_packets += src[j].i_packets;
+ }
}
- offset /= sizeof(u32);
-
- if (length > 0) {
- u32 *dst = (u32 *) buffer;
-
- *start = buffer;
- memset(dst, 0, length);
-
- for_each_possible_cpu(i) {
- unsigned int j;
- u32 *src;
+ seq_write(m, dst, 256 * sizeof(struct ip_rt_acct));
+ kfree(dst);
+ return 0;
+}
- src = ((u32 *) per_cpu_ptr(ip_rt_acct, i)) + offset;
- for (j = 0; j < length/4; j++)
- dst[j] += src[j];
- }
- }
- return length;
+static int rt_acct_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rt_acct_proc_show, NULL);
}
+
+static const struct file_operations rt_acct_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = rt_acct_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
#endif
static int __net_init ip_rt_do_proc_init(struct net *net)
@@ -567,8 +566,7 @@ static int __net_init ip_rt_do_proc_init(struct net *net)
goto err2;
#ifdef CONFIG_NET_CLS_ROUTE
- pde = create_proc_read_entry("rt_acct", 0, net->proc_net,
- ip_rt_acct_read, NULL);
+ pde = proc_create("rt_acct", 0, net->proc_net, &rt_acct_proc_fops);
if (!pde)
goto err3;
#endif
^ permalink raw reply
* Re: [rfc 1/3 v2] [E1000-devel] [rfc 1/4] igb: Add igb_cleanup_vf()
From: Jeff Kirsher @ 2009-11-25 7:40 UTC (permalink / raw)
To: Simon Horman; +Cc: e1000-devel, netdev, Arnd Bergmann, Alexander Duyck
In-Reply-To: <20091125063530.796967189@vergenet.net>
On Tue, Nov 24, 2009 at 22:32, Simon Horman <horms@verge.net.au> wrote:
> Move virtual finction cleanup code into igb_cleanup_vf() and for the sake
> of symmetry rename igb_probe_vfs() as igb_init_vf().
>
> Although these functions aren't entirely symmetrical it should aid
> maintenance by making the relationship between initialisation and cleanup
> more obvious.
>
> Note that there appears to be no way for adapter->vfs_allocated_count to be
> non-zero for the case where CONFIG_PCI_IOV is not set, so reseting this
> value was moved to inside the relvant #ifdef.
>
> Signed-off-by: Simon Horman <horms@verge.net.au>
>
> ---
> Thu, 05 Nov 2009 11:58:48 +1100
> * Initial post
>
> Wed, 25 Nov 2009 15:43:45 +1100
> * Actually remove adapter->vfs_allocated_count = 0 from outside of
> igb_cleanup_vf()
> * Up-port to current net-next
Thanks Simon and congrats on the new addition! I have added this
three patch series to my tree for review and testing.
--
Cheers,
Jeff
^ permalink raw reply
* Re: [PATCH v2 0/7] via-velocity performance fixes
From: Simon Kagstrom @ 2009-11-25 7:39 UTC (permalink / raw)
To: David Miller; +Cc: netdev, davej, shemminger, romieu
In-Reply-To: <20091124.121339.226248026.davem@davemloft.net>
On Tue, 24 Nov 2009 12:13:39 -0800 (PST)
David Miller <davem@davemloft.net> wrote:
> Simon I'm still waiting for you to fix the transmit function return
> value problems I pointed out in patch #5.
>
> Please get to this so I can apply your patches.
Sorry, I missed that comment. I only subscribed to netdev after having
sent out the patches, so I didn't get that reply. I've looked it up now
(and I'm subscribed now!), so I'll send out a new version.
Thanks,
// Simon
^ permalink raw reply
* Re: [PATCH net-next-2.6] ixgbe: Fix TX stats accounting
From: Jeff Kirsher @ 2009-11-25 7:38 UTC (permalink / raw)
To: Eric Dumazet
Cc: Peter P Waskiewicz Jr, robert@herjulf.net, Jesper Dangaard Brouer,
Linux Netdev List, David S. Miller
In-Reply-To: <4B0BDE3E.2020406@gmail.com>
On Tue, Nov 24, 2009 at 05:23, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Here is an updated version, because ixgbe_get_ethtool_stats()
> needs to call dev_get_stats() or "ethtool -S" wont give
> correct tx_bytes/tx_packets values.
>
> [PATCH net-next-2.6] ixgbe: Fix TX stats accounting
>
> Several cpus can update netdev->stats.tx_bytes & netdev->stats.tx_packets
> in parallel. In this case, TX stats are under estimated and false sharing
> takes place.
>
> After a pktgen session sending exactly 200000000 packets :
> # ifconfig fiber0 | grep TX
> TX packets:198501982 errors:0 dropped:0 overruns:0 carrier:0
>
>
> Multi queue devices should instead use txq->tx_bytes & txq->tx_packets
> in their xmit() method (appropriate txq lock already held by caller, no
> cache line miss), or use appropriate locking.
>
> After patch, same pktgen session gives :
>
> # ifconfig fiber0 | grep TX
> TX packets:200000000 errors:0 dropped:0 overruns:0 carrier:0
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> ---
> drivers/net/ixgbe/ixgbe_ethtool.c | 1 +
> drivers/net/ixgbe/ixgbe_main.c | 20 ++++----------------
> 2 files changed, 5 insertions(+), 16 deletions(-)
>
Thanks Eric. I have added the patch to my tree for testing and review.
--
Cheers,
Jeff
^ permalink raw reply
* [rfc 3/3 v2] [E1000-devel] [rfc 4/4] igb: expose 82576 bandiwidth allocation
From: Simon Horman @ 2009-11-25 6:32 UTC (permalink / raw)
To: e1000-devel, netdev; +Cc: Arnd Bergmann, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091125063213.203372240@vergenet.net>
[-- Attachment #1: igb-expose-82576-bandwidth-allocation-2.patch --]
[-- Type: text/plain, Size: 12266 bytes --]
The 82576 has support for bandwidth allocation to VFs.
Contrary to the documentation in the 82576 datasheet v2.41 this
appears to work as follows:
* The ratio supplied is always proportional to 1Gbit/s,
regardless of if the link speed.
* The ratio supplied is an upper-bound on bandwidth available
to the VF, not a minimun guarantee
This patch exposes bandwidth control to userspace through a simple
per-device (PF) sysfs file, bandwidth_allocation.
* The file contains a whitespace delimited list of values, one per VF.
* The first value corresponds to the first VF and so on.
* Valid values are integers from 0 to 1000
* A value of 0 indicates that bandwidth_allocation is disabled.
* Other values indicate the allocated bandwidth, in 1/1000ths of a gigabit/s
e.g. The following for a PF with 4 VFs allocates ~20Mbits/ to VF 1,
~100Mbit/s to VF 2, and leave the other 2 VFs with no allocation.
echo "20 100 0 0" > /sys/class/net/eth3/device/bandwidth_allocation
This interface is intended to allow testing of the hardware feature.
There are ongoing discussions about how to expose this feature
to user-space in a more generic way.
Signed-off-by: Simon Horman <horms@verge.net.au>
---
Thu, 05 Nov 2009 11:58:51 +1100
* Initial post
Wed, 25 Nov 2009 16:58:23 +1100
* Refresh for changes to proceeding patches in series
* Up-port to latest net-next
Index: net-next-2.6/drivers/net/igb/igb_main.c
===================================================================
--- net-next-2.6.orig/drivers/net/igb/igb_main.c 2009-11-25 17:05:44.000000000 +1100
+++ net-next-2.6/drivers/net/igb/igb_main.c 2009-11-25 17:06:51.000000000 +1100
@@ -47,6 +47,9 @@
#ifdef CONFIG_IGB_DCA
#include <linux/dca.h>
#endif
+#ifdef CONFIG_PCI_IOV
+#include <linux/ctype.h>
+#endif
#include "igb.h"
#define DRV_VERSION "2.1.0-k2"
@@ -157,6 +160,15 @@ static unsigned int max_vfs = 0;
module_param(max_vfs, uint, 0);
MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate "
"per physical function");
+
+static ssize_t igb_set_bandwidth_allocation(struct device *,
+ struct device_attribute *,
+ const char *, size_t);
+static ssize_t igb_show_bandwidth_allocation(struct device *,
+ struct device_attribute *,
+ char *);
+DEVICE_ATTR(bandwidth_allocation, S_IRUGO | S_IWUSR,
+ igb_show_bandwidth_allocation, igb_set_bandwidth_allocation);
#endif /* CONFIG_PCI_IOV */
static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
@@ -1771,6 +1783,19 @@ static void __devinit igb_init_vf(struct
if (pci_enable_sriov(pdev, adapter->vfs_allocated_count))
goto err_free;
+ if (device_create_file(&pdev->dev, &dev_attr_bandwidth_allocation))
+ goto err_sriov;
+
+ adapter->bandwidth_allocation = kcalloc(adapter->vfs_allocated_count,
+ sizeof(unsigned int),
+ GFP_KERNEL);
+ if (!adapter->bandwidth_allocation)
+ goto err_file;
+ memset(adapter->bandwidth_allocation,
+ adapter->vfs_allocated_count * sizeof(unsigned int), 0);
+
+ spin_lock_init(&adapter->bandwidth_allocation_lock);
+
dev_info(&pdev->dev, "%d vfs allocated\n",
adapter->vfs_allocated_count);
for (i = 0; i < adapter->vfs_allocated_count; i++) {
@@ -1779,6 +1804,10 @@ static void __devinit igb_init_vf(struct
}
return;
+err_file:
+ device_remove_file(&pdev->dev, &dev_attr_bandwidth_allocation);
+err_sriov:
+ pci_disable_sriov(pdev);
err_free:
kfree(adapter->vf_data);
err_zero:
@@ -1903,6 +1932,7 @@ static void igb_init_hw_timer(struct igb
static void igb_cleanup_vf(struct igb_adapter * adapter)
{
#ifdef CONFIG_PCI_IOV
+ struct pci_dev *pdev = adapter->pdev;
struct e1000_hw *hw = &adapter->hw;
if (!adapter->vf_data)
@@ -1919,6 +1949,9 @@ static void igb_cleanup_vf(struct igb_ad
wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
msleep(100);
dev_info(&adapter->pdev->dev, "IOV Disabled\n");
+
+ device_remove_file(&pdev->dev, &dev_attr_bandwidth_allocation);
+ kfree(adapter->bandwidth_allocation);
#endif
}
@@ -2227,6 +2260,123 @@ void igb_configure_tx_ring(struct igb_ad
wr32(E1000_TXDCTL(reg_idx), txdctl);
}
+#ifdef CONFIG_PCI_IOV
+static void igb_disable_bandwidth_allocation_vf(struct e1000_hw *hw, int vf)
+{
+ wr32(E1000_VMBASEL, vf);
+ wr32(E1000_VMBAC, 0);
+}
+
+static void igb_disable_bandwidth_allocation(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ int i;
+
+ for (i = 0; i < adapter->vfs_allocated_count; i++)
+ igb_disable_bandwidth_allocation_vf(hw, i);
+}
+
+static void igb_enable_bandwidth_allocation_vf(struct e1000_hw *hw, int vf,
+ unsigned int allocation)
+{
+ u32 rq;
+
+ /* Allocation is expressed as 1000ths of link speed [+]
+ *
+ * rq is calcualted as 1 / (allocation / 1000) = 1000 / allocation
+ *
+ * E1000_VMBAC_RF_INT_SHIFT and E1000_VMBAC_RF_MASK are used
+ * to marshal the result into the desired format: 23 bits of
+ * which 14 are to the right of the decimal point.
+ *
+ * [+] According to the the 82576 v2.41 datasheet rq should
+ * be a ratio of the link speed, however, empirically
+ * it appears to always be a ration of to 1Gbit/s,
+ * even when the link is 100Mbit/s.
+ */
+ rq = ((1000 << E1000_VMBAC_RF_INT_SHIFT) / allocation) &
+ E1000_VMBAC_RF_MASK;
+
+ wr32(E1000_VMBASEL, vf);
+ wr32(E1000_VMBAC, rq|E1000_VMBAC_RC_ENA);
+}
+
+static void igb_enable_bandwidth_allocation(struct igb_adapter *adapter)
+{
+ u32 i, reg;
+ struct e1000_hw *hw = &adapter->hw;
+
+ /* Only enable bandwidth_allocation if it has been set
+ * and the link speed is 100Mbit/s or 1Gbit/s */
+ if (!adapter->bandwidth_allocation ||
+ (adapter->link_speed != SPEED_100 &&
+ adapter->link_speed != SPEED_1000)) {
+ igb_disable_bandwidth_allocation(adapter);
+ return;
+ }
+
+ for (i = 0; i < adapter->vfs_allocated_count; i++) {
+ wr32(E1000_VMBASEL, i);
+ if (adapter->bandwidth_allocation[i])
+ igb_enable_bandwidth_allocation_vf(hw, i,
+ adapter->bandwidth_allocation[i]);
+ else
+ igb_disable_bandwidth_allocation_vf(hw, i);
+
+ /* XXX:
+ *
+ * The 82576 datasheet, section 4.5.11.1.5.1 "Configuring Tx
+ * Bandwidth to VMs" states that the desired setting is:
+ * VMBAMMW.MMW_SIZE = 16 * MSS
+ *
+ * But isn't MSS a property of skbs that are using tso
+ * rather than adapters?
+ *
+ * If so, should we use the maximum value here? */
+ /* XXX: Should this go inside or outside the for loop ? */
+ reg = 64 * 16;
+ wr32(E1000_VMBAMMW, reg);
+ }
+}
+#endif
+
+static void igb_check_bandwidth_allocation(struct igb_adapter *adapter)
+{
+#ifdef CONFIG_PCI_IOV
+ u32 vmbacs;
+ struct e1000_hw *hw = &adapter->hw;
+
+ if (!adapter->vf_data)
+ return;
+
+ /* The 82576 datasheet, section 4.5.11.1.5.2 "Link Speed Change
+ * Procedure" describes the sequence below. However the
+ * SPEED_CHG never seems to be set.
+ */
+ vmbacs = rd32(E1000_VMBACS);
+ if (vmbacs & E1000_VMBACS_SPEED_CHG) {
+ /* XXX: Never seem to get here */
+ int err = 0;
+
+ if (vmbacs & E1000_VMBACS_VMBA_SET) {
+ igb_disable_bandwidth_allocation(adapter);
+ err = 1;
+ }
+
+ vmbacs &= ~E1000_VMBACS_SPEED_CHG;
+ wr32(E1000_VMBACS, vmbacs);
+
+ if (err)
+ return;
+ }
+
+ spin_lock(&adapter->bandwidth_allocation_lock);
+ igb_enable_bandwidth_allocation(adapter);
+ spin_unlock(&adapter->bandwidth_allocation_lock);
+#endif
+ return;
+}
+
/**
* igb_configure_tx - Configure transmit Unit after Reset
* @adapter: board private structure
@@ -3111,6 +3261,8 @@ static void igb_watchdog_task(struct wor
break;
}
+ igb_check_bandwidth_allocation(adapter);
+
netif_carrier_on(netdev);
igb_ping_all_vfs(adapter);
@@ -6010,4 +6162,101 @@ static void igb_vmm_control(struct igb_a
}
}
+#ifdef CONFIG_PCI_IOV
+static ssize_t igb_show_bandwidth_allocation(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct net_device *netdev = dev_get_drvdata(dev);
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ int i;
+
+ if (!adapter->vf_data)
+ return -ENOENT;
+
+ *buf = '\0';
+ for (i = 0; i < adapter->vfs_allocated_count; i++) {
+ if (i > 0)
+ strcat(buf, " ");
+ sprintf(buf + strlen(buf), "%i",
+ adapter->bandwidth_allocation[i]);
+ }
+ strcat(buf, "\n");
+
+ return strlen(buf);
+}
+
+static unsigned long igb_strtoul(const char *cp, char **endp, unsigned int base)
+{
+ const char *orig = cp;
+ unsigned long x;
+
+ while (isspace(*cp))
+ cp++;
+
+ x = simple_strtoul(cp, endp, base);
+ if (cp == *endp)
+ *endp = (char *)orig;
+
+ return x;
+}
+
+static ssize_t igb_set_bandwidth_allocation(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct net_device *netdev = dev_get_drvdata(dev);
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ int i;
+ size_t len;
+ ssize_t status = -ENOENT;
+ unsigned int *new, total;
+ unsigned long x;
+ const char *p;
+ char *next_p;
+
+ if (!adapter->vf_data)
+ return -ENOENT;
+
+ len = adapter->vfs_allocated_count * sizeof(unsigned int);
+
+ new = kmalloc(len, GFP_KERNEL);
+ if (!new)
+ return -ENOMEM;
+
+ p = buf;
+ total = 0;
+ for (i = 0; i < adapter->vfs_allocated_count; i++) {
+ x = igb_strtoul(p, &next_p, 10);
+ if (p == next_p) {
+ dev_err(dev, "not enough values\n");
+ goto err;
+ }
+ if (x > 1000) {
+ dev_err(dev, "value is too large\n");
+ goto err;
+ }
+ new[i] = x;
+ total += x;
+ p = next_p;
+ }
+
+ /* Check for trailing rubbish */
+ igb_strtoul(p, &next_p, 10);
+ if (p != next_p) {
+ dev_err(dev, "trailing rubbish\n");
+ goto err;
+ }
+
+ spin_lock(&adapter->bandwidth_allocation_lock);
+ memcpy(adapter->bandwidth_allocation, new, len);
+ igb_enable_bandwidth_allocation(adapter);
+ spin_unlock(&adapter->bandwidth_allocation_lock);
+
+ status = count;
+err:
+ kfree(new);
+ return status;
+}
+#endif /* CONFIG_PCI_IOV */
/* igb_main.c */
Index: net-next-2.6/drivers/net/igb/e1000_regs.h
===================================================================
--- net-next-2.6.orig/drivers/net/igb/e1000_regs.h 2009-11-25 16:59:19.000000000 +1100
+++ net-next-2.6/drivers/net/igb/e1000_regs.h 2009-11-25 17:06:51.000000000 +1100
@@ -311,6 +311,16 @@
#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
* Filter - RW */
+/* Tx Bandwidth Allocation to VM Registers */
+#define E1000_VMBACS 0x03600 /* VM Bandwidth Allocation
+ * Control & Status - RW */
+#define E1000_VMBAMMW 0x03670 /* VM Bandwidth Allocation
+ * Max Memory Window - RW */
+#define E1000_VMBASEL 0x03604 /* VM Bandwidth Allocation
+ * Select - RW */
+#define E1000_VMBAC 0x03608 /* VM Bandwidth Allocation
+ * Config - RW */
+
#define wr32(reg, value) (writel(value, hw->hw_addr + reg))
#define rd32(reg) (readl(hw->hw_addr + reg))
#define wrfl() ((void)rd32(E1000_STATUS))
Index: net-next-2.6/drivers/net/igb/e1000_defines.h
===================================================================
--- net-next-2.6.orig/drivers/net/igb/e1000_defines.h 2009-11-25 16:59:18.000000000 +1100
+++ net-next-2.6/drivers/net/igb/e1000_defines.h 2009-11-25 17:06:51.000000000 +1100
@@ -724,4 +724,13 @@
#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision based
on DMA coal */
+/* VM Bandwidth Allocation Control & Status */
+#define E1000_VMBACS_VMBA_SET 0x00001000
+#define E1000_VMBACS_SPEED_CHG 0x80000000
+
+/* VM Bandwidth Allocation Config */
+#define E1000_VMBAC_RF_INT_SHIFT 14
+#define E1000_VMBAC_RF_MASK ((1<<23)-1) /* RF_DEC and RF_INT */
+#define E1000_VMBAC_RC_ENA 0x80000000
+
#endif
Index: net-next-2.6/drivers/net/igb/igb.h
===================================================================
--- net-next-2.6.orig/drivers/net/igb/igb.h 2009-11-25 16:59:19.000000000 +1100
+++ net-next-2.6/drivers/net/igb/igb.h 2009-11-25 17:06:51.000000000 +1100
@@ -312,6 +312,10 @@ struct igb_adapter {
unsigned int vfs_allocated_count;
struct vf_data_storage *vf_data;
u32 rss_queues;
+#ifdef CONFIG_PCI_IOV
+ unsigned int *bandwidth_allocation;
+ spinlock_t bandwidth_allocation_lock;
+#endif
};
#define IGB_FLAG_HAS_MSI (1 << 0)
^ permalink raw reply
* [rfc 2/3 v2] [E1000-devel] [rfc 3/4] igb: Common error path in igb_init_vfs()
From: Simon Horman @ 2009-11-25 6:32 UTC (permalink / raw)
To: e1000-devel, netdev; +Cc: Arnd Bergmann, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20091125063213.203372240@vergenet.net>
[-- Attachment #1: igb-common-error-path-in-igb_init_vfs.2.patch --]
[-- Type: text/plain, Size: 2968 bytes --]
Drop out into an error path on error.
This is a bit superfluous as things stand, though arguably
it already makes the code cleaner. But it should help things a lot
if igb_init_vfs() has a several things to unwind on error.
This patch eliminates resetting adapter->vfs_allocated_count to 0
in the case where CONFIG_PCI_IOV is not set, because in that
case adapter->vfs_allocated_count can never be non-zero.
Signed-off-by: Simon Horman <horms@verge.net.au>
---
Thu, 05 Nov 2009 11:58:50 +1100
* Initial post
Wed, 25 Nov 2009 16:44:15 +1100
* Merged with " Initialise adapter->vfs_allocated_count in igb_init_vf()",
however the initialisation of adapter->vfs_allocated_count is no
longer moved into igb_init_vf() as doing so results in a panic.
Index: net-next-2.6/drivers/net/igb/igb_main.c
===================================================================
--- net-next-2.6.orig/drivers/net/igb/igb_main.c 2009-11-25 17:05:43.000000000 +1100
+++ net-next-2.6/drivers/net/igb/igb_main.c 2009-11-25 17:05:44.000000000 +1100
@@ -1753,38 +1753,37 @@ static void __devinit igb_init_vf(struct
{
#ifdef CONFIG_PCI_IOV
struct pci_dev *pdev = adapter->pdev;
+ unsigned char mac_addr[ETH_ALEN];
+ int i;
if (adapter->vfs_allocated_count > 7)
adapter->vfs_allocated_count = 7;
- if (adapter->vfs_allocated_count) {
- adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
- sizeof(struct vf_data_storage),
- GFP_KERNEL);
- /* if allocation failed then we do not support SR-IOV */
- if (!adapter->vf_data) {
- adapter->vfs_allocated_count = 0;
- dev_err(&pdev->dev, "Unable to allocate memory for VF "
- "Data Storage\n");
- }
+ adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
+ sizeof(struct vf_data_storage), GFP_KERNEL);
+ /* if allocation failed then we do not support SR-IOV */
+ if (!adapter->vf_data) {
+ dev_err(&pdev->dev, "Unable to allocate memory for VF "
+ "Data Storage\n");
+ goto err_zero;
}
- if (pci_enable_sriov(pdev, adapter->vfs_allocated_count)) {
- kfree(adapter->vf_data);
- adapter->vf_data = NULL;
-#endif /* CONFIG_PCI_IOV */
- adapter->vfs_allocated_count = 0;
-#ifdef CONFIG_PCI_IOV
- } else {
- unsigned char mac_addr[ETH_ALEN];
- int i;
- dev_info(&pdev->dev, "%d vfs allocated\n",
- adapter->vfs_allocated_count);
- for (i = 0; i < adapter->vfs_allocated_count; i++) {
- random_ether_addr(mac_addr);
- igb_set_vf_mac(adapter, i, mac_addr);
- }
+ if (pci_enable_sriov(pdev, adapter->vfs_allocated_count))
+ goto err_free;
+
+ dev_info(&pdev->dev, "%d vfs allocated\n",
+ adapter->vfs_allocated_count);
+ for (i = 0; i < adapter->vfs_allocated_count; i++) {
+ random_ether_addr(mac_addr);
+ igb_set_vf_mac(adapter, i, mac_addr);
}
+
+ return;
+err_free:
+ kfree(adapter->vf_data);
+err_zero:
+ adapter->vf_data = NULL;
+ adapter->vfs_allocated_count = 0;
#endif /* CONFIG_PCI_IOV */
}
^ permalink raw reply
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