* Re: [PATCH net] e1000e: Change wthresh to 1 to avoid possible Tx stalls.
From: Jeff Kirsher @ 2012-06-06 8:46 UTC (permalink / raw)
To: Hiroaki SHIMODA; +Cc: davem, denys, eric.dumazet, therbert, netdev
In-Reply-To: <20120606174355.823e9aa7.shimoda.hiroaki@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 864 bytes --]
On Wed, 2012-06-06 at 17:43 +0900, Hiroaki SHIMODA wrote:
> Denys Fedoryshchenko reported Tx stalls on e1000e with BQL enabled.
>
> e1000e has WTHRESH which determines when Tx descripters are written
> back and successive Tx interrupts are generated, and setting WTHRESH
> to 5 gives efficient bus utilization but this cause possible Tx
> stalls,
> especially on BQL enabled system.
>
> To avoid possible Tx stalls, change WTHRESH to 1.
>
> Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
> Tested-by: Denys Fedoryshchenko <denys@visp.net.lb>
> Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
> ---
> drivers/net/ethernet/intel/e1000e/e1000.h | 6 +++---
> drivers/net/ethernet/intel/e1000e/netdev.c | 2 +-
> 2 files changed, 4 insertions(+), 4 deletions(-)
Thanks! I will add this to my queue of e1000e patches.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH] virtio-net: fix a race on 32bit arches
From: Eric Dumazet @ 2012-06-06 8:45 UTC (permalink / raw)
To: Jason Wang; +Cc: mst, netdev, linux-kernel, virtualization, Stephen Hemminger
In-Reply-To: <1338971724.2760.3913.camel@edumazet-glaptop>
On Wed, 2012-06-06 at 10:35 +0200, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> commit 3fa2a1df909 (virtio-net: per cpu 64 bit stats (v2)) added a race
> on 32bit arches.
>
> We must use separate syncp for rx and tx path as they can be run at the
> same time on different cpus. Thus one sequence increment can be lost and
> readers spin forever.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Stephen Hemminger <shemminger@vyatta.com>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Cc: Jason Wang <jasowang@redhat.com>
> ---
Just to make clear : even using percpu stats/syncp, we have no guarantee
that write_seqcount_begin() is done with one instruction. [1]
It is OK on x86 if "incl" instruction is generated by the compiler, but
on a RISC cpu, the "load memory,%reg ; inc %reg ; store %reg,memory" can
be interrupted.
So if you are 100% sure all paths are safe against preemption/BH, then
this patch is not needed, but a big comment in the code would avoid
adding possible races in the future.
[1] If done with one instruction, we still have a race, since a reader
might see an even sequence and conclude no writer is inside the critical
section. So read values could be wrong.
^ permalink raw reply
* [PATCH net] e1000e: Change wthresh to 1 to avoid possible Tx stalls.
From: Hiroaki SHIMODA @ 2012-06-06 8:43 UTC (permalink / raw)
To: jeffrey.t.kirsher, davem; +Cc: denys, eric.dumazet, therbert, netdev
Denys Fedoryshchenko reported Tx stalls on e1000e with BQL enabled.
e1000e has WTHRESH which determines when Tx descripters are written
back and successive Tx interrupts are generated, and setting WTHRESH
to 5 gives efficient bus utilization but this cause possible Tx stalls,
especially on BQL enabled system.
To avoid possible Tx stalls, change WTHRESH to 1.
Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
Tested-by: Denys Fedoryshchenko <denys@visp.net.lb>
Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
---
drivers/net/ethernet/intel/e1000e/e1000.h | 6 +++---
drivers/net/ethernet/intel/e1000e/netdev.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index 6e6fffb..dc28078 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -175,13 +175,13 @@ struct e1000_info;
/*
* in the case of WTHRESH, it appears at least the 82571/2 hardware
* writes back 4 descriptors when WTHRESH=5, and 3 descriptors when
- * WTHRESH=4, and since we want 64 bytes at a time written back, set
- * it to 5
+ * WTHRESH=4, so setting 5 gives most efficient bus utilization but
+ * to avoid possible Tx hangs, set it to 1
*/
#define E1000_TXDCTL_DMA_BURST_ENABLE \
(E1000_TXDCTL_GRAN | /* set descriptor granularity */ \
E1000_TXDCTL_COUNT_DESC | \
- (5 << 16) | /* wthresh must be +1 more than desired */\
+ (1 << 16) | /* wthresh must be +1 more than desired */\
(1 << 8) | /* hthresh */ \
0x1f) /* pthresh */
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index a4b0435..b031312 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -2806,7 +2806,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
* set up some performance related parameters to encourage the
* hardware to use the bus more efficiently in bursts, depends
* on the tx_int_delay to be enabled,
- * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time
+ * wthresh = 1 ==> burst write is disabled to consider Tx hangs
* hthresh = 1 ==> prefetch when one or more available
* pthresh = 0x1f ==> prefetch if internal cache 31 or less
* BEWARE: this seems to work but should be considered first if
--
1.7.8.6
^ permalink raw reply related
* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Hiroaki SHIMODA @ 2012-06-06 8:43 UTC (permalink / raw)
To: Eric Dumazet
Cc: Tom Herbert, Denys Fedoryshchenko, netdev, e1000-devel,
jeffrey.t.kirsher, jesse.brandeburg, davem
In-Reply-To: <1338959413.2760.3686.camel@edumazet-glaptop>
On Wed, 06 Jun 2012 07:10:13 +0200
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Tue, 2012-05-29 at 23:25 +0900, Hiroaki SHIMODA wrote:
>
> > If I understand the code and spec correctly, TX interrupts are
> > generated when TXDCTL.WTHRESH descriptors have been accumulated
> > and write backed.
> >
> > I tentatively changed the TXDCTL.WTHRESH to 1, then it seems
> > that latency spikes are disappear.
> >
> > drivers/net/ethernet/intel/e1000e/e1000.h
> > @@ -181,7 +181,7 @@ struct e1000_info;
> > #define E1000_TXDCTL_DMA_BURST_ENABLE \
> > (E1000_TXDCTL_GRAN | /* set descriptor granularity */ \
> > E1000_TXDCTL_COUNT_DESC | \
> > - (5 << 16) | /* wthresh must be +1 more than desired */\
> > + (1 << 16) | /* wthresh must be +1 more than desired */\
> > (1 << 8) | /* hthresh */ \
> > 0x1f) /* pthresh */
> >
>
>
> Was this patch officially submitted ?
>
> Thanks !
Sorry for long delay. I'll post.
(I have no idea how to fix this problem as keeping TXDCTL.WTHRESH to 5)
^ permalink raw reply
* [RFC] connectat() and bindat() system calls
From: Stanislav Kinsbursky @ 2012-06-06 8:38 UTC (permalink / raw)
To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA@public.gmane.org,
bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org, James Bottomley,
devel-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org
Hello.
I'd really appreciate for any comments on subj - implementation of new system
call: connectat and bindat.
Reasons for new system calls:
1) Path length for UNIX sockets is limited to 108 symbols.
Syscalls are useful as is since removes limitation.
2) Ability to perform connect/bind calls to UNIX sockets starting from specified
path in kernel.
This is required for proper support of kernel connect operations in SUNRPC
layer. Which, in turn, required for proper support of NFS in containers.
These system calls could be used only for non-abstract UNIX sockets, obviously.
Possible implementation could be adding of struct path pointer to sockaddr_un.
But this pointer have to valid only for connect and bind calls, and caller have
to hold and release path by himself.
--
Best regards,
Stanislav Kinsbursky
^ permalink raw reply
* [PATCH] virtio-net: fix a race on 32bit arches
From: Eric Dumazet @ 2012-06-06 8:35 UTC (permalink / raw)
To: Jason Wang; +Cc: mst, netdev, linux-kernel, virtualization, Stephen Hemminger
From: Eric Dumazet <edumazet@google.com>
commit 3fa2a1df909 (virtio-net: per cpu 64 bit stats (v2)) added a race
on 32bit arches.
We must use separate syncp for rx and tx path as they can be run at the
same time on different cpus. Thus one sequence increment can be lost and
readers spin forever.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
---
drivers/net/virtio_net.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 5214b1e..f18149a 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -42,7 +42,8 @@ module_param(gso, bool, 0444);
#define VIRTNET_DRIVER_VERSION "1.0.0"
struct virtnet_stats {
- struct u64_stats_sync syncp;
+ struct u64_stats_sync tx_syncp;
+ struct u64_stats_sync rx_syncp;
u64 tx_bytes;
u64 tx_packets;
@@ -300,10 +301,10 @@ static void receive_buf(struct net_device *dev, void *buf, unsigned int len)
hdr = skb_vnet_hdr(skb);
- u64_stats_update_begin(&stats->syncp);
+ u64_stats_update_begin(&stats->rx_syncp);
stats->rx_bytes += skb->len;
stats->rx_packets++;
- u64_stats_update_end(&stats->syncp);
+ u64_stats_update_end(&stats->rx_syncp);
if (hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
pr_debug("Needs csum!\n");
@@ -565,10 +566,10 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) {
pr_debug("Sent skb %p\n", skb);
- u64_stats_update_begin(&stats->syncp);
+ u64_stats_update_begin(&stats->tx_syncp);
stats->tx_bytes += skb->len;
stats->tx_packets++;
- u64_stats_update_end(&stats->syncp);
+ u64_stats_update_end(&stats->tx_syncp);
tot_sgs += skb_vnet_hdr(skb)->num_sg;
dev_kfree_skb_any(skb);
@@ -703,12 +704,16 @@ static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev,
u64 tpackets, tbytes, rpackets, rbytes;
do {
- start = u64_stats_fetch_begin(&stats->syncp);
+ start = u64_stats_fetch_begin(&stats->tx_syncp);
tpackets = stats->tx_packets;
tbytes = stats->tx_bytes;
+ } while (u64_stats_fetch_retry(&stats->tx_syncp, start));
+
+ do {
+ start = u64_stats_fetch_begin(&stats->rx_syncp);
rpackets = stats->rx_packets;
rbytes = stats->rx_bytes;
- } while (u64_stats_fetch_retry(&stats->syncp, start));
+ } while (u64_stats_fetch_retry(&stats->rx_syncp, start));
tot->rx_packets += rpackets;
tot->tx_packets += tpackets;
^ permalink raw reply related
* Re: [V2 RFC net-next PATCH 2/2] virtio_net: export more statistics through ethtool
From: Michael S. Tsirkin @ 2012-06-06 8:27 UTC (permalink / raw)
To: Jason Wang; +Cc: netdev, linux-kernel, virtualization
In-Reply-To: <20120606075217.29081.30713.stgit@amd-6168-8-1.englab.nay.redhat.com>
On Wed, Jun 06, 2012 at 03:52:17PM +0800, Jason Wang wrote:
> Satistics counters is useful for debugging and performance optimization, so this
> patch lets virtio_net driver collect following and export them to userspace
> through "ethtool -S":
>
> - number of packets sent/received
> - number of bytes sent/received
> - number of callbacks for tx/rx
> - number of kick for tx/rx
> - number of bytes/packets queued for tx
>
> As virtnet_stats were per-cpu, so both per-cpu and gloabl satistics were
> collected like:
>
> NIC statistics:
> tx_bytes[0]: 1731209929
> tx_packets[0]: 60685
> tx_kicks[0]: 63
> tx_callbacks[0]: 73
> tx_queued_bytes[0]: 1935749360
> tx_queued_packets[0]: 80652
> rx_bytes[0]: 2695648
> rx_packets[0]: 40767
> rx_kicks[0]: 1
> rx_callbacks[0]: 2077
> tx_bytes[1]: 9105588697
> tx_packets[1]: 344150
> tx_kicks[1]: 162
> tx_callbacks[1]: 905
> tx_queued_bytes[1]: 8901049412
> tx_queued_packets[1]: 324184
> rx_bytes[1]: 23679828
> rx_packets[1]: 358770
> rx_kicks[1]: 6
> rx_callbacks[1]: 17717
> tx_bytes: 10836798626
> tx_packets: 404835
> tx_kicks: 225
> tx_callbacks: 978
> tx_queued_bytes: 10836798772
> tx_queued_packets: 404836
> rx_bytes: 26375476
> rx_packets: 399537
> rx_kicks: 7
> rx_callbacks: 19794
>
> TODO:
>
> - more statistics
> - calculate the pending bytes/pkts
>
Do we need that? pending is (queued - packets), no?
> Signed-off-by: Jason Wang <jasowang@redhat.com>
>
> ---
> Changes from v1:
>
> - style & typo fixs
> - convert the statistics fields to array
> - use unlikely()
> ---
> drivers/net/virtio_net.c | 115 +++++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 113 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 6e4aa6f..909a0a7 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -44,8 +44,14 @@ module_param(gso, bool, 0444);
> enum virtnet_stats_type {
> VIRTNET_TX_BYTES,
> VIRTNET_TX_PACKETS,
> + VIRTNET_TX_KICKS,
> + VIRTNET_TX_CBS,
> + VIRTNET_TX_Q_BYTES,
> + VIRTNET_TX_Q_PACKETS,
> VIRTNET_RX_BYTES,
> VIRTNET_RX_PACKETS,
> + VIRTNET_RX_KICKS,
> + VIRTNET_RX_CBS,
> VIRTNET_NUM_STATS,
> };
>
> @@ -54,6 +60,21 @@ struct virtnet_stats {
> u64 data[VIRTNET_NUM_STATS];
> };
>
> +static struct {
static const?
> + char string[ETH_GSTRING_LEN];
> +} virtnet_stats_str_attr[] = {
> + { "tx_bytes" },
> + { "tx_packets" },
> + { "tx_kicks" },
> + { "tx_callbacks" },
> + { "tx_queued_bytes" },
> + { "tx_queued_packets" },
> + { "rx_bytes" },
> + { "rx_packets" },
> + { "rx_kicks" },
> + { "rx_callbacks" },
> +};
> +
> struct virtnet_info {
> struct virtio_device *vdev;
> struct virtqueue *rvq, *svq, *cvq;
> @@ -146,6 +167,11 @@ static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask)
> static void skb_xmit_done(struct virtqueue *svq)
> {
> struct virtnet_info *vi = svq->vdev->priv;
> + struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
> +
> + u64_stats_update_begin(&stats->syncp);
> + stats->data[VIRTNET_TX_CBS]++;
> + u64_stats_update_end(&stats->syncp);
>
> /* Suppress further interrupts. */
> virtqueue_disable_cb(svq);
> @@ -465,6 +491,7 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
> {
> int err;
> bool oom;
> + struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
>
> do {
> if (vi->mergeable_rx_bufs)
> @@ -481,13 +508,24 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
> } while (err > 0);
> if (unlikely(vi->num > vi->max))
> vi->max = vi->num;
> - virtqueue_kick(vi->rvq);
> + if (virtqueue_kick_prepare(vi->rvq)) {
if (unlikely())
also move stats here where they are actually used?
> + virtqueue_notify(vi->rvq);
> + u64_stats_update_begin(&stats->syncp);
> + stats->data[VIRTNET_RX_KICKS]++;
> + u64_stats_update_end(&stats->syncp);
> + }
> return !oom;
> }
>
> static void skb_recv_done(struct virtqueue *rvq)
> {
> struct virtnet_info *vi = rvq->vdev->priv;
> + struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
> +
> + u64_stats_update_begin(&stats->syncp);
> + stats->data[VIRTNET_RX_CBS]++;
> + u64_stats_update_end(&stats->syncp);
> +
> /* Schedule NAPI, Suppress further interrupts if successful. */
> if (napi_schedule_prep(&vi->napi)) {
> virtqueue_disable_cb(rvq);
> @@ -630,7 +668,9 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
> static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
> {
> struct virtnet_info *vi = netdev_priv(dev);
> + struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
> int capacity;
> + bool kick;
>
> /* Free up any pending old buffers before queueing new ones. */
> free_old_xmit_skbs(vi);
> @@ -655,7 +695,17 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
> kfree_skb(skb);
> return NETDEV_TX_OK;
> }
> - virtqueue_kick(vi->svq);
> +
> + kick = virtqueue_kick_prepare(vi->svq);
> + if (unlikely(kick))
> + virtqueue_notify(vi->svq);
> +
> + u64_stats_update_begin(&stats->syncp);
> + if (unlikely(kick))
> + stats->data[VIRTNET_TX_KICKS]++;
> + stats->data[VIRTNET_TX_Q_BYTES] += skb->len;
> + stats->data[VIRTNET_TX_Q_PACKETS]++;
> + u64_stats_update_end(&stats->syncp);
>
> /* Don't wait up for transmitted skbs to be freed. */
> skb_orphan(skb);
> @@ -943,10 +993,71 @@ static void virtnet_get_drvinfo(struct net_device *dev,
>
> }
>
> +static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
> +{
> + int i, cpu;
> + switch (stringset) {
> + case ETH_SS_STATS:
> + for_each_possible_cpu(cpu)
> + for (i = 0; i < VIRTNET_NUM_STATS; i++) {
> + sprintf(buf, "%s[%u]",
> + virtnet_stats_str_attr[i].string, cpu);
> + buf += ETH_GSTRING_LEN;
I would do
ret = snprintf(buf, ETH_GSTRING_LEN, ...)
BUG_ON(ret >= ETH_GSTRING_LEN);
here to make it more robust.
> + }
> + for (i = 0; i < VIRTNET_NUM_STATS; i++) {
> + memcpy(buf, virtnet_stats_str_attr[i].string,
> + ETH_GSTRING_LEN);
> + buf += ETH_GSTRING_LEN;
> + }
So why not just memcpy the whole array there?
memcpy(buf, virtnet_stats_str_attr,
sizeof virtnet_stats_str_attr);
> + break;
> + }
> +}
> +
> +static int virtnet_get_sset_count(struct net_device *dev, int sset)
> +{
> + switch (sset) {
> + case ETH_SS_STATS:
also add
BUILD_BUG_ON(VIRTNET_NUM_STATS != (sizeof virtnet_stats_str_attr) / ETH_GSTRING_LEN);
> + return VIRTNET_NUM_STATS * (num_possible_cpus() + 1);
> + default:
> + return -EOPNOTSUPP;
> + }
> +}
> +
> +static void virtnet_get_ethtool_stats(struct net_device *dev,
> + struct ethtool_stats *stats, u64 *buf)
> +{
> + struct virtnet_info *vi = netdev_priv(dev);
> + int cpu, i;
> + unsigned int start;
> + struct virtnet_stats sample, total;
> +
> + memset(&total, 0, sizeof(total));
sizeof total
when operand is a variable,
to distinguish from when it is a type.
> +
> + for_each_possible_cpu(cpu) {
> + struct virtnet_stats *s = per_cpu_ptr(vi->stats, cpu);
> + do {
> + start = u64_stats_fetch_begin(&s->syncp);
> + memcpy(&sample.data, &s->data,
> + sizeof(u64) * VIRTNET_NUM_STATS);
> + } while (u64_stats_fetch_retry(&s->syncp, start));
> +
> + for (i = 0; i < VIRTNET_NUM_STATS; i++) {
> + *buf = sample.data[i];
> + total.data[i] += sample.data[i];
> + buf++;
> + }
> + }
> +
> + memcpy(buf, &total.data, sizeof(u64) * VIRTNET_NUM_STATS);
> +}
> +
> static const struct ethtool_ops virtnet_ethtool_ops = {
> .get_drvinfo = virtnet_get_drvinfo,
> .get_link = ethtool_op_get_link,
> .get_ringparam = virtnet_get_ringparam,
> + .get_ethtool_stats = virtnet_get_ethtool_stats,
> + .get_strings = virtnet_get_strings,
> + .get_sset_count = virtnet_get_sset_count,
> };
>
> #define MIN_MTU 68
^ permalink raw reply
* Re: [V2 RFC net-next PATCH 1/2] virtio_net: convert the statistics into array
From: Eric Dumazet @ 2012-06-06 8:22 UTC (permalink / raw)
To: Jason Wang; +Cc: netdev, mst, linux-kernel, virtualization
In-Reply-To: <20120606075208.29081.75284.stgit@amd-6168-8-1.englab.nay.redhat.com>
On Wed, 2012-06-06 at 15:52 +0800, Jason Wang wrote:
> Currently, we store the statistics in the independent fields of virtnet_stats,
> this is not scalable when we want to add more counters. As suggested by Michael,
> this patch convert it to an array and use the enum as the index to access them.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> drivers/net/virtio_net.c | 30 +++++++++++++++++-------------
> 1 files changed, 17 insertions(+), 13 deletions(-)
>
> struct virtnet_stats {
> struct u64_stats_sync syncp;
> - u64 tx_bytes;
> - u64 tx_packets;
> -
> - u64 rx_bytes;
> - u64 rx_packets;
> + u64 data[VIRTNET_NUM_STATS];
> };
>
Interesting, but I fear you'll have a lot of problems.
Current code is buggy, and you are adding more possible races.
We could have one cpu doing the :
u64_stats_update_begin(&stats->syncp);
stats->rx_bytes += skb->len;
stats->rx_packets++;
u64_stats_update_end(&stats->syncp);
And another one doing :
u64_stats_update_begin(&stats->syncp);
stats->tx_bytes += skb->len;
stats->tx_packets++;
u64_stats_update_end(&stats->syncp);
And one syncp sequence increment can be lost, since both cpus are
basically doing this at the same time :
write_seqcount_begin(&syncp->seq);
I'll send a fix in a separate thread.
^ permalink raw reply
* Re: [PATCH] net: sierra_net: device IDs for Aircard 320U++
From: Bjørn Mork @ 2012-06-06 8:19 UTC (permalink / raw)
To: Greg KH
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA,
Dan Williams, linux-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8, Autif Khan,
Tom Cassidy, stable-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20120606081246.GB7306-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
Greg KH <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org> writes:
> On Wed, Jun 06, 2012 at 09:18:10AM +0200, Bjørn Mork wrote:
>> Adding device IDs for Aircard 320U and two other devices
>> found in the out-of-tree version of this driver.
>>
>> Cc: linux-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org
>> Cc: Autif Khan <autif.mlist-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Cc: Tom Cassidy <tomas.cassidy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Signed-off-by: Bjørn Mork <bjorn-yOkvZcmFvRU@public.gmane.org>
>> ---
>> drivers/net/usb/sierra_net.c | 14 ++++++++++----
>> 1 file changed, 10 insertions(+), 4 deletions(-)
>
> Wait, Tom just sent me a patch adding these device ids to the sierra
> serial driver, why would the same device work for both drivers?
Because it's a composite device. Was this a trick question? :-)
> Where should the device id go?
To both drivers. The device is similar to the 1199:68a3 device already
supported by both drivers. It has a number of serial ports (depending
on how many features like GPS etc is enabled) supported by the "sierra"
driver and one ethernet interface speaking Sierra's HIP protocol
supported by the "sierra_net" driver.
Bjørn
--
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
* Re: [PATCH] net: sierra_net: device IDs for Aircard 320U++
From: Greg KH @ 2012-06-06 8:12 UTC (permalink / raw)
To: Bjørn Mork
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA,
Dan Williams, linux-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8, Autif Khan,
Tom Cassidy, stable-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1338967090-7119-1-git-send-email-bjorn-yOkvZcmFvRU@public.gmane.org>
On Wed, Jun 06, 2012 at 09:18:10AM +0200, Bjørn Mork wrote:
> Adding device IDs for Aircard 320U and two other devices
> found in the out-of-tree version of this driver.
>
> Cc: linux-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org
> Cc: Autif Khan <autif.mlist-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: Tom Cassidy <tomas.cassidy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Bjørn Mork <bjorn-yOkvZcmFvRU@public.gmane.org>
> ---
> drivers/net/usb/sierra_net.c | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
Wait, Tom just sent me a patch adding these device ids to the sierra
serial driver, why would the same device work for both drivers? Where
should the device id go?
confused,
greg k-h
--
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
* [V2 RFC net-next PATCH 2/2] virtio_net: export more statistics through ethtool
From: Jason Wang @ 2012-06-06 7:52 UTC (permalink / raw)
To: netdev, rusty, virtualization, linux-kernel, mst
In-Reply-To: <20120606075208.29081.75284.stgit@amd-6168-8-1.englab.nay.redhat.com>
Satistics counters is useful for debugging and performance optimization, so this
patch lets virtio_net driver collect following and export them to userspace
through "ethtool -S":
- number of packets sent/received
- number of bytes sent/received
- number of callbacks for tx/rx
- number of kick for tx/rx
- number of bytes/packets queued for tx
As virtnet_stats were per-cpu, so both per-cpu and gloabl satistics were
collected like:
NIC statistics:
tx_bytes[0]: 1731209929
tx_packets[0]: 60685
tx_kicks[0]: 63
tx_callbacks[0]: 73
tx_queued_bytes[0]: 1935749360
tx_queued_packets[0]: 80652
rx_bytes[0]: 2695648
rx_packets[0]: 40767
rx_kicks[0]: 1
rx_callbacks[0]: 2077
tx_bytes[1]: 9105588697
tx_packets[1]: 344150
tx_kicks[1]: 162
tx_callbacks[1]: 905
tx_queued_bytes[1]: 8901049412
tx_queued_packets[1]: 324184
rx_bytes[1]: 23679828
rx_packets[1]: 358770
rx_kicks[1]: 6
rx_callbacks[1]: 17717
tx_bytes: 10836798626
tx_packets: 404835
tx_kicks: 225
tx_callbacks: 978
tx_queued_bytes: 10836798772
tx_queued_packets: 404836
rx_bytes: 26375476
rx_packets: 399537
rx_kicks: 7
rx_callbacks: 19794
TODO:
- more statistics
- calculate the pending bytes/pkts
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
Changes from v1:
- style & typo fixs
- convert the statistics fields to array
- use unlikely()
---
drivers/net/virtio_net.c | 115 +++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 6e4aa6f..909a0a7 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -44,8 +44,14 @@ module_param(gso, bool, 0444);
enum virtnet_stats_type {
VIRTNET_TX_BYTES,
VIRTNET_TX_PACKETS,
+ VIRTNET_TX_KICKS,
+ VIRTNET_TX_CBS,
+ VIRTNET_TX_Q_BYTES,
+ VIRTNET_TX_Q_PACKETS,
VIRTNET_RX_BYTES,
VIRTNET_RX_PACKETS,
+ VIRTNET_RX_KICKS,
+ VIRTNET_RX_CBS,
VIRTNET_NUM_STATS,
};
@@ -54,6 +60,21 @@ struct virtnet_stats {
u64 data[VIRTNET_NUM_STATS];
};
+static struct {
+ char string[ETH_GSTRING_LEN];
+} virtnet_stats_str_attr[] = {
+ { "tx_bytes" },
+ { "tx_packets" },
+ { "tx_kicks" },
+ { "tx_callbacks" },
+ { "tx_queued_bytes" },
+ { "tx_queued_packets" },
+ { "rx_bytes" },
+ { "rx_packets" },
+ { "rx_kicks" },
+ { "rx_callbacks" },
+};
+
struct virtnet_info {
struct virtio_device *vdev;
struct virtqueue *rvq, *svq, *cvq;
@@ -146,6 +167,11 @@ static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask)
static void skb_xmit_done(struct virtqueue *svq)
{
struct virtnet_info *vi = svq->vdev->priv;
+ struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
+
+ u64_stats_update_begin(&stats->syncp);
+ stats->data[VIRTNET_TX_CBS]++;
+ u64_stats_update_end(&stats->syncp);
/* Suppress further interrupts. */
virtqueue_disable_cb(svq);
@@ -465,6 +491,7 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
{
int err;
bool oom;
+ struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
do {
if (vi->mergeable_rx_bufs)
@@ -481,13 +508,24 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
} while (err > 0);
if (unlikely(vi->num > vi->max))
vi->max = vi->num;
- virtqueue_kick(vi->rvq);
+ if (virtqueue_kick_prepare(vi->rvq)) {
+ virtqueue_notify(vi->rvq);
+ u64_stats_update_begin(&stats->syncp);
+ stats->data[VIRTNET_RX_KICKS]++;
+ u64_stats_update_end(&stats->syncp);
+ }
return !oom;
}
static void skb_recv_done(struct virtqueue *rvq)
{
struct virtnet_info *vi = rvq->vdev->priv;
+ struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
+
+ u64_stats_update_begin(&stats->syncp);
+ stats->data[VIRTNET_RX_CBS]++;
+ u64_stats_update_end(&stats->syncp);
+
/* Schedule NAPI, Suppress further interrupts if successful. */
if (napi_schedule_prep(&vi->napi)) {
virtqueue_disable_cb(rvq);
@@ -630,7 +668,9 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+ struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
int capacity;
+ bool kick;
/* Free up any pending old buffers before queueing new ones. */
free_old_xmit_skbs(vi);
@@ -655,7 +695,17 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
kfree_skb(skb);
return NETDEV_TX_OK;
}
- virtqueue_kick(vi->svq);
+
+ kick = virtqueue_kick_prepare(vi->svq);
+ if (unlikely(kick))
+ virtqueue_notify(vi->svq);
+
+ u64_stats_update_begin(&stats->syncp);
+ if (unlikely(kick))
+ stats->data[VIRTNET_TX_KICKS]++;
+ stats->data[VIRTNET_TX_Q_BYTES] += skb->len;
+ stats->data[VIRTNET_TX_Q_PACKETS]++;
+ u64_stats_update_end(&stats->syncp);
/* Don't wait up for transmitted skbs to be freed. */
skb_orphan(skb);
@@ -943,10 +993,71 @@ static void virtnet_get_drvinfo(struct net_device *dev,
}
+static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+ int i, cpu;
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for_each_possible_cpu(cpu)
+ for (i = 0; i < VIRTNET_NUM_STATS; i++) {
+ sprintf(buf, "%s[%u]",
+ virtnet_stats_str_attr[i].string, cpu);
+ buf += ETH_GSTRING_LEN;
+ }
+ for (i = 0; i < VIRTNET_NUM_STATS; i++) {
+ memcpy(buf, virtnet_stats_str_attr[i].string,
+ ETH_GSTRING_LEN);
+ buf += ETH_GSTRING_LEN;
+ }
+ break;
+ }
+}
+
+static int virtnet_get_sset_count(struct net_device *dev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return VIRTNET_NUM_STATS * (num_possible_cpus() + 1);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void virtnet_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *buf)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ int cpu, i;
+ unsigned int start;
+ struct virtnet_stats sample, total;
+
+ memset(&total, 0, sizeof(total));
+
+ for_each_possible_cpu(cpu) {
+ struct virtnet_stats *s = per_cpu_ptr(vi->stats, cpu);
+ do {
+ start = u64_stats_fetch_begin(&s->syncp);
+ memcpy(&sample.data, &s->data,
+ sizeof(u64) * VIRTNET_NUM_STATS);
+ } while (u64_stats_fetch_retry(&s->syncp, start));
+
+ for (i = 0; i < VIRTNET_NUM_STATS; i++) {
+ *buf = sample.data[i];
+ total.data[i] += sample.data[i];
+ buf++;
+ }
+ }
+
+ memcpy(buf, &total.data, sizeof(u64) * VIRTNET_NUM_STATS);
+}
+
static const struct ethtool_ops virtnet_ethtool_ops = {
.get_drvinfo = virtnet_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_ringparam = virtnet_get_ringparam,
+ .get_ethtool_stats = virtnet_get_ethtool_stats,
+ .get_strings = virtnet_get_strings,
+ .get_sset_count = virtnet_get_sset_count,
};
#define MIN_MTU 68
^ permalink raw reply related
* [V2 RFC net-next PATCH 1/2] virtio_net: convert the statistics into array
From: Jason Wang @ 2012-06-06 7:52 UTC (permalink / raw)
To: netdev, rusty, virtualization, linux-kernel, mst
Currently, we store the statistics in the independent fields of virtnet_stats,
this is not scalable when we want to add more counters. As suggested by Michael,
this patch convert it to an array and use the enum as the index to access them.
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/net/virtio_net.c | 30 +++++++++++++++++-------------
1 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 5214b1e..6e4aa6f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -41,13 +41,17 @@ module_param(gso, bool, 0444);
#define VIRTNET_SEND_COMMAND_SG_MAX 2
#define VIRTNET_DRIVER_VERSION "1.0.0"
+enum virtnet_stats_type {
+ VIRTNET_TX_BYTES,
+ VIRTNET_TX_PACKETS,
+ VIRTNET_RX_BYTES,
+ VIRTNET_RX_PACKETS,
+ VIRTNET_NUM_STATS,
+};
+
struct virtnet_stats {
struct u64_stats_sync syncp;
- u64 tx_bytes;
- u64 tx_packets;
-
- u64 rx_bytes;
- u64 rx_packets;
+ u64 data[VIRTNET_NUM_STATS];
};
struct virtnet_info {
@@ -301,8 +305,8 @@ static void receive_buf(struct net_device *dev, void *buf, unsigned int len)
hdr = skb_vnet_hdr(skb);
u64_stats_update_begin(&stats->syncp);
- stats->rx_bytes += skb->len;
- stats->rx_packets++;
+ stats->data[VIRTNET_RX_BYTES] += skb->len;
+ stats->data[VIRTNET_RX_PACKETS]++;
u64_stats_update_end(&stats->syncp);
if (hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
@@ -566,8 +570,8 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
pr_debug("Sent skb %p\n", skb);
u64_stats_update_begin(&stats->syncp);
- stats->tx_bytes += skb->len;
- stats->tx_packets++;
+ stats->data[VIRTNET_TX_BYTES] += skb->len;
+ stats->data[VIRTNET_TX_PACKETS]++;
u64_stats_update_end(&stats->syncp);
tot_sgs += skb_vnet_hdr(skb)->num_sg;
@@ -704,10 +708,10 @@ static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev,
do {
start = u64_stats_fetch_begin(&stats->syncp);
- tpackets = stats->tx_packets;
- tbytes = stats->tx_bytes;
- rpackets = stats->rx_packets;
- rbytes = stats->rx_bytes;
+ tpackets = stats->data[VIRTNET_TX_PACKETS];
+ tbytes = stats->data[VIRTNET_TX_BYTES];
+ rpackets = stats->data[VIRTNET_RX_PACKETS];
+ rbytes = stats->data[VIRTNET_RX_BYTES];
} while (u64_stats_fetch_retry(&stats->syncp, start));
tot->rx_packets += rpackets;
^ permalink raw reply related
* [PATCH] net: sierra_net: device IDs for Aircard 320U++
From: Bjørn Mork @ 2012-06-06 7:18 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA, Greg KH, Dan Williams,
Bjørn Mork, linux-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8,
Autif Khan, Tom Cassidy, stable-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20120605212414.GB6526-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
Adding device IDs for Aircard 320U and two other devices
found in the out-of-tree version of this driver.
Cc: linux-ywE8TTl5eJHWpu6QEFMNjNBPR1lH4CV8@public.gmane.org
Cc: Autif Khan <autif.mlist-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: Tom Cassidy <tomas.cassidy-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Bjørn Mork <bjorn-yOkvZcmFvRU@public.gmane.org>
---
drivers/net/usb/sierra_net.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index 3faef56..d75d1f5 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -946,7 +946,7 @@ struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
}
static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 };
-static const struct sierra_net_info_data sierra_net_info_data_68A3 = {
+static const struct sierra_net_info_data sierra_net_info_data_direct_ip = {
.rx_urb_size = 8 * 1024,
.whitelist = {
.infolen = ARRAY_SIZE(sierra_net_ifnum_list),
@@ -954,7 +954,7 @@ static const struct sierra_net_info_data sierra_net_info_data_68A3 = {
}
};
-static const struct driver_info sierra_net_info_68A3 = {
+static const struct driver_info sierra_net_info_direct_ip = {
.description = "Sierra Wireless USB-to-WWAN Modem",
.flags = FLAG_WWAN | FLAG_SEND_ZLP,
.bind = sierra_net_bind,
@@ -962,12 +962,18 @@ static const struct driver_info sierra_net_info_68A3 = {
.status = sierra_net_status,
.rx_fixup = sierra_net_rx_fixup,
.tx_fixup = sierra_net_tx_fixup,
- .data = (unsigned long)&sierra_net_info_data_68A3,
+ .data = (unsigned long)&sierra_net_info_data_direct_ip,
};
static const struct usb_device_id products[] = {
{USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */
- .driver_info = (unsigned long) &sierra_net_info_68A3},
+ .driver_info = (unsigned long) &sierra_net_info_direct_ip},
+ {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */
+ .driver_info = (unsigned long) &sierra_net_info_direct_ip},
+ {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */
+ .driver_info = (unsigned long) &sierra_net_info_direct_ip},
+ {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */
+ .driver_info = (unsigned long) &sierra_net_info_direct_ip},
{}, /* last item */
};
--
1.7.10
--
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] net: stmmac: Fix clock en-/disable calls
From: Stefan Roese @ 2012-06-06 6:49 UTC (permalink / raw)
To: netdev; +Cc: viresh kumar, Giuseppe Cavallaro
Signed-off-by: Stefan Roese <sr@denx.de>
Cc: viresh kumar <viresh.linux@gmail.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 6b5d060..f46d8d0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -109,7 +109,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
static inline int stmmac_clk_enable(struct stmmac_priv *priv)
{
if (!IS_ERR(priv->stmmac_clk))
- return clk_enable(priv->stmmac_clk);
+ return clk_prepare_enable(priv->stmmac_clk);
return 0;
}
@@ -119,7 +119,7 @@ static inline void stmmac_clk_disable(struct stmmac_priv *priv)
if (IS_ERR(priv->stmmac_clk))
return;
- clk_disable(priv->stmmac_clk);
+ clk_disable_unprepare(priv->stmmac_clk);
}
static inline int stmmac_clk_get(struct stmmac_priv *priv)
{
--
1.7.10.4
^ permalink raw reply related
* Re: [net-next RFC PATCH] virtio_net: collect satistics and export through ethtool
From: Michael S. Tsirkin @ 2012-06-06 6:49 UTC (permalink / raw)
To: Jason Wang; +Cc: netdev, linux-kernel, virtualization
In-Reply-To: <4FCEE45B.8080800@redhat.com>
On Wed, Jun 06, 2012 at 01:02:19PM +0800, Jason Wang wrote:
> On 06/05/2012 06:10 PM, Michael S. Tsirkin wrote:
> >On Tue, Jun 05, 2012 at 04:38:41PM +0800, Jason Wang wrote:
> >>Satistics counters is useful for debugging and performance optimization, so this
> >>patch lets virtio_net driver collect following and export them to userspace
> >>through "ethtool -S":
> >>
> >>- number of packets sent/received
> >>- number of bytes sent/received
> >>- number of callbacks for tx/rx
> >>- number of kick for tx/rx
> >>- number of bytes/packets queued for tx
> >>
> >>As virtnet_stats were per-cpu, so both per-cpu and gloabl satistics were exposed
> >>like:
> >>
> >>NIC statistics:
> >> tx_bytes[0]: 2551
> >> tx_packets[0]: 12
> >> tx_kick[0]: 12
> >> tx_callbacks[0]: 1
> >> tx_queued_packets[0]: 12
> >> tx_queued_bytes[0]: 3055
> >> rx_bytes[0]: 0
> >> rx_packets[0]: 0
> >> rx_kick[0]: 0
> >> rx_callbacks[0]: 0
> >> tx_bytes[1]: 5575
> >> tx_packets[1]: 37
> >> tx_kick[1]: 38
> >> tx_callbacks[1]: 0
> >> tx_queued_packets[1]: 38
> >> tx_queued_bytes[1]: 5217
> >> rx_bytes[1]: 4175
> >> rx_packets[1]: 25
> >> rx_kick[1]: 1
> >> rx_callbacks[1]: 16
> >> tx_bytes: 8126
> >> tx_packets: 49
> >> tx_kick: 50
> >> tx_callbacks: 1
> >> tx_queued_packets: 50
> >> tx_queued_bytes: 8272
> >> rx_bytes: 4175
> >> rx_packets: 25
> >> rx_kick: 1
> >> rx_callbacks: 16
> >>
> >>TODO:
> >>
> >>- more satistics
> >>- unitfy the ndo_get_stats64 and get_ethtool_stats
> >>- calculate the pending bytes/pkts
> >>
> >>Signed-off-by: Jason Wang<jasowang@redhat.com>
> >>---
> >> drivers/net/virtio_net.c | 130 +++++++++++++++++++++++++++++++++++++++++++++-
> >> 1 files changed, 127 insertions(+), 3 deletions(-)
> >>
> >>diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> >>index 5214b1e..7ab0cc1 100644
> >>--- a/drivers/net/virtio_net.c
> >>+++ b/drivers/net/virtio_net.c
> >>@@ -41,6 +41,10 @@ module_param(gso, bool, 0444);
> >> #define VIRTNET_SEND_COMMAND_SG_MAX 2
> >> #define VIRTNET_DRIVER_VERSION "1.0.0"
> >>
> >>+#define VIRTNET_STAT_OFF(m) offsetof(struct virtnet_stats, m)
> >>+#define VIRTNET_STAT(stat, i) (*((u64 *)((char *)stat + \
> >What's going on? Why cast to char *?
>
> It's used to let the pointer advance at the unit of bytes instead of
> the whole stat strcuture.
Make offset be in units of sizeof u64 and you won't need
this hack.
Also, macro parameters must be surrounded with ().
> >>+ virtnet_stats_str_attr[i].stat_offset)))
> >These are confusing unless you see what virtnet_stats_str_attr
> >is so please move them near that definition.
>
> ok.
> >>+
> >> struct virtnet_stats {
> >> struct u64_stats_sync syncp;
> >> u64 tx_bytes;
> >>@@ -48,8 +52,33 @@ struct virtnet_stats {
> >>
> >> u64 rx_bytes;
> >> u64 rx_packets;
> >>+
> >>+ u64 tx_kick;
> >>+ u64 rx_kick;
> >>+ u64 tx_callbacks;
> >>+ u64 rx_callbacks;
> >>+ u64 tx_queued_packets;
> >>+ u64 tx_queued_bytes;
> >>+};
> >I have an idea (not a must): why don't we simply create an enum
> >enum virtnet_stats {
> > VIRTNET_TX_KICK,
> > VIRTNET_RX_KICK,
> > ....
> > VIRTNET_MAX_STAT,
> >}
> >
> >
> >now stats can just do
> > stats->data[VIRTNET_RX_KICK] instead of stats->rx_kick
> >which is not a big problem, but copying them in bulk
> >becomes straight-forward, no need for macros at all.
> >
> >If we decide to do this, needs to be a separate patch,
> >then this one on top.
>
> Make sense, would do this.
> >>+
> >>+static struct {
> >static const.
> >
> >>+ char string[ETH_GSTRING_LEN];
> >>+ int stat_offset;
> >>+} virtnet_stats_str_attr[] = {
> >>+ { "tx_bytes", VIRTNET_STAT_OFF(tx_bytes)},
> >>+ { "tx_packets", VIRTNET_STAT_OFF(tx_packets)},
> >>+ { "tx_kick", VIRTNET_STAT_OFF(tx_kick)},
> >>+ { "tx_callbacks", VIRTNET_STAT_OFF(tx_callbacks)},
> >>+ { "tx_queued_packets", VIRTNET_STAT_OFF(tx_queued_packets)},
> >>+ { "tx_queued_bytes", VIRTNET_STAT_OFF(tx_queued_bytes)},
> >>+ { "rx_bytes" , VIRTNET_STAT_OFF(rx_bytes)},
> >>+ { "rx_packets", VIRTNET_STAT_OFF(rx_packets)},
> >>+ { "rx_kick", VIRTNET_STAT_OFF(rx_kick)},
> >>+ { "rx_callbacks", VIRTNET_STAT_OFF(rx_callbacks)},
> >VIRTNET_STAT_OFF does not save much here, but if you are after
> >saving characters then make the macro instanciate the string
> >as well.
> >
> >> };
> >>
> >>+#define VIRTNET_NUM_STATS ARRAY_SIZE(virtnet_stats_str_attr)
> >>+
> >if you pass virtnet_stats_str_attr to VIRTNET_STAT macro,
> >then it's explicit and VIRTNET_NUM_STATS won't be needed either.
>
> It's used to report the number of satistics through .get_sset_count.
Yes but you can then open-code.
> >
> >> struct virtnet_info {
> >> struct virtio_device *vdev;
> >> struct virtqueue *rvq, *svq, *cvq;
> >>@@ -142,6 +171,11 @@ static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask)
> >> static void skb_xmit_done(struct virtqueue *svq)
> >> {
> >> struct virtnet_info *vi = svq->vdev->priv;
> >>+ struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
> >>+
> >>+ u64_stats_update_begin(&stats->syncp);
> >>+ stats->tx_callbacks++;
> >>+ u64_stats_update_end(&stats->syncp);
> >>
> >> /* Suppress further interrupts. */
> >> virtqueue_disable_cb(svq);
> >>@@ -461,6 +495,7 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
> >> {
> >> int err;
> >> bool oom;
> >>+ struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
> >>
> >> do {
> >> if (vi->mergeable_rx_bufs)
> >>@@ -477,13 +512,24 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
> >> } while (err> 0);
> >> if (unlikely(vi->num> vi->max))
> >> vi->max = vi->num;
> >>- virtqueue_kick(vi->rvq);
> >>+ if (virtqueue_kick_prepare(vi->rvq)) {
> >>+ virtqueue_notify(vi->rvq);
> >>+ u64_stats_update_begin(&stats->syncp);
> >>+ stats->rx_kick++;
> >>+ u64_stats_update_end(&stats->syncp);
> >>+ }
> >> return !oom;
> >> }
> >>
> >> static void skb_recv_done(struct virtqueue *rvq)
> >> {
> >> struct virtnet_info *vi = rvq->vdev->priv;
> >>+ struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
> >>+
> >>+ u64_stats_update_begin(&stats->syncp);
> >>+ stats->rx_callbacks++;
> >>+ u64_stats_update_end(&stats->syncp);
> >>+
> >> /* Schedule NAPI, Suppress further interrupts if successful. */
> >> if (napi_schedule_prep(&vi->napi)) {
> >> virtqueue_disable_cb(rvq);
> >>@@ -626,7 +672,9 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
> >> static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
> >> {
> >> struct virtnet_info *vi = netdev_priv(dev);
> >>+ struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
> >> int capacity;
> >>+ bool kick;
> >>
> >> /* Free up any pending old buffers before queueing new ones. */
> >> free_old_xmit_skbs(vi);
> >>@@ -651,7 +699,17 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
> >> kfree_skb(skb);
> >> return NETDEV_TX_OK;
> >> }
> >>- virtqueue_kick(vi->svq);
> >>+
> >>+ kick = virtqueue_kick_prepare(vi->svq);
> >>+ if (kick)
> >probably
> > if (unlikely(kick))
> >
> >>+ virtqueue_notify(vi->svq);
> >>+
> >>+ u64_stats_update_begin(&stats->syncp);
> >>+ if (kick)
> >this too
> >
> >>+ stats->tx_kick++;
> >>+ stats->tx_queued_bytes += skb->len;
> >>+ stats->tx_queued_packets++;
> >>+ u64_stats_update_end(&stats->syncp);
> >>
> >> /* Don't wait up for transmitted skbs to be freed. */
> >> skb_orphan(skb);
> >>@@ -926,7 +984,6 @@ static void virtnet_get_ringparam(struct net_device *dev,
> >>
> >> }
> >>
> >>-
> >> static void virtnet_get_drvinfo(struct net_device *dev,
> >> struct ethtool_drvinfo *info)
> >> {
> >>@@ -939,10 +996,77 @@ static void virtnet_get_drvinfo(struct net_device *dev,
> >>
> >> }
> >>
> >>+static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
> >>+{
> >>+ int i, cpu;
> >>+ switch (stringset) {
> >>+ case ETH_SS_STATS:
> >>+ for_each_possible_cpu(cpu)
> >>+ for (i = 0; i< VIRTNET_NUM_STATS; i++) {
> >>+ sprintf(buf, "%s[%u]",
> >>+ virtnet_stats_str_attr[i].string, cpu);
> >>+ buf += ETH_GSTRING_LEN;
> >>+ }
> >>+ for (i = 0; i< VIRTNET_NUM_STATS; i++) {
> >>+ memcpy(buf, virtnet_stats_str_attr[i].string,
> >>+ ETH_GSTRING_LEN);
> >>+ buf += ETH_GSTRING_LEN;
> >>+ }
> >>+ break;
> >>+ }
> >>+}
> >>+
> >>+static int virtnet_get_sset_count(struct net_device *dev, int sset)
> >>+{
> >>+ switch (sset) {
> >>+ case ETH_SS_STATS:
> >>+ return VIRTNET_NUM_STATS * (num_online_cpus() + 1);
> >This will allocate buffers for online cpus only, but the above
> >will fill them in for all possible cpus.
> >Will this overrun some buffer?
> >
>
> Yes, a typo here, should be num_possible_cpus().
> Thanks
> >>+ default:
> >>+ return -EOPNOTSUPP;
> >>+ }
> >>+}
> >>+
> >>+static void virtnet_get_ethtool_stats(struct net_device *dev,
> >>+ struct ethtool_stats *stats, u64 *buf)
> >The coding style says
> > Descendants are always substantially shorter than the parent and
> > are placed substantially to the right.
> >
> >you can't call it substantially to the right if it's to the left of
> >the opening '(' :), so please indent it aligning on the opening.
>
> Looks like something wrong in my emacs c-style confiugration, would
> check it.
> >>+{
> >>+ struct virtnet_info *vi = netdev_priv(dev);
> >>+ int cpu, i;
> >>+ unsigned int start;
> >>+ struct virtnet_stats sample, total;
> >>+
> >>+ memset(&total, 0, sizeof(total));
> >>+ memset(&sample, 0, sizeof(sample));
> >>+
> >>+ for_each_possible_cpu(cpu) {
> >>+ struct virtnet_stats *stats = per_cpu_ptr(vi->stats, cpu);
> >>+ do {
> >>+ start = u64_stats_fetch_begin(&stats->syncp);
> >>+ for (i = 0; i< VIRTNET_NUM_STATS; i++) {
> >>+ VIRTNET_STAT(&sample, i) =
> >>+ VIRTNET_STAT(stats, i);
> >when you feel the need to break lines like this - don't :)
> >use an inline function instead.
> >
> >>+
> >kill empty line here
> >>+ }
> >don't put {} around single statements pls.
>
> Sure
> >>+ } while (u64_stats_fetch_retry(&stats->syncp, start));
> >>+ for (i = 0; i< VIRTNET_NUM_STATS; i++) {
> >>+ *buf = VIRTNET_STAT(&sample, i);
> >>+ VIRTNET_STAT(&total, i) += VIRTNET_STAT(stats, i);
> >>+ buf++;
> >>+ }
> >>+ }
> >>+
> >>+ for (i = 0; i< VIRTNET_NUM_STATS; i++) {
> >>+ *buf = VIRTNET_STAT(&total, i);
> >>+ buf++;
> >>+ }
> >>+}
> >>+
> >> static const struct ethtool_ops virtnet_ethtool_ops = {
> >> .get_drvinfo = virtnet_get_drvinfo,
> >> .get_link = ethtool_op_get_link,
> >> .get_ringparam = virtnet_get_ringparam,
> >>+ .get_ethtool_stats = virtnet_get_ethtool_stats,
> >>+ .get_strings = virtnet_get_strings,
> >>+ .get_sset_count = virtnet_get_sset_count,
> >> };
> >>
> >> #define MIN_MTU 68
> >--
> >To unsubscribe from this list: send the line "unsubscribe netdev" in
> >the body of a message to majordomo@vger.kernel.org
> >More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [patch] net/ethernet: ks8851_mll unregister_netdev() before freeing
From: Dan Carpenter @ 2012-06-06 6:31 UTC (permalink / raw)
To: Raffaele Recalcati; +Cc: David S. Miller, netdev, kernel-janitors
We added another error condition here, but if we were to hit it then
we need to unregister_netdev() before doing the free_netdev().
Otherwise we would hit the BUG_ON() in free_netdev():
BUG_ON(dev->reg_state != NETREG_UNREGISTERED);
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
Static checker stuff. I don't have this hardware.
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index 70bd329..875dd5e 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -1606,7 +1606,7 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
if (!pdata) {
netdev_err(netdev, "No platform data\n");
err = -ENODEV;
- goto err_register;
+ goto err_pdata;
}
memcpy(ks->mac_addr, pdata->mac_addr, 6);
if (!is_valid_ether_addr(ks->mac_addr)) {
@@ -1626,6 +1626,8 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
(id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7);
return 0;
+err_pdata:
+ unregister_netdev(netdev);
err_register:
err_get_irq:
iounmap(ks->hw_addr_cmd);
^ permalink raw reply related
* [PATCH net-next 0/7] be2net: patch series
From: Sathya Perla @ 2012-06-06 5:39 UTC (permalink / raw)
To: netdev; +Cc: Sathya Perla
Pls apply.
Sathya Perla (7):
be2net: do not call be_vid_config() when there's no vlan config
be2net: cleanup be_vid_config()
be2net: do not modify PCI MaxReadReq size
be2net: fix reporting number of actual rx queues
be2net: remove unnecessary usage of unlikely()
be2net: do not use SCRATCHPAD register
be2net: update driver version
drivers/net/ethernet/emulex/benet/be.h | 2 +-
drivers/net/ethernet/emulex/benet/be_hw.h | 2 -
drivers/net/ethernet/emulex/benet/be_main.c | 50 ++++++++++++---------------
3 files changed, 23 insertions(+), 31 deletions(-)
--
1.7.4
^ permalink raw reply
* [PATCH net-next 6/7] be2net: do not use SCRATCHPAD register
From: Sathya Perla @ 2012-06-06 5:37 UTC (permalink / raw)
To: netdev; +Cc: Sathya Perla
In-Reply-To: <1338961043-26820-1-git-send-email-sathya.perla@emulex.com>
The CUST_SCRATCHPAD_CSR register is used for marking if FW cleanup is
needed. This is used in a crash kernel scenario. Do no use this register as
it is not available for some functions. Instead, always issue an FLR when
a function is probed *except* when VFs are preset (enabled in the previous
PF load).
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_hw.h | 2 --
drivers/net/ethernet/emulex/benet/be_main.c | 10 +++-------
2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
index d9fb0c5..7c8a710 100644
--- a/drivers/net/ethernet/emulex/benet/be_hw.h
+++ b/drivers/net/ethernet/emulex/benet/be_hw.h
@@ -58,8 +58,6 @@
#define SLI_PORT_CONTROL_IP_MASK 0x08000000
-#define PCICFG_CUST_SCRATCHPAD_CSR 0x1EC
-
/********* Memory BAR register ************/
#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
/* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 42ee75b..f29827f 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1049,6 +1049,8 @@ static int be_find_vfs(struct be_adapter *adapter, int vf_state)
u16 offset, stride;
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
+ if (!pos)
+ return 0;
pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset);
pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride);
@@ -2542,7 +2544,6 @@ static int be_clear(struct be_adapter *adapter)
be_cmd_fw_clean(adapter);
be_msix_disable(adapter);
- pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 0);
return 0;
}
@@ -2785,8 +2786,6 @@ static int be_setup(struct be_adapter *adapter)
schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
-
- pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 1);
return 0;
err:
be_clear(adapter);
@@ -3724,10 +3723,7 @@ reschedule:
static bool be_reset_required(struct be_adapter *adapter)
{
- u32 reg;
-
- pci_read_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, ®);
- return reg;
+ return be_find_vfs(adapter, ENABLED) > 0 ? false : true;
}
static int __devinit be_probe(struct pci_dev *pdev,
--
1.7.4
^ permalink raw reply related
* [PATCH net-next 7/7] be2net: update driver version
From: Sathya Perla @ 2012-06-06 5:37 UTC (permalink / raw)
To: netdev; +Cc: Sathya Perla
In-Reply-To: <1338961043-26820-1-git-send-email-sathya.perla@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index c5c4c0e..7b5cc2b 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -34,7 +34,7 @@
#include "be_hw.h"
#include "be_roce.h"
-#define DRV_VER "4.2.220u"
+#define DRV_VER "4.2.248.0u"
#define DRV_NAME "be2net"
#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
#define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC"
--
1.7.4
^ permalink raw reply related
* [PATCH net-next 5/7] be2net: remove unnecessary usage of unlikely()
From: Sathya Perla @ 2012-06-06 5:37 UTC (permalink / raw)
To: netdev; +Cc: Sathya Perla
In-Reply-To: <1338961043-26820-1-git-send-email-sathya.perla@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 3aa478f..42ee75b 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -719,8 +719,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb,
* 60 bytes long.
* As a workaround disable TX vlan offloading in such cases.
*/
- if (unlikely(vlan_tx_tag_present(skb) &&
- (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60))) {
+ if (vlan_tx_tag_present(skb) &&
+ (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60)) {
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
goto tx_drop;
--
1.7.4
^ permalink raw reply related
* [PATCH net-next 4/7] be2net: fix reporting number of actual rx queues
From: Sathya Perla @ 2012-06-06 5:37 UTC (permalink / raw)
To: netdev; +Cc: Sathya Perla
In-Reply-To: <1338961043-26820-1-git-send-email-sathya.perla@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 695c3cf..3aa478f 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1890,6 +1890,12 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
*/
adapter->num_rx_qs = (num_irqs(adapter) > 1) ?
num_irqs(adapter) + 1 : 1;
+ if (adapter->num_rx_qs != MAX_RX_QS) {
+ rtnl_lock();
+ netif_set_real_num_rx_queues(adapter->netdev,
+ adapter->num_rx_qs);
+ rtnl_unlock();
+ }
adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
for_all_rx_queues(adapter, rxo, i) {
@@ -3740,7 +3746,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
goto disable_dev;
pci_set_master(pdev);
- netdev = alloc_etherdev_mq(sizeof(struct be_adapter), MAX_TX_QS);
+ netdev = alloc_etherdev_mqs(sizeof(*adapter), MAX_TX_QS, MAX_RX_QS);
if (netdev == NULL) {
status = -ENOMEM;
goto rel_reg;
--
1.7.4
^ permalink raw reply related
* [PATCH net-next 1/7] be2net: don't call vid_config() when there's no vlan config
From: Sathya Perla @ 2012-06-06 5:37 UTC (permalink / raw)
To: netdev; +Cc: Sathya Perla
be_vid_config() is called from be_setup() to replay config cmds after
a card reset. Skip calling it when no vlans are configured.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 08efd30..f1b0926 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2762,7 +2762,8 @@ static int be_setup(struct be_adapter *adapter)
be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
- be_vid_config(adapter, false, 0);
+ if (adapter->vlans_added)
+ be_vid_config(adapter, false, 0);
be_set_rx_mode(adapter->netdev);
--
1.7.4
^ permalink raw reply related
* [PATCH net-next 2/7] be2net: cleanup be_vid_config()
From: Sathya Perla @ 2012-06-06 5:37 UTC (permalink / raw)
To: netdev; +Cc: Sathya Perla
In-Reply-To: <1338961043-26820-1-git-send-email-sathya.perla@emulex.com>
- get rid of 2 unused arguments to the routine and some unused code
- don't use the term "vlan_tag" in place of "vid" as they are different
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 25 +++++++++----------------
1 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index f1b0926..cfbec8b 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -785,19 +785,12 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
* A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE.
* If the user configures more, place BE in vlan promiscuous mode.
*/
-static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
+static int be_vid_config(struct be_adapter *adapter)
{
- struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf_num];
- u16 vtag[BE_NUM_VLANS_SUPPORTED];
- u16 ntags = 0, i;
+ u16 vids[BE_NUM_VLANS_SUPPORTED];
+ u16 num = 0, i;
int status = 0;
- if (vf) {
- vtag[0] = cpu_to_le16(vf_cfg->vlan_tag);
- status = be_cmd_vlan_config(adapter, vf_cfg->if_handle, vtag,
- 1, 1, 0);
- }
-
/* No need to further configure vids if in promiscuous mode */
if (adapter->promiscuous)
return 0;
@@ -808,10 +801,10 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
/* Construct VLAN Table to give to HW */
for (i = 0; i < VLAN_N_VID; i++)
if (adapter->vlan_tag[i])
- vtag[ntags++] = cpu_to_le16(i);
+ vids[num++] = cpu_to_le16(i);
status = be_cmd_vlan_config(adapter, adapter->if_handle,
- vtag, ntags, 1, 0);
+ vids, num, 1, 0);
/* Set to VLAN promisc mode as setting VLAN filter failed */
if (status) {
@@ -840,7 +833,7 @@ static int be_vlan_add_vid(struct net_device *netdev, u16 vid)
adapter->vlan_tag[vid] = 1;
if (adapter->vlans_added <= (adapter->max_vlans + 1))
- status = be_vid_config(adapter, false, 0);
+ status = be_vid_config(adapter);
if (!status)
adapter->vlans_added++;
@@ -862,7 +855,7 @@ static int be_vlan_rem_vid(struct net_device *netdev, u16 vid)
adapter->vlan_tag[vid] = 0;
if (adapter->vlans_added <= adapter->max_vlans)
- status = be_vid_config(adapter, false, 0);
+ status = be_vid_config(adapter);
if (!status)
adapter->vlans_added--;
@@ -889,7 +882,7 @@ static void be_set_rx_mode(struct net_device *netdev)
be_cmd_rx_filter(adapter, IFF_PROMISC, OFF);
if (adapter->vlans_added)
- be_vid_config(adapter, false, 0);
+ be_vid_config(adapter);
}
/* Enable multicast promisc if num configured exceeds what we support */
@@ -2763,7 +2756,7 @@ static int be_setup(struct be_adapter *adapter)
be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
if (adapter->vlans_added)
- be_vid_config(adapter, false, 0);
+ be_vid_config(adapter);
be_set_rx_mode(adapter->netdev);
--
1.7.4
^ permalink raw reply related
* [PATCH net-next 3/7] be2net: do not modify PCI MaxReadReq size
From: Sathya Perla @ 2012-06-06 5:37 UTC (permalink / raw)
To: netdev; +Cc: Sathya Perla
In-Reply-To: <1338961043-26820-1-git-send-email-sathya.perla@emulex.com>
Setting the PCI MRRS to a value of 4096 (overriding the system decided
value) had provided perf improvement in TX.
But, IBM has provided feedback that on POWER platforms, this value is set
by the system firmware, and drivers modifying this value can cause
unpredictable results (like EEH errors.) So, backing off this change.
On POWER7 platforms most slots, it seems, do get a MRRS of 4096.
This patch reverts the following commit:
"be2net: Modified PCI MaxReadReq size to 4096 bytes"
commit 5a56eb10babbcd7b3796dc3c28c271260aa3608d.
Suggested-by: Brian King <bjking1@us.ibm.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index cfbec8b..695c3cf 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2766,8 +2766,6 @@ static int be_setup(struct be_adapter *adapter)
be_cmd_set_flow_control(adapter, adapter->tx_fc,
adapter->rx_fc);
- pcie_set_readrq(adapter->pdev, 4096);
-
if (be_physfn(adapter) && num_vfs) {
if (adapter->dev_num_vfs)
be_vf_setup(adapter);
--
1.7.4
^ permalink raw reply related
* Re: [PATCH] netdev: mv643xx_eth: Prevent build on PPC32
From: Andrew Lunn @ 2012-06-06 5:29 UTC (permalink / raw)
To: Josh Boyer
Cc: Ben Hutchings, Lennert Buytenhek, Andrew Lunn, Olof Johansson,
netdev
In-Reply-To: <20120606023842.GD7683@zod.bos.redhat.com>
> The proper fix, from my minimal looking, was one of:
>
> 1) revert the change for ARM that introduced th clk stuff
> 2) do a similar change as the original commit but with a bunch of
> #ifdef-ery
> 3) implement the clkdev API stuff for 32-bit ppc
>
> Honestly, I'd go for either 1 or 2. The commit that introduced it was
> broken to begin with, but that isn't my call.
I broke it. Sorry.
At the time, there was a push to remove all the #ifdefs. The following
patchset was doing this:
https://lkml.org/lkml/2012/4/21/94
it would provide dummy implementations for those systems without clk
support. However, it seems that patch set never made it in, and i did
not declare my dependency on it.
I'm happy to add #ifdef. However, i would first like to understand
what was 'broken to begin with'.
Thanks
Andrew
^ 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