* Re: [PATCH net-next] ixgbe: flush when in xmit_more mode and under descriptor pressure
From: Alexander Duyck @ 2014-08-26 16:24 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: davem, netdev
In-Reply-To: <53FCB400.70705@redhat.com>
On 08/26/2014 09:21 AM, Daniel Borkmann wrote:
> On 08/26/2014 06:01 PM, Alexander Duyck wrote:
> ...
>> My thought is to just fold ixgbe_maybe_stop_tx into the if statement.
>>
>> So it shoudl be:
>> if (!skb->smit_more || ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED))
>
> Right, that's better; I was just thinking about the DMA error case,
> but in that case we release resources back anyway.
Actually the order does need to be reversed though. We should test for
stop_tx first, then xmit_more. Doing it the other way around would
cause issues as maybe_stop_tx has some other side effects.
Thaks,
Alex
^ permalink raw reply
* Re: [PATCH v6 net-next 4/6] bpf: enable bpf syscall on x64 and i386
From: Alexei Starovoitov @ 2014-08-26 16:29 UTC (permalink / raw)
To: Ingo Molnar
Cc: David Miller, Linus Torvalds, Andy Lutomirski, Steven Rostedt,
Daniel Borkmann, Chema Gonzalez, Eric Dumazet, Peter Zijlstra,
Brendan Gregg, Namhyung Kim, H. Peter Anvin, Andrew Morton,
Kees Cook, Linux API, Network Development, LKML
In-Reply-To: <20140826074534.GA19799@gmail.com>
On Tue, Aug 26, 2014 at 12:45 AM, Ingo Molnar <mingo@kernel.org> wrote:
>
> * Alexei Starovoitov <ast@plumgrid.com> wrote:
>
>> On Mon, Aug 25, 2014 at 6:07 PM, David Miller <davem@davemloft.net> wrote:
>> > From: Alexei Starovoitov <ast@plumgrid.com>
>> > Date: Mon, 25 Aug 2014 18:00:56 -0700
>> >
>> >> -
>> >> +asmlinkage long sys_bpf(int cmd, unsigned long arg2, unsigned long arg3,
>> >> + unsigned long arg4, unsigned long arg5);
>> >
>> > Please do not add interfaces with opaque types as arguments.
>> >
>> > It is impossible for the compiler to type check the args at
>> > compile time when userspace tries to use this stuff.
>>
>> I share this concern. I went with single BPF syscall, because
>> alternative is 6 syscalls for every command and more
>> syscalls in the future when we'd need to add another command.
>
> See 'struct perf_event_attr':
>
> SYSCALL_DEFINE5(perf_event_open,
> struct perf_event_attr __user *, attr_uptr,
> pid_t, pid, int, cpu, int, group_fd, unsigned long, flags)
>
> This way we were able to gradually grow to the sophisticated ABI
> you can find in include/uapi/linux/perf_event.h, without having
> to touch the syscall interface. (It's not the only method: we
> also have a handful of ioctls, where that's the most natural
> interface for a perf event fd.)
Thanks! that's a good alternative.
One approach would be to have two bpf syscalls:
map_fd = bpf_map_create(map_type, nlattr)
+ bunch of ioctl()s that do lookup/update/delete/...
prog_fd = bpf_prog_load(prog_type, nlattr)
but ioctl()s would still do a lot of type casting.
so how about single syscall:
fd = bpf(int cmd, union bpf_attr *attrs, int size)
union bpf_attr {
struct bpf_map_create_attr { /* used by bpf_map_create cmd */
__u32 key_size, value_size, ...
};
struct bpf_map_access_attr { /* by lookup/update/delete/get_next */
int map_fd;
void __user *key; /* used by all */
void __user *value; /* used by lookup/update */
void __user *next_key; /* used by get_next */
};
struct nlattr prog_attr[0]; /* used by bpf_prog_load cmd */
};
If you prefer I can make prog_load attrs to be explicit struct
as well, but nlattr feels cleaner, since there can be optional
sections that are quite large. Like one with 'readonly constants'
that I'm still working on as part of cleaner strings support.
Also I think I will change tracing attachment interface.
Currently write("prog_fd_as_int") -> "/sys/../tracing/events/..."
does the attachment, but as Andy noticed that may be not
secure enough if there is fork() somewhere in the process
that does open() of debugfs and write().
Looks like another ioctl() like PERF_EVENT_IOC_SET_FILTER_BPF
on top of perf_event_open() would be cleaner and event->owner
check can be done easily.
Can I create kprobe event through perf_event_open() ?
^ permalink raw reply
* Re: [PATCH 2/2] ixgbe: support skb->xmit_more in netdev_ops->ndo_start_xmit()
From: Alexander Duyck @ 2014-08-26 16:36 UTC (permalink / raw)
To: Tom Herbert, Hannes Frederic Sowa
Cc: David Miller, Linux Netdev List, Jamal Hadi Salim, Eric Dumazet,
Jeff Kirsher, Rusty Russell, Daniel Borkmann, brouer
In-Reply-To: <CA+mtBx_phCQDd=nS4Wfe=9R=FXpQ3xqfnBrYuPwzqRNaybcc6A@mail.gmail.com>
On 08/26/2014 09:20 AM, Tom Herbert wrote:
> On Tue, Aug 26, 2014 at 8:40 AM, Hannes Frederic Sowa
> <hannes@stressinduktion.org> wrote:
>> On Di, 2014-08-26 at 08:00 -0700, Alexander Duyck wrote:
>>> On 08/25/2014 04:35 PM, David Miller wrote:
>>>>
>>>> From: Daniel Borkmann <dborkman@redhat.com>
>>>>
>>>> This implements the deferred tail pointer flush API for the ixgbe
>>>> driver. Similar version also proposed longer time ago by Alexander Duyck.
>>>>
>>>> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
>>>> Signed-off-by: David S. Miller <davem@davemloft.net>
>>>> ---
>>>> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 7 ++++---
>>>> 1 file changed, 4 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
>>>> index 87bd53f..ba9ceaa 100644
>>>> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
>>>> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
>>>> @@ -6958,9 +6958,10 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring,
>>>>
>>>> tx_ring->next_to_use = i;
>>>>
>>>> - /* notify HW of packet */
>>>> - ixgbe_write_tail(tx_ring, i);
>>>> -
>>>> + if (!skb->xmit_more) {
>>>> + /* notify HW of packet */
>>>> + ixgbe_write_tail(tx_ring, i);
>>>> + }
>>>> return;
>>>> dma_error:
>>>> dev_err(tx_ring->dev, "TX DMA map failed\n");
>>>>
>>>
>>> It might help to add some handling for the case where xmit_more is set,
>>> but the ring has become full. This current implementation introduces
>>> the risk of triggering a Tx hang.
>>
>> IMHO this should be done before the patch lands in the driver.
>>
>>> My advice would be to pull the ixgbe_maybe_stop_tx code at the end of
>>> xmit_frame into the if check here, and perhaps look into adding an
>>> additional check to see if BQL has stopped the ring as well.
>>
>> I would like to have the BQL check not in the driver but in the generic
>> code steering xmit_more.
>>
>
> BQL stops the queue from netdev_tx_sent_queue, we could change that to
> return indication queue was stopped and use that as another check to
> flush.
Either that or we could just add it as state check.
Maybe change the code to something like:
ixgbe_maybe_stop_tx(tx_ring, DESC_UNUSED);
/* notify HW of packet */
if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more)
ixgbe_write_tail(tx_ring, i)
Then we could catch both the driver or stack stopping the ring and
identifying it as an indication that we should flush the ring.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH v6 net-next 4/6] bpf: enable bpf syscall on x64 and i386
From: Alexei Starovoitov @ 2014-08-26 16:40 UTC (permalink / raw)
To: Ingo Molnar
Cc: Daniel Borkmann, Stephen Hemminger, David S. Miller,
Linus Torvalds, Andy Lutomirski, Steven Rostedt, Chema Gonzalez,
Eric Dumazet, Peter Zijlstra, Brendan Gregg, Namhyung Kim,
H. Peter Anvin, Andrew Morton, Kees Cook, Linux API,
Network Development, LKML
In-Reply-To: <20140826080231.GA20565-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Tue, Aug 26, 2014 at 1:02 AM, Ingo Molnar <mingo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>
>> That said, I think Alexei is referring to the examples et al
>> from the bigger previous proposed patch set.
>
> I mean, if all the testing already exists, it should be part of
> an initial submission and such.
That's what I did. V5 set contains all examples and verifier testsuite:
https://lkml.org/lkml/2014/8/24/107
Dave asked to split it up into subsets, since it's too big too review
at once. which makes sense, so this V6 is only first part and
the plan was:
1st(this) set - introduces uapi/linux/bpf.h and BPF syscall for maps only
2nd set will extend BPF syscall with programs and verifier
3rd set will use eBPF in tracing, add samples and verifier tests
4th set will have llvm and C examples
Each set is around 6-8 patches instead of 29 in V5
^ permalink raw reply
* Re: [PATCH 0/2] Get rid of ndo_xmit_flush
From: Alexander Duyck @ 2014-08-26 16:43 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: David Miller, netdev, therbert, jhs, hannes, edumazet,
jeffrey.t.kirsher, rusty, dborkman
In-Reply-To: <20140826145225.6673ab3f@redhat.com>
On 08/26/2014 05:52 AM, Jesper Dangaard Brouer wrote:
>
> On Tue, 26 Aug 2014 12:13:47 +0200 Jesper Dangaard Brouer <brouer@redhat.com> wrote:
>
>> On Tue, 26 Aug 2014 08:28:15 +0200 Jesper Dangaard Brouer <brouer@redhat.com> wrote:
>>> On Mon, 25 Aug 2014 16:34:58 -0700 (PDT) David Miller <davem@davemloft.net> wrote:
>>>
>>>> Given Jesper's performance numbers, it's not the way to go.
>>>>
>>>> Instead, go with a signalling scheme via new boolean skb->xmit_more.
>>>
>>> I'll do benchmarking based on this new API proposal today.
>>
>> While establish an accurate baseline for my measurements. I'm
>> starting to see too much variation in my trafgen measurements.
>> Meaning that we unfortunately cannot use it to measure variations on
>> the nanosec scale.
>
> Thus, we need to find a better more accurate measurement tool than
> trafgen/af_packet.
>
> Changed my PPS monitor "ifpps-oneliner" to calculate the nanosec
> variation between the instant reading and the average. For TX also
> record the "max" and "min" variation value seen.
>
> This should give us a better (instant) picture of how accurate the
> measurement is.
>
> ifpps -clod eth5 -t 1000 | \
> awk 'BEGIN{txsum=0; rxsum=0; n=0; txvar=0; txvar_min=0; txvar_max=0; rxvar=0;} \
> /[[:digit:]]/ {txsum+=$11;rxsum+=$3;n++; \
> txvar=0; if (txsum/n>10 && $11>0) { \
> txvar=((1/(txsum/n)*10^9)-(1/$11*10^9)); \
> if (n>10 && txvar < txvar_min) {txvar_min=txvar}; \
> if (n>10 && txvar > txvar_max) {txvar_max=txvar}; \
> }; \
> rxvar=0; if (rxsum/n>10 && $3>0 ) { rxvar=((1/(rxsum/n)*10^9)-(1/$3*10^9))}; \
> printf "instant rx:%u tx:%u pps n:%u average: rx:%d tx:%d pps (instant variation TX %.3f ns (min:%.3f max:%.3f) RX %.3f ns)\n", $3, $11, n, rxsum/n, txsum/n, txvar, txvar_min, txvar_max, rxvar; \
> if (txvar > 2) {printf "WARNING instant variation high\n" } }'
>
>
> Nanosec variation with trafgen:
> -------------------------------
>
> As can be seen, the min and max nanosec variation with trafgen is
> higher than we would like:
>
> Results: trafgen
> (sudo ethtool -C eth5 rx-usecs 1)
> instant rx:0 tx:1566064 pps n:152 average: rx:0 tx:1564534 pps
> (instant variation TX 0.624 ns (min:-6.336 max:1.766) RX 0.000 ns)
>
> Results: trafgen
> (sudo ethtool -C eth5 rx-usecs 30)
> instant rx:0 tx:1576452 pps n:121 average: rx:0 tx:1575652 pps
> (instant variation TX 0.322 ns (min:-4.479 max:0.714) RX 0.000 ns)
>
>
> Switching to pktgen
> -------------------
>
> I suspect a more accurate measurement tool will be "pktgen", because
> we can cut out most of the things that can cause these variations
> (like kmem_cache and cache-hot variations, and most sched variations).
>
> The main problem with ixgbe is that, in this overload scenario, the
> performance is limited by the TX ring size and cleanup intervals, as
> described in:
> http://netoptimizer.blogspot.dk/2014/06/pktgen-for-network-overload-testing.html
> https://www.kernel.org/doc/Documentation/networking/pktgen.txt
>
> Results below: Try to determine which ixgbe ethtool setting gives the
> most stable PPS readings. Notice the TX "min" and "max" nanosec
> variations seen over the period. Sampling over approx 120 sec.
>
> The best setting seems to be:
> sudo ethtool -C eth5 rx-usecs 30
> sudo ethtool -G eth5 tx 512 #(default size)
>
> Pktgen tests are single CPU performance numbers, script based on:
> https://github.com/netoptimizer/network-testing/blob/master/pktgen/example01.sh
> with CLONE_SKB="100000" (and single flow, const port number 9/discard)
>
> Setting:
> sudo ethtool -G eth5 tx 512 #(Default setting)
> sudo ethtool -C eth5 rx-usecs 1 #(Default setting)
> Result pktgen:
> * instant rx:1 tx:3933892 pps n:120 average: rx:1 tx:3934182 pps
> (instant variation TX -0.019 ns (min:-0.047 max:0.016) RX 0.000 ns)
>
> The variation very small, but the performance is limited by the TX
> ring buffer being full most of the time, TX cleanup being too slow.
>
> Setting: (inc TX ring size)
> sudo ethtool -G eth5 tx 1024
> sudo ethtool -C eth5 rx-usecs 1 #(default setting)
> Result pktgen:
> * instant rx:1 tx:5745632 pps n:118 average: rx:1 tx:5748818 pps
> (instant variation TX -0.096 ns (min:-0.293 max:0.897) RX 0.000 ns)
>
> Setting:
> sudo ethtool -G eth5 tx 512
> sudo ethtool -C eth5 rx-usecs 20
> Result pktgen:
> * instant rx:1 tx:5765168 pps n:120 average: rx:0 tx:5782242 pps
> (instant variation TX -0.512 ns (min:-1.008 max:1.599) RX 0.000 ns)
>
> Setting:
> sudo ethtool -G eth5 tx 512
> sudo ethtool -C eth5 rx-usecs 30
> Result pktgen:
> * instant rx:1 tx:5920856 pps n:114 average: rx:1 tx:5918350 pps
> (instant variation TX 0.071 ns (min:-0.177 max:0.135) RX 0.000 ns)
>
> Setting:
> sudo ethtool -G eth5 tx 512
> sudo ethtool -C eth5 rx-usecs 40
> Result pktgen:
> * instant rx:1 tx:5958408 pps n:120 average: rx:0 tx:5947908 pps
> (instant variation TX 0.296 ns (min:-1.410 max:0.595) RX 0.000 ns)
>
> Setting:
> sudo ethtool -G eth5 tx 512
> sudo ethtool -C eth5 rx-usecs 50
> Result pktgen:
> * instant rx:1 tx:5966964 pps n:120 average: rx:1 tx:5967306 pps
> (instant variation TX -0.010 ns (min:-1.330 max:0.169) RX 0.000 ns)
>
> Setting:
> sudo ethtool -C eth5 rx-usecs 30
> sudo ethtool -G eth5 tx 1024
> Result pktgen:
> instant rx:0 tx:5846252 pps n:120 average: rx:1 tx:5852464 pps
> (instant variation TX -0.182 ns (min:-0.467 max:2.249) RX 0.000 ns)
>
>
My advice would be to disable all C states and P states (including
turbo) if possible, and try using idle=poll. Any processor frequency
and/or C state transitions will totally wreak havoc with trying to get
reliable results out of any performance test.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH (net.git)] phy: fix EEE checks inside the phy_init_eee.
From: Florian Fainelli @ 2014-08-26 16:55 UTC (permalink / raw)
To: Giuseppe Cavallaro, netdev; +Cc: Nandini Sharma
In-Reply-To: <1409038012-11574-1-git-send-email-peppe.cavallaro@st.com>
On 08/26/2014 12:26 AM, Giuseppe Cavallaro wrote:
> According to the Std 802.3az if the EEE Adv (Reg 7.60), Link partner ability
> (Reg 7.61) and EEE capability (Register 3.20) bits return 0 this means no EEE
> is supported. So this patch fixes the checks inside the phy_init_eee function.
>
> Signed-off-by: Nandini Sharma <nandini.sharma@st.com>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/net/phy/phy.c | 18 +++++++++---------
> 1 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index c94e2a2..a854d38 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -1036,31 +1036,31 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
> /* First check if the EEE ability is supported */
> eee_cap = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE,
> MDIO_MMD_PCS, phydev->addr);
> - if (eee_cap < 0)
> - return eee_cap;
> + if (eee_cap <= 0)
> + goto eee_exit_err;
>
> cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
> if (!cap)
> - return -EPROTONOSUPPORT;
> + goto eee_exit_err;
!cap is most likely not possible anymore now that you are checking that
eee_cap <= 0
>
> /* Check which link settings negotiated and verify it in
> * the EEE advertising registers.
> */
> eee_lp = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE,
> MDIO_MMD_AN, phydev->addr);
> - if (eee_lp < 0)
> - return eee_lp;
> + if (eee_lp <= 0)
> + goto eee_exit_err;
>
> eee_adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
> MDIO_MMD_AN, phydev->addr);
> - if (eee_adv < 0)
> - return eee_adv;
> + if (eee_adv <= 0)
> + goto eee_exit_err;
>
> adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
> lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
> idx = phy_find_setting(phydev->speed, phydev->duplex);
> if (!(lp & adv & settings[idx].setting))
> - return -EPROTONOSUPPORT;
> + goto eee_exit_err;
>
> if (clk_stop_enable) {
> /* Configure the PHY to stop receiving xMII
> @@ -1080,7 +1080,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
>
> return 0; /* EEE supported */
> }
> -
> +eee_exit_err:
> return -EPROTONOSUPPORT;
> }
> EXPORT_SYMBOL(phy_init_eee);
>
^ permalink raw reply
* Re: [patch net-next RFC 02/12] net: rename netdev_phys_port_id to more generic name
From: Stephen Hemminger @ 2014-08-26 17:14 UTC (permalink / raw)
To: Or Gerlitz
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w, ronye-VPRAkNaXOzVWk0Htik3J/w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ben-/+tVBieCtBitmTQ+vhA3Yw, buytenh-OLH4Qvv75CYX/NnBR394Jw,
Jiri Pirko, roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
netdev-u79uwXL29TY76Z2rM5mHXA, dborkman-H+wXaHxf7aLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <53FC7C3C.3090901-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
On Tue, 26 Aug 2014 15:23:24 +0300
Or Gerlitz <ogerlitz-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> wrote:
> just a nit, but if this approach/patch goes in, any reason not to change
> IFLA_PHYS_PORT_ID to IFLA_PHYS_ITEM_ID?
Userspace API
^ permalink raw reply
* [PATCH v2 net-next] ixgbe: flush when in xmit_more mode and under descriptor pressure
From: Daniel Borkmann @ 2014-08-26 17:34 UTC (permalink / raw)
To: alexander.h.duyck; +Cc: davem, netdev
When xmit_more mode is being used and the ring is about to
become full or the stack has stopped the ring, enforce a tail
pointer write to the hw. Otherwise, we could risk a TX hang.
Code suggested by Alexander Duyck.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
v1->v2:
- Worked in Alex' feedback; in accordance w/ Alex, sending out v2
- Rerun tests, looks good
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 63 +++++++++++++++------------
1 file changed, 34 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index ba9ceaa..53fbf06 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -6837,6 +6837,36 @@ static void ixgbe_tx_olinfo_status(union ixgbe_adv_tx_desc *tx_desc,
tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
}
+static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
+{
+ netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
+
+ /* Herbert's original patch had:
+ * smp_mb__after_netif_stop_queue();
+ * but since that doesn't exist yet, just open code it.
+ */
+ smp_mb();
+
+ /* We need to check again in a case another CPU has just
+ * made room available.
+ */
+ if (likely(ixgbe_desc_unused(tx_ring) < size))
+ return -EBUSY;
+
+ /* A reprieve! - use start_queue because it doesn't call schedule */
+ netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index);
+ ++tx_ring->tx_stats.restart_queue;
+ return 0;
+}
+
+static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
+{
+ if (likely(ixgbe_desc_unused(tx_ring) >= size))
+ return 0;
+
+ return __ixgbe_maybe_stop_tx(tx_ring, size);
+}
+
#define IXGBE_TXD_CMD (IXGBE_TXD_CMD_EOP | \
IXGBE_TXD_CMD_RS)
@@ -6958,10 +6988,13 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring,
tx_ring->next_to_use = i;
- if (!skb->xmit_more) {
+ ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED);
+
+ if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
/* notify HW of packet */
ixgbe_write_tail(tx_ring, i);
}
+
return;
dma_error:
dev_err(tx_ring->dev, "TX DMA map failed\n");
@@ -7068,32 +7101,6 @@ static void ixgbe_atr(struct ixgbe_ring *ring,
input, common, ring->queue_index);
}
-static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
-{
- netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index);
- /* Herbert's original patch had:
- * smp_mb__after_netif_stop_queue();
- * but since that doesn't exist yet, just open code it. */
- smp_mb();
-
- /* We need to check again in a case another CPU has just
- * made room available. */
- if (likely(ixgbe_desc_unused(tx_ring) < size))
- return -EBUSY;
-
- /* A reprieve! - use start_queue because it doesn't call schedule */
- netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index);
- ++tx_ring->tx_stats.restart_queue;
- return 0;
-}
-
-static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
-{
- if (likely(ixgbe_desc_unused(tx_ring) >= size))
- return 0;
- return __ixgbe_maybe_stop_tx(tx_ring, size);
-}
-
static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv, select_queue_fallback_t fallback)
{
@@ -7262,8 +7269,6 @@ xmit_fcoe:
#endif /* IXGBE_FCOE */
ixgbe_tx_map(tx_ring, first, hdr_len);
- ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED);
-
return NETDEV_TX_OK;
out_drop:
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH 12/35] [PATCH 12/36] net: Replace get_cpu_var through this_cpu_ptr
From: Tejun Heo @ 2014-08-26 18:09 UTC (permalink / raw)
To: Christoph Lameter
Cc: akpm, rostedt, linux-kernel, Ingo Molnar, Peter Zijlstra,
Thomas Gleixner, netdev, Eric Dumazet, David S. Miller
In-Reply-To: <20140817173034.793528138@linux.com>
On Sun, Aug 17, 2014 at 12:30:35PM -0500, Christoph Lameter wrote:
> Replace uses of get_cpu_var for address calculation through this_cpu_ptr.
>
> Cc: netdev@vger.kernel.org
> Cc: Eric Dumazet <edumazet@google.com>
> Acked-by: David S. Miller <davem@davemloft.net>
> Signed-off-by: Christoph Lameter <cl@linux.com>
(Please disregard the ones I posted for v1 of the patch series)
Applied to percpu/for-3.18-consistent-ops. Please let me know if this
patch should be routed differently. Note that this patch was to be
applied to percpu/for-3.17 but delayed due to build issues caused by
cpumask_var_t.
Thanks.
--
tejun
^ permalink raw reply
* Re: [patch net-next RFC 10/12] openvswitch: add support for datapath hardware offload
From: Andy Gospodarek @ 2014-08-26 18:41 UTC (permalink / raw)
To: Thomas Graf
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w, ronye-VPRAkNaXOzVWk0Htik3J/w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, Andy Gospodarek,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w, Shrijeet Mukherjee,
John Fastabend, jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw, Jiri Pirko, Roopa Prabhu,
Jamal Hadi Salim, aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, Neil Horman, netdev,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ, dborkman,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, David Miller
In-Reply-To: <20140826161956.GA15316-FZi0V3Vbi30CUdFEqe4BF2D2FQJk+8+b@public.gmane.org>
On Tue, Aug 26, 2014 at 05:19:56PM +0100, Thomas Graf wrote:
> On 08/26/14 at 11:54am, Andy Gospodarek wrote:
> > It is easy to *say* it could be added later, but connecting to software
> > forwarding in the kernel outside of OVS (which is important to some)
> > would take significant effort since this set only connects switch
> > hardware to OVS.
>
> Can you explain why that effort is more significant if a flow API
> added first? I'm not saying it is easy to offload the existing
> forwarding path, otherwise it would have been done already, but
> I don't understand how the proposal makes this any more difficult.
Sorry if I introduced any confusion. My intent was not to imply there
was specific increased technical effort required to implement other
software forwarding elements in hardware if a flow-based API is added
first.
> > It may be that all software-based forwarding is done via OVS in the
> > future, but it feels like we are long way from that future for those
> > that do not want to use an external controller.
>
> Wait... I don't want to use OpenFlow to configure my laptop ;-)
You don't? I do. ;-)
^ permalink raw reply
* Re: [patch net-next RFC 06/12] net: introduce dummy switch
From: Andy Gospodarek @ 2014-08-26 19:14 UTC (permalink / raw)
To: Jiri Pirko
Cc: ryazanov.s.a-Re5JQEeQqe8AvxtiuMwx3w,
jasowang-H+wXaHxf7aLQT0dZR+AlfA,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
Neil.Jerram-QnUH15yq9NYqDJ6do+/SaQ,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
dev-yBygre7rU0TnMu66kgdUjQ, nbd-p3rKhJxN3npAfugRpC6u6w,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w, ronye-VPRAkNaXOzVWk0Htik3J/w,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
ogerlitz-VPRAkNaXOzVWk0Htik3J/w, ben-/+tVBieCtBitmTQ+vhA3Yw,
buytenh-OLH4Qvv75CYX/NnBR394Jw,
roopa-qUQiAmfTcIp+XZJcv9eMoEEOCMrvLtNR,
jhs-jkUAjuhPggJWk0Htik3J/w, aviadr-VPRAkNaXOzVWk0Htik3J/w,
nicolas.dichtel-pdR9zngts4EAvxtiuMwx3w,
vyasevic-H+wXaHxf7aLQT0dZR+AlfA, nhorman-2XuSBdqkA4R54TAoqtyWWQ,
netdev-u79uwXL29TY76Z2rM5mHXA,
stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ,
dborkman-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <1408637945-10390-7-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
On Thu, Aug 21, 2014 at 06:18:59PM +0200, Jiri Pirko wrote:
> Dummy switch implementation using switchdev interface
>
[...]
> + if (!data || !data[IFLA_DYMMYSWPORT_PHYS_SWITCH_ID])
[...]
> + dsp->psid.id_len = nla_len(data[IFLA_DYMMYSWPORT_PHYS_SWITCH_ID]);
> + memcpy(dsp->psid.id, nla_data(data[IFLA_DYMMYSWPORT_PHYS_SWITCH_ID]),
[...]
> + [IFLA_DYMMYSWPORT_PHYS_SWITCH_ID] = { .type = NLA_BINARY,
[...]
> + IFLA_DYMMYSWPORT_PHYS_SWITCH_ID,
I realize this does compile, but I suspect this was a typo?
^ permalink raw reply
* Re: [PATCH v2 3/3] tg3: Fix tx_pending checks for tg3_tso_bug
From: Benjamin Poirier @ 2014-08-26 19:25 UTC (permalink / raw)
To: Prashant Sreedharan; +Cc: Michael Chan, netdev, linux-kernel
In-Reply-To: <1408749447.8268.53.camel@prashant>
On 2014/08/22 16:17, Prashant Sreedharan wrote:
> Benjamin, thanks for the patch. Broadcom QA will be testing the changes.
> Couple of comments below.
> > segs = skb_gso_segment(skb, tp->dev->features &
> > ~(NETIF_F_TSO | NETIF_F_TSO6));
> > - if (IS_ERR(segs) || !segs)
> > + if (IS_ERR_OR_NULL(segs))
> > goto tg3_tso_bug_end;
> >
> > do {
> > + unsigned int desc_cnt = skb_shinfo(segs)->nr_frags + 1;
> > +
> > nskb = segs;
> > segs = segs->next;
> > nskb->next = NULL;
> > - tg3_start_xmit(nskb, tp->dev);
> > +
> > + if (tg3_tx_avail(tnapi) <= segs_remaining - 1 + desc_cnt &&
> > + skb_linearize(nskb)) {
> > + nskb->next = segs;
> > + segs = nskb;
> > + do {
> > + nskb = segs->next;
> > +
> > + dev_kfree_skb_any(segs);
> > + segs = nskb;
> > + } while (segs);
>
> If skb_linearize() fails need to increment the tp->tx_dropped count
Sorry for the delay, while testing this error path I noticed a potential
problem. There should be an additional check here to stop the queue with
the default threshold. Otherwise, the netdev_err message at the start of
__tg3_start_xmit() could be triggered when the next frame is
transmitted. That is because the previous calls to __tg3_start_xmit() in
tg3_tso_bug() may have been using a stop_thresh=segs_remaining that is <
MAX_SKB_FRAGS + 1.
>
> > + goto tg3_tso_bug_end;
> > + }
> > + segs_remaining--;
> > + if (segs_remaining)
> > + __tg3_start_xmit(nskb, tp->dev, segs_remaining);
>
> To clarify passing segs_remaining will make sure the queue is never
> stopped correct ?
It makes sure the queue is not stopped before we are finished submitting
all gso segments.
This is what's alluded to in this part of the commit message:
This puts us in the exceptional situation that a single skb that
triggers tg3_tso_bug() may require the entire tx ring. [...]
Likewise, usually the tx queue is stopped as soon as an skb with
max frags may overrun it. Since the skbs submitted from
tg3_tso_bug() use a controlled number of descriptors, the tx
queue stop threshold may be lowered.
>
> > + else
> > + tg3_start_xmit(nskb, tp->dev);
> > } while (segs);
> >
>
>
^ permalink raw reply
* [PATCH net v3 1/4] tg3: Limit minimum tx queue wakeup threshold
From: Benjamin Poirier @ 2014-08-26 19:26 UTC (permalink / raw)
To: Prashant Sreedharan, Michael Chan; +Cc: netdev, linux-kernel
tx_pending may be set by the user (via ethtool -G) to a low enough value that
TG3_TX_WAKEUP_THRESH becomes smaller than MAX_SKB_FRAGS + 1. This may cause
the tx queue to be waked when there are in fact not enough descriptors to
handle an skb with max frags. This in turn causes tg3_start_xmit() to return
NETDEV_TX_BUSY and print error messages. Fix the problem by putting a limit to
how low TG3_TX_WAKEUP_THRESH can go.
Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
---
I noticed the problem in a 3.0 kernel when setting `ethtool eth0 -G tx 50` and
running a netperf TCP_STREAM test. The console fills up with
[10597.596155] tg3 0000:06:00.0: eth0: BUG! Tx Ring full when queue awake!
The problem in tg3 remains in current kernels though it does not reproduce as
easily since "5640f76 net: use a per task frag allocator (v3.7-rc1)". I
reproduced on current kernels by using the fail_page_alloc fault injection
mechanism to force the creation of skbs with many order-0 frags. Note that the
following script may also trigger another bug (NETDEV WATCHDOG), which is
fixed in the next patch.
$ cat /tmp/doit.sh
F="/sys/kernel/debug/fail_page_alloc"
echo -1 > "$F/times"
echo 0 > "$F/verbose"
echo 0 > "$F/ignore-gfp-wait"
echo 1 > "$F/task-filter"
echo 100 > "$F/probability"
netperf -H 192.168.9.30 -l100 -t omni -- -d send &
n=$!
sleep 0.3
echo 1 > "/proc/$n/make-it-fail"
sleep 10
kill "$n"
---
drivers/net/ethernet/broadcom/tg3.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 3ac5d23..b11c0fd 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -202,7 +202,8 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
#endif
/* minimum number of free TX descriptors required to wake up TX process */
-#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4)
+#define TG3_TX_WAKEUP_THRESH(tnapi) max_t(u32, (tnapi)->tx_pending / 4, \
+ MAX_SKB_FRAGS + 1)
#define TG3_TX_BD_DMA_MAX_2K 2048
#define TG3_TX_BD_DMA_MAX_4K 4096
--
1.8.4.5
^ permalink raw reply related
* [PATCH net v3 2/4] tg3: Fix tx_pending check for MAX_SKB_FRAGS
From: Benjamin Poirier @ 2014-08-26 19:26 UTC (permalink / raw)
To: Prashant Sreedharan, Michael Chan; +Cc: netdev, linux-kernel
In-Reply-To: <1409081178-4877-1-git-send-email-bpoirier@suse.de>
The rest of the driver assumes at least one free descriptor in the tx ring.
Therefore, since an skb with max frags takes up (MAX_SKB_FRAGS + 1)
descriptors, tx_pending must be > (MAX_SKB_FRAGS + 1).
Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
---
Changes v1->v2
Moved ahead in the series from 3/3 to 2/3, no functionnal change
I reproduced this bug using the same approach explained in patch 1.
The bug reproduces with tx_pending = 18
---
drivers/net/ethernet/broadcom/tg3.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index b11c0fd..0cecd6d 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -12319,7 +12319,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
if ((ering->rx_pending > tp->rx_std_ring_mask) ||
(ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) ||
(ering->tx_pending > TG3_TX_RING_SIZE - 1) ||
- (ering->tx_pending <= MAX_SKB_FRAGS) ||
+ (ering->tx_pending <= MAX_SKB_FRAGS + 1) ||
(tg3_flag(tp, TSO_BUG) &&
(ering->tx_pending <= (MAX_SKB_FRAGS * 3))))
return -EINVAL;
--
1.8.4.5
^ permalink raw reply related
* [PATCH net v3 3/4] tg3: Move tx queue stop logic to its own function
From: Benjamin Poirier @ 2014-08-26 19:26 UTC (permalink / raw)
To: Prashant Sreedharan, Michael Chan; +Cc: netdev, linux-kernel
In-Reply-To: <1409081178-4877-1-git-send-email-bpoirier@suse.de>
It is duplicated. Also, the first instance in tg3_start_xmit() is racy.
Consider:
tg3_start_xmit()
if budget <= ...
tg3_tx()
(free up the entire ring)
tx_cons =
smp_mb
if queue_stopped and tx_avail, NO
if !queue_stopped
stop queue
return NETDEV_TX_BUSY
... tx queue stopped forever
Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
---
Changes v2->v3
* new patch to avoid repeatedly open coding this block in the next patch.
---
drivers/net/ethernet/broadcom/tg3.c | 69 ++++++++++++++++++-------------------
1 file changed, 34 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 0cecd6d..5d39554 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -7831,6 +7831,29 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
+static inline bool tg3_maybe_stop_txq(struct tg3_napi *tnapi,
+ struct netdev_queue *txq,
+ u32 stop_thresh, u32 wakeup_thresh)
+{
+ bool stopped = false;
+
+ if (unlikely(tg3_tx_avail(tnapi) <= stop_thresh)) {
+ if (!netif_tx_queue_stopped(txq)) {
+ stopped = true;
+ netif_tx_stop_queue(txq);
+ BUG_ON(wakeup_thresh >= tnapi->tx_pending);
+ }
+ /* netif_tx_stop_queue() must be done before checking tx index
+ * in tg3_tx_avail(), because in tg3_tx(), we update tx index
+ * before checking for netif_tx_queue_stopped().
+ */
+ smp_mb();
+ if (tg3_tx_avail(tnapi) > wakeup_thresh)
+ netif_tx_wake_queue(txq);
+ }
+ return stopped;
+}
+
/* Use GSO to workaround all TSO packets that meet HW bug conditions
* indicated in tg3_tx_frag_set()
*/
@@ -7841,20 +7864,9 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3;
/* Estimate the number of fragments in the worst case */
- if (unlikely(tg3_tx_avail(tnapi) <= frag_cnt_est)) {
- netif_tx_stop_queue(txq);
-
- /* netif_tx_stop_queue() must be done before checking
- * checking tx index in tg3_tx_avail() below, because in
- * tg3_tx(), we update tx index before checking for
- * netif_tx_queue_stopped().
- */
- smp_mb();
- if (tg3_tx_avail(tnapi) <= frag_cnt_est)
- return NETDEV_TX_BUSY;
-
- netif_tx_wake_queue(txq);
- }
+ tg3_maybe_stop_txq(tnapi, txq, frag_cnt_est, frag_cnt_est);
+ if (netif_tx_queue_stopped(txq))
+ return NETDEV_TX_BUSY;
segs = skb_gso_segment(skb, tp->dev->features &
~(NETIF_F_TSO | NETIF_F_TSO6));
@@ -7902,16 +7914,13 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
* interrupt. Furthermore, IRQ processing runs lockless so we have
* no IRQ context deadlocks to worry about either. Rejoice!
*/
- if (unlikely(budget <= (skb_shinfo(skb)->nr_frags + 1))) {
- if (!netif_tx_queue_stopped(txq)) {
- netif_tx_stop_queue(txq);
-
- /* This is a hard error, log it. */
- netdev_err(dev,
- "BUG! Tx Ring full when queue awake!\n");
- }
- return NETDEV_TX_BUSY;
+ if (tg3_maybe_stop_txq(tnapi, txq, skb_shinfo(skb)->nr_frags + 1,
+ TG3_TX_WAKEUP_THRESH(tnapi))) {
+ /* This is a hard error, log it. */
+ netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
}
+ if (netif_tx_queue_stopped(txq))
+ return NETDEV_TX_BUSY;
entry = tnapi->tx_prod;
base_flags = 0;
@@ -8087,18 +8096,8 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
tw32_tx_mbox(tnapi->prodmbox, entry);
tnapi->tx_prod = entry;
- if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
- netif_tx_stop_queue(txq);
-
- /* netif_tx_stop_queue() must be done before checking
- * checking tx index in tg3_tx_avail() below, because in
- * tg3_tx(), we update tx index before checking for
- * netif_tx_queue_stopped().
- */
- smp_mb();
- if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
- netif_tx_wake_queue(txq);
- }
+ tg3_maybe_stop_txq(tnapi, txq, MAX_SKB_FRAGS + 1,
+ TG3_TX_WAKEUP_THRESH(tnapi));
mmiowb();
return NETDEV_TX_OK;
--
1.8.4.5
^ permalink raw reply related
* [PATCH net v3 4/4] tg3: Fix tx_pending checks for tg3_tso_bug
From: Benjamin Poirier @ 2014-08-26 19:26 UTC (permalink / raw)
To: Prashant Sreedharan, Michael Chan; +Cc: netdev, linux-kernel
In-Reply-To: <1409081178-4877-1-git-send-email-bpoirier@suse.de>
In tg3_set_ringparam(), the tx_pending test to cover the cases where
tg3_tso_bug() is entered has two problems
1) the check is only done for certain hardware whereas the workaround
is now used more broadly. IOW, the check may not be performed when it
is needed.
2) the check is too optimistic.
For example, with a 5761 (SHORT_DMA_BUG), tg3_set_ringparam() skips over the
"tx_pending <= (MAX_SKB_FRAGS * 3)" check because TSO_BUG is false. Even if it
did do the check, with a full sized skb, frag_cnt_est = 135 but the check is
for <= MAX_SKB_FRAGS * 3 (= 17 * 3 = 51). So the check is insufficient. This
leads to the following situation: by setting, ex. tx_pending = 100, there can
be an skb that triggers tg3_tso_bug() and that is large enough to cause
tg3_tso_bug() to stop the queue even when it is empty. We then end up with a
netdev watchdog transmit timeout.
Given that 1) some of the conditions tested for in tg3_tx_frag_set() apply
regardless of the chipset flags and that 2) it is difficult to estimate ahead
of time the max possible number of frames that a large skb may be split into
by gso, we instead take the approach of adjusting dev->gso_max_segs according
to the requested tx_pending size.
This puts us in the exceptional situation that a single skb that triggers
tg3_tso_bug() may require the entire tx ring. Usually the tx queue is woken up
when at least a quarter of it is available (TG3_TX_WAKEUP_THRESH) but that
would be insufficient now. To avoid useless wakeups, the tx queue wake up
threshold is made dynamic. Likewise, usually the tx queue is stopped as soon
as an skb with max frags may overrun it. Since the skbs submitted from
tg3_tso_bug() use a controlled number of descriptors, the tx queue stop
threshold may be lowered.
Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
---
Changes v1->v2
* in tg3_set_ringparam(), reduce gso_max_segs further to budget 3 descriptors
per gso seg instead of only 1 as in v1
* in tg3_tso_bug(), check that this estimation (3 desc/seg) holds, otherwise
linearize some skbs as needed
* in tg3_start_xmit(), make the queue stop threshold a parameter, for the
reason explained in the commit description
Changes v2->v3
* use tg3_maybe_stop_txq() instead of repeatedly open coding it
* add the requested tp->tx_dropped++ stat increase in tg3_tso_bug() if
skb_linearize() fails and we must abort
* in the same code block, add an additional check to stop the queue with the
default threshold. Otherwise, the netdev_err message at the start of
__tg3_start_xmit() could be triggered when the next frame is transmitted.
That is because the previous calls to __tg3_start_xmit() in tg3_tso_bug()
may have been using a stop_thresh=segs_remaining that is < MAX_SKB_FRAGS +
1.
For v3, I repeated the same rr latency test I had done for v2. Once again, I
did not measure a significant impact.
* without patches
rr values: 6297.2 6851.71 6928.61 6907.2 6682.71 6808.54 6920.69 6906.56 6890.48 6891.39
sample size: 10
mean: 6808.509
standard deviation: 194.1019
quantiles: 6297.2 6819.332 6890.935 6907.04 6928.61
6800±200
Performance counter stats for 'netperf -H 192.168.9.30 -l60 -T 0,0 -t omni -- -d rr' (10 runs):
480672.401297 task-clock # 8.001 CPUs utilized ( +- 0.01% ) [100.00%]
840,080 context-switches # 0.002 M/sec ( +- 0.88% ) [100.00%]
598 CPU-migrations # 0.000 M/sec ( +- 10.27% ) [100.00%]
552 page-faults # 0.000 M/sec ( +- 81.33% )
275,174,355,207 cycles # 0.572 GHz ( +- 7.02% ) [15.38%]
791,022,327,544 stalled-cycles-frontend # 287.46% frontend cycles idle ( +- 4.74% ) [24.88%]
686,658,715,636 stalled-cycles-backend # 249.54% backend cycles idle ( +- 4.93% ) [34.88%]
114,236,655,920 instructions # 0.42 insns per cycle
# 6.92 stalled cycles per insn ( +- 5.02% ) [44.88%]
25,562,621,872 branches # 53.181 M/sec ( +- 5.23% ) [50.00%]
200,879,548 branch-misses # 0.79% of all branches ( +- 0.85% ) [50.00%]
27,266,292,729 L1-dcache-loads # 56.725 M/sec ( +- 4.94% ) [50.00%]
360,072,063 L1-dcache-load-misses # 1.32% of all L1-dcache hits ( +- 0.39% ) [49.88%]
85,199,150 LLC-loads # 0.177 M/sec ( +- 1.20% ) [40.00%]
27,617 LLC-load-misses # 0.03% of all LL-cache hits ( +- 49.75% ) [ 5.00%]
60.078218016 seconds time elapsed ( +- 0.01% )
* with patches
rr values: 6849.21 6872.63 6848.53 6889.81 6889.85 6873.16 6831.34 6918.74 6878.89 6908.51
sample size: 10
mean: 6876.067
standard deviation: 27.40782
quantiles: 6831.34 6855.065 6876.025 6889.84 6918.74
6880±30
Performance counter stats for 'netperf -H 192.168.9.30 -l60 -T 0,0 -t omni -- -d rr' (10 runs):
480644.699898 task-clock # 8.001 CPUs utilized ( +- 0.00% ) [100.00%]
848,240 context-switches # 0.002 M/sec ( +- 0.13% ) [100.00%]
627 CPU-migrations # 0.000 M/sec ( +- 9.33% ) [100.00%]
417 page-faults # 0.000 M/sec ( +- 75.42% )
286,712,301,611 cycles # 0.597 GHz ( +- 4.51% ) [15.01%]
793,756,649,085 stalled-cycles-frontend # 276.85% frontend cycles idle ( +- 2.74% ) [25.01%]
692,444,350,996 stalled-cycles-backend # 241.51% backend cycles idle ( +- 2.76% ) [35.01%]
116,273,550,243 instructions # 0.41 insns per cycle
# 6.83 stalled cycles per insn ( +- 3.29% ) [45.00%]
26,158,199,645 branches # 54.423 M/sec ( +- 3.63% ) [50.00%]
194,639,162 branch-misses # 0.74% of all branches ( +- 0.82% ) [50.00%]
27,866,571,166 L1-dcache-loads # 57.977 M/sec ( +- 3.43% ) [50.00%]
359,443,756 L1-dcache-load-misses # 1.29% of all L1-dcache hits ( +- 0.62% ) [50.00%]
81,806,786 LLC-loads # 0.170 M/sec ( +- 1.36% ) [40.00%]
9,063 LLC-load-misses # 0.01% of all LL-cache hits ( +- 44.72% ) [ 5.00%]
60.074340899 seconds time elapsed ( +- 0.00% )
I reproduced this bug using the same approach explained in patch 1.
The bug reproduces with tx_pending <= 135
---
drivers/net/ethernet/broadcom/tg3.c | 62 +++++++++++++++++++++++++++++--------
drivers/net/ethernet/broadcom/tg3.h | 1 +
2 files changed, 50 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 5d39554..070acff 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -204,6 +204,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
/* minimum number of free TX descriptors required to wake up TX process */
#define TG3_TX_WAKEUP_THRESH(tnapi) max_t(u32, (tnapi)->tx_pending / 4, \
MAX_SKB_FRAGS + 1)
+/* estimate a certain number of descriptors per gso segment */
+#define TG3_TX_DESC_PER_SEG(seg_nb) ((seg_nb) * 3)
+#define TG3_TX_SEG_PER_DESC(desc_nb) ((desc_nb) / 3)
+
#define TG3_TX_BD_DMA_MAX_2K 2048
#define TG3_TX_BD_DMA_MAX_4K 4096
@@ -6609,10 +6613,10 @@ static void tg3_tx(struct tg3_napi *tnapi)
smp_mb();
if (unlikely(netif_tx_queue_stopped(txq) &&
- (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))) {
+ (tg3_tx_avail(tnapi) > tnapi->wakeup_thresh))) {
__netif_tx_lock(txq, smp_processor_id());
if (netif_tx_queue_stopped(txq) &&
- (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))
+ (tg3_tx_avail(tnapi) > tnapi->wakeup_thresh))
netif_tx_wake_queue(txq);
__netif_tx_unlock(txq);
}
@@ -7830,6 +7834,8 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
}
static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
+static netdev_tx_t __tg3_start_xmit(struct sk_buff *, struct net_device *,
+ u32);
static inline bool tg3_maybe_stop_txq(struct tg3_napi *tnapi,
struct netdev_queue *txq,
@@ -7841,14 +7847,16 @@ static inline bool tg3_maybe_stop_txq(struct tg3_napi *tnapi,
if (!netif_tx_queue_stopped(txq)) {
stopped = true;
netif_tx_stop_queue(txq);
- BUG_ON(wakeup_thresh >= tnapi->tx_pending);
+ tnapi->wakeup_thresh = wakeup_thresh;
+ BUG_ON(tnapi->wakeup_thresh >= tnapi->tx_pending);
}
/* netif_tx_stop_queue() must be done before checking tx index
* in tg3_tx_avail(), because in tg3_tx(), we update tx index
- * before checking for netif_tx_queue_stopped().
+ * before checking for netif_tx_queue_stopped(). The memory
+ * barrier also synchronizes wakeup_thresh changes.
*/
smp_mb();
- if (tg3_tx_avail(tnapi) > wakeup_thresh)
+ if (tg3_tx_avail(tnapi) > tnapi->wakeup_thresh)
netif_tx_wake_queue(txq);
}
return stopped;
@@ -7861,10 +7869,10 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
struct netdev_queue *txq, struct sk_buff *skb)
{
struct sk_buff *segs, *nskb;
- u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3;
+ unsigned int segs_remaining = skb_shinfo(skb)->gso_segs;
+ u32 desc_cnt_est = TG3_TX_DESC_PER_SEG(segs_remaining);
- /* Estimate the number of fragments in the worst case */
- tg3_maybe_stop_txq(tnapi, txq, frag_cnt_est, frag_cnt_est);
+ tg3_maybe_stop_txq(tnapi, txq, desc_cnt_est, desc_cnt_est);
if (netif_tx_queue_stopped(txq))
return NETDEV_TX_BUSY;
@@ -7874,10 +7882,32 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
goto tg3_tso_bug_end;
do {
+ unsigned int desc_cnt = skb_shinfo(segs)->nr_frags + 1;
+
nskb = segs;
segs = segs->next;
nskb->next = NULL;
- tg3_start_xmit(nskb, tp->dev);
+
+ if (tg3_tx_avail(tnapi) <= segs_remaining - 1 + desc_cnt &&
+ skb_linearize(nskb)) {
+ tp->tx_dropped++;
+ nskb->next = segs;
+ segs = nskb;
+ do {
+ nskb = segs->next;
+
+ dev_kfree_skb_any(segs);
+ segs = nskb;
+ } while (segs);
+ tg3_maybe_stop_txq(tnapi, txq, MAX_SKB_FRAGS + 1,
+ TG3_TX_WAKEUP_THRESH(tnapi));
+ goto tg3_tso_bug_end;
+ }
+ segs_remaining--;
+ if (segs_remaining)
+ __tg3_start_xmit(nskb, tp->dev, segs_remaining);
+ else
+ tg3_start_xmit(nskb, tp->dev);
} while (segs);
tg3_tso_bug_end:
@@ -7889,6 +7919,12 @@ tg3_tso_bug_end:
/* hard_start_xmit for all devices */
static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
+ return __tg3_start_xmit(skb, dev, MAX_SKB_FRAGS + 1);
+}
+
+static netdev_tx_t __tg3_start_xmit(struct sk_buff *skb,
+ struct net_device *dev, u32 stop_thresh)
+{
struct tg3 *tp = netdev_priv(dev);
u32 len, entry, base_flags, mss, vlan = 0;
u32 budget;
@@ -8096,7 +8132,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
tw32_tx_mbox(tnapi->prodmbox, entry);
tnapi->tx_prod = entry;
- tg3_maybe_stop_txq(tnapi, txq, MAX_SKB_FRAGS + 1,
+ tg3_maybe_stop_txq(tnapi, txq, stop_thresh,
TG3_TX_WAKEUP_THRESH(tnapi));
mmiowb();
@@ -12318,9 +12354,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
if ((ering->rx_pending > tp->rx_std_ring_mask) ||
(ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) ||
(ering->tx_pending > TG3_TX_RING_SIZE - 1) ||
- (ering->tx_pending <= MAX_SKB_FRAGS + 1) ||
- (tg3_flag(tp, TSO_BUG) &&
- (ering->tx_pending <= (MAX_SKB_FRAGS * 3))))
+ (ering->tx_pending <= MAX_SKB_FRAGS + 1))
return -EINVAL;
if (netif_running(dev)) {
@@ -12340,6 +12374,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
if (tg3_flag(tp, JUMBO_RING_ENABLE))
tp->rx_jumbo_pending = ering->rx_jumbo_pending;
+ dev->gso_max_segs = TG3_TX_SEG_PER_DESC(ering->tx_pending - 1);
for (i = 0; i < tp->irq_max; i++)
tp->napi[i].tx_pending = ering->tx_pending;
@@ -17816,6 +17851,7 @@ static int tg3_init_one(struct pci_dev *pdev,
else
sndmbx += 0xc;
}
+ dev->gso_max_segs = TG3_TX_SEG_PER_DESC(TG3_DEF_TX_RING_PENDING - 1);
tg3_init_coal(tp);
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 461acca..6a7e13d 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -3006,6 +3006,7 @@ struct tg3_napi {
u32 tx_pending;
u32 last_tx_cons;
u32 prodmbox;
+ u32 wakeup_thresh;
struct tg3_tx_buffer_desc *tx_ring;
struct tg3_tx_ring_info *tx_buffers;
--
1.8.4.5
^ permalink raw reply related
* [PATCH net-next 0/4] Broadcom BCM7xxx PHY updates for new entries
From: Florian Fainelli @ 2014-08-26 20:04 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
Hi David,
Another week, another set of updates for the Broadcom BCM7xxx PHY driver. This
patch set cleanups the existing definitions, adds a macro to ease the addition
of future chips, and finally add two new SoCs to the list of supported chips.
Thanks!
Florian Fainelli (4):
net: phy: bcm7xxx: introduce BCM7XXX_28NM_GPHY macro
net: phy: broadcom: fix PHY_BCM_OUI_4
net: phy: broadcom: add new Broadcom OUI
net: phy: bcm7xxx: add BCM7250 and BCM7364 PHY entries
drivers/net/phy/bcm7xxx.c | 58 ++++++++++++++++++-----------------------------
include/linux/brcmphy.h | 6 +++--
2 files changed, 26 insertions(+), 38 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH net-next 0/4] Broadcom BCM7xxx PHY updates for new entries
From: Florian Fainelli @ 2014-08-26 20:05 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
Hi David,
Another week, another set of updates for the Broadcom BCM7xxx PHY driver. This
patch set cleanups the existing definitions, adds a macro to ease the addition
of future chips, and finally add two new SoCs to the list of supported chips.
Thanks!
Florian Fainelli (4):
net: phy: bcm7xxx: introduce BCM7XXX_28NM_GPHY macro
net: phy: broadcom: fix PHY_BCM_OUI_4
net: phy: broadcom: add new Broadcom OUI
net: phy: bcm7xxx: add BCM7250 and BCM7364 PHY entries
drivers/net/phy/bcm7xxx.c | 58 ++++++++++++++++++-----------------------------
include/linux/brcmphy.h | 6 +++--
2 files changed, 26 insertions(+), 38 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH net-next 2/4] net: phy: broadcom: fix PHY_BCM_OUI_4
From: Florian Fainelli @ 2014-08-26 20:05 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <1409083510-29511-1-git-send-email-f.fainelli@gmail.com>
PHY_BCM_OUI_4 is missing two significant digits that actually make it an
OUI, add those missing bits so it becomes usable again for matching.
Fixes: b560a58c45c6 ("net: phy: add Broadcom BCM7xxx internal PHY driver")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
include/linux/brcmphy.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index ee1431d976fa..921f17ca4c26 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -21,7 +21,7 @@
#define PHY_BCM_OUI_1 0x00206000
#define PHY_BCM_OUI_2 0x0143bc00
#define PHY_BCM_OUI_3 0x03625c00
-#define PHY_BCM_OUI_4 0x600d0000
+#define PHY_BCM_OUI_4 0x600d8400
#define PHY_BCM_OUI_5 0x03625e00
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 3/4] net: phy: broadcom: add new Broadcom OUI
From: Florian Fainelli @ 2014-08-26 20:05 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <1409083510-29511-1-git-send-email-f.fainelli@gmail.com>
Broadcom started to use a new OUI for its 2013 and newer products:
D4-01-29 which translates into 0xae025000 for a 32-bits OUI, add its
definition.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
include/linux/brcmphy.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 921f17ca4c26..cbcfad36d4c0 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -23,7 +23,7 @@
#define PHY_BCM_OUI_3 0x03625c00
#define PHY_BCM_OUI_4 0x600d8400
#define PHY_BCM_OUI_5 0x03625e00
-
+#define PHY_BCM_OUI_6 0xae025000
#define PHY_BCM_FLAGS_MODE_COPPER 0x00000001
#define PHY_BCM_FLAGS_MODE_1000BX 0x00000002
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 4/4] net: phy: bcm7xxx: add BCM7250 and BCM7364 PHY entries
From: Florian Fainelli @ 2014-08-26 20:05 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <1409083510-29511-1-git-send-email-f.fainelli@gmail.com>
Add two new entries to the Broadcom BCM7xxx internal PHY driver for
BCM7250 and BCM7364 chips. Those chips share the usual 28nm process
Gigabit PHY sequence and require the same workarounds so far.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/bcm7xxx.c | 4 ++++
include/linux/brcmphy.h | 2 ++
2 files changed, 6 insertions(+)
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index 948c7086679a..09dd6e1dc6e1 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -335,6 +335,8 @@ static int bcm7xxx_dummy_config_init(struct phy_device *phydev)
}
static struct phy_driver bcm7xxx_driver[] = {
+ BCM7XXX_28NM_GPHY(PHY_ID_BCM7250, "Broadcom BCM7250"),
+ BCM7XXX_28NM_GPHY(PHY_ID_BCM7364, "Broadcom BCM7364"),
BCM7XXX_28NM_GPHY(PHY_ID_BCM7366, "Broadcom BCM7366"),
BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"),
BCM7XXX_28NM_GPHY(PHY_ID_BCM7445, "Broadcom BCM7445"),
@@ -367,6 +369,8 @@ static struct phy_driver bcm7xxx_driver[] = {
} };
static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
+ { PHY_ID_BCM7250, 0xfffffff0, },
+ { PHY_ID_BCM7364, 0xfffffff0, },
{ PHY_ID_BCM7366, 0xfffffff0, },
{ PHY_ID_BCM7439, 0xfffffff0, },
{ PHY_ID_BCM7445, 0xfffffff0, },
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index cbcfad36d4c0..5bd35cc0d471 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -13,6 +13,8 @@
#define PHY_ID_BCM5461 0x002060c0
#define PHY_ID_BCM57780 0x03625d90
+#define PHY_ID_BCM7250 0xae025280
+#define PHY_ID_BCM7364 0xae025260
#define PHY_ID_BCM7366 0x600d8490
#define PHY_ID_BCM7439 0x600d8480
#define PHY_ID_BCM7445 0x600d8510
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 0/4 RESEND] Broadcom BCM7xxx PHY updates for new entries
From: Florian Fainelli @ 2014-08-26 20:10 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
Hi David,
Another week, another set of updates for the Broadcom BCM7xxx PHY driver. This
patch set cleanups the existing definitions, adds a macro to ease the addition
of future chips, and finally add two new SoCs to the list of supported chips.
Resending since the first patch did not make it to the list, sorry about that.
Thanks!
Florian Fainelli (4):
net: phy: bcm7xxx: introduce BCM7XXX_28NM_GPHY macro
net: phy: broadcom: fix PHY_BCM_OUI_4
net: phy: broadcom: add new Broadcom OUI
net: phy: bcm7xxx: add BCM7250 and BCM7364 PHY entries
drivers/net/phy/bcm7xxx.c | 58 ++++++++++++++++++-----------------------------
include/linux/brcmphy.h | 6 +++--
2 files changed, 26 insertions(+), 38 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH net-next 2/4 RESEND] net: phy: broadcom: fix PHY_BCM_OUI_4
From: Florian Fainelli @ 2014-08-26 20:10 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <1409083851-29690-1-git-send-email-f.fainelli@gmail.com>
PHY_BCM_OUI_4 is missing two significant digits that actually make it an
OUI, add those missing bits so it becomes usable again for matching.
Fixes: b560a58c45c6 ("net: phy: add Broadcom BCM7xxx internal PHY driver")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
include/linux/brcmphy.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index ee1431d976fa..921f17ca4c26 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -21,7 +21,7 @@
#define PHY_BCM_OUI_1 0x00206000
#define PHY_BCM_OUI_2 0x0143bc00
#define PHY_BCM_OUI_3 0x03625c00
-#define PHY_BCM_OUI_4 0x600d0000
+#define PHY_BCM_OUI_4 0x600d8400
#define PHY_BCM_OUI_5 0x03625e00
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 3/4 RESEND] net: phy: broadcom: add new Broadcom OUI
From: Florian Fainelli @ 2014-08-26 20:10 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <1409083851-29690-1-git-send-email-f.fainelli@gmail.com>
Broadcom started to use a new OUI for its 2013 and newer products:
D4-01-29 which translates into 0xae025000 for a 32-bits OUI, add its
definition.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
include/linux/brcmphy.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 921f17ca4c26..cbcfad36d4c0 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -23,7 +23,7 @@
#define PHY_BCM_OUI_3 0x03625c00
#define PHY_BCM_OUI_4 0x600d8400
#define PHY_BCM_OUI_5 0x03625e00
-
+#define PHY_BCM_OUI_6 0xae025000
#define PHY_BCM_FLAGS_MODE_COPPER 0x00000001
#define PHY_BCM_FLAGS_MODE_1000BX 0x00000002
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 4/4 RESEND] net: phy: bcm7xxx: add BCM7250 and BCM7364 PHY entries
From: Florian Fainelli @ 2014-08-26 20:10 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <1409083851-29690-1-git-send-email-f.fainelli@gmail.com>
Add two new entries to the Broadcom BCM7xxx internal PHY driver for
BCM7250 and BCM7364 chips. Those chips share the usual 28nm process
Gigabit PHY sequence and require the same workarounds so far.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/bcm7xxx.c | 4 ++++
include/linux/brcmphy.h | 2 ++
2 files changed, 6 insertions(+)
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index 948c7086679a..09dd6e1dc6e1 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -335,6 +335,8 @@ static int bcm7xxx_dummy_config_init(struct phy_device *phydev)
}
static struct phy_driver bcm7xxx_driver[] = {
+ BCM7XXX_28NM_GPHY(PHY_ID_BCM7250, "Broadcom BCM7250"),
+ BCM7XXX_28NM_GPHY(PHY_ID_BCM7364, "Broadcom BCM7364"),
BCM7XXX_28NM_GPHY(PHY_ID_BCM7366, "Broadcom BCM7366"),
BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"),
BCM7XXX_28NM_GPHY(PHY_ID_BCM7445, "Broadcom BCM7445"),
@@ -367,6 +369,8 @@ static struct phy_driver bcm7xxx_driver[] = {
} };
static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
+ { PHY_ID_BCM7250, 0xfffffff0, },
+ { PHY_ID_BCM7364, 0xfffffff0, },
{ PHY_ID_BCM7366, 0xfffffff0, },
{ PHY_ID_BCM7439, 0xfffffff0, },
{ PHY_ID_BCM7445, 0xfffffff0, },
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index cbcfad36d4c0..5bd35cc0d471 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -13,6 +13,8 @@
#define PHY_ID_BCM5461 0x002060c0
#define PHY_ID_BCM57780 0x03625d90
+#define PHY_ID_BCM7250 0xae025280
+#define PHY_ID_BCM7364 0xae025260
#define PHY_ID_BCM7366 0x600d8490
#define PHY_ID_BCM7439 0x600d8480
#define PHY_ID_BCM7445 0x600d8510
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox