* Re: [PATCH RESEND net-next] docs: net: Convert tcp.txt to RST format
From: Tobin C. Harding @ 2018-09-11 22:25 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S. Miller, Eric Dumazet, netdev, linux-doc, linux-kernel
In-Reply-To: <7f50abcd-f2fa-c043-9e5b-8e5ca89c52a1@gmail.com>
On Tue, Sep 11, 2018 at 03:30:19AM -0700, Eric Dumazet wrote:
>
>
> On 09/11/2018 12:13 AM, Tobin C. Harding wrote:
> > Restructured text is the kernel documentation format of choice now.
> > Some text from tcp.txt is out of date, specifically the function
> > tcp_write() does not appear to be in the tree anymore. Also the
> > following data members have been removed
> >
> > sk->tcp_pend_event
> > sk->transmit_queue
> > sk->transmit_new
> > sk->transmit_end
> > sk->tcp_last_tx_ack
> > sk->tcp_dup_ack
> >
> > Remove section 'How the new TCP output machine [nyi] works'. This
> > leaves only a single section so we can name the document with that
> > section heading now.
> >
> > Convert tcp.txt to RST format. Add GPLv2 SPDX tag.
> >
> > Signed-off-by: Tobin C. Harding <me@tobin.cc>
> >
>
> I dunno, this 'doc' is probably useless and should be deleted.
Cool! The best type of patch - line removal only. I'll put it in.
thanks,
Tobin.
^ permalink raw reply
* Re: [PATCH net-next v3 02/17] zinc: introduce minimal cryptography library
From: Andy Lutomirski @ 2018-09-11 22:16 UTC (permalink / raw)
To: Eric Biggers
Cc: Greg Kroah-Hartman, Ard Biesheuvel, Jason A. Donenfeld,
Linux Kernel Mailing List, <netdev@vger.kernel.org>,
David S. Miller, Andy Lutomirski, Samuel Neves,
Jean-Philippe Aumasson,
open list:HARDWARE RANDOM NUMBER GENERATOR CORE
In-Reply-To: <20180911214737.GA81235@gmail.com>
> On Sep 11, 2018, at 2:47 PM, Eric Biggers <ebiggers@kernel.org> wrote:
>
>> On Tue, Sep 11, 2018 at 04:56:24PM +0200, Greg Kroah-Hartman wrote:
>> On Tue, Sep 11, 2018 at 12:08:56PM +0200, Ard Biesheuvel wrote:
>>>> As Zinc is simply library code, its config options are un-menued, with
>>>> the exception of CONFIG_ZINC_DEBUG, which enables various selftests and
>>>> BUG_ONs.
>>>>
>>>
>>> In spite of the wall of text, you fail to point out exactly why the
>>> existing AEAD API in unsuitable, and why fixing it is not an option.
>>>
>>> As I pointed out in a previous version, I don't think we need a
>>> separate crypto API/library in the kernel, and I don't think you have
>>> convinced anyone else yet either.
>>
>> Um, then why do people keep sprinkling new crypto/hash code all around
>> the kernel tree? It's because what we have as a crypto api is complex
>> and is hard to use for many in-kernel users.
>>
>> Something like this new interface (zinc) is a much "saner" api for
>> writing kernel code that has to interact with crypto/hash primitives.
>>
>> I see no reason why the existing crypto code can be redone to use the
>> zinc crypto primitives over time, making there only be one main location
>> for the crypto algorithms. But to do it the other way around is pretty
>> much impossible given the complexities in the existing api that has been
>> created over time.
>>
>> Not to say that the existing api is not a viable one, but ugh, really?
>> You have to admit it is a pain to try to use in any "normal" type of
>> "here's a bytestream, go give me a hash" type of method, right?
>>
>> Also there is the added benefit that the crypto primitives here have
>> been audited by a number of people (so Jason stated), and they are
>> written in a way that the crypto community can more easily interact and
>> contribute to. Which is _way_ better than what we have today.
>>
>> So this gets my "stamp of approval" for whatever it is worth :)
>>
>
> I think you mean you see no reason why it *cannot* be converted? The
> conversions definitely *should* be done, just like how some of the existing
> crypto API algorithms like SHA-256 already wrap implementations in lib/. In my
> view, lib/zinc/ isn't fundamentally different from what we already have for some
> algorithms. So it's misguided to design/present it as some novel thing, which
> unfortunately this patchset still does to a large extent. (The actual new thing
> is how architecture-specific implementations are handled.)
>
> Of course, the real problem is that even after multiple revisions of this
> patchset, there's still no actual conversions of the existing crypto API
> algorithms over to use the new implementations. "Zinc" is still completely
> separate from the existing crypto API.
>
Jason, can you do one of these conversions as an example?
> So, it's not yet clear that the conversions will actually work out without
> problems that would require changes in "Zinc". I don't think it makes sense to
> merge all this stuff without doing the conversions, or at the very least
> demonstrating how they will be done.
>
> In particular, in its current form "Zinc" is useless for anyone that needs the
> existing crypto API. For example, for HPolyC,
> (https://lkml.org/lkml/2018/8/6/857), I need to make improvements to ChaCha and
> Poly1305 in the existing crypto API, e.g. to add support for XChaCha and
> NEON-accelerated Poly1305. Having completely separate ChaCha and Poly1305
> implementations in Zinc doesn't help at all. If anything, it makes things
> harder because people will have to review/maintain both sets of implementations;
> and when trying to make the improvements I need, I'll find myself in the middle
> of a holy war between two competing camps who each have their own opinion about
> The Right Way To Do Crypto, and their own crypto implementations and APIs in the
> kernel.
>
> - Eric
^ permalink raw reply
* Re: tools/bpf regression causing samples/bpf/ to hang
From: Björn Töpel @ 2018-09-11 17:15 UTC (permalink / raw)
To: yhs; +Cc: Netdev, ast, Daniel Borkmann, Jesper Dangaard Brouer
In-Reply-To: <f17b2896-6191-b929-593e-20ae090d4d56@fb.com>
Den tis 11 sep. 2018 kl 18:47 skrev Yonghong Song <yhs@fb.com>:
>
>
>
> On 9/11/18 4:11 AM, Björn Töpel wrote:
> > Hi Yonghong, I tried to run the XDP samples from the bpf-next tip
> > today, and was hit by a regression.
> >
> > Commit f7010770fbac ("tools/bpf: move bpf/lib netlink related
> > functions into a new file") adds a while(1) around the recv call in
> > bpf_set_link_xdp_fd making that call getting stuck in an infinite
> > loop.
> >
> > I simply removed the loop, and that solved my problem (patch below).
> >
> > However, I don't know if removing the loop would break bpftool for
> > you. If not, I can submit the patch as a proper one for bpf-next.
>
> Hi, Björn, thanks for reporting the problem.
> The while loop is needed since the "recv" syscall buffer size
> may not be big enough to hold all the returned information, in
> which cases, multiple "recv" calls are needed.
>
> Could you try the following patch to see whether it fixed your
> issue? Thanks!
>
Nope, it doesn't -- but if you move that hunk after the for-loop it works.
Cheers,
Björn
> commit 3eb1c0249dfc3ea4ad61aa223dce32262af7e049 (HEAD -> fix)
> Author: Yonghong Song <yhs@fb.com>
> Date: Tue Sep 11 08:58:20 2018 -0700
>
> tools/bpf: fix a netlink recv issue
>
> Commit f7010770fbac ("tools/bpf: move bpf/lib netlink related
> functions into a new file") introduced a while loop for the
> netlink recv path. This while loop is needed since the
> buffer in recv syscall may not be big enough to hold all the
> information and in such cases multiple recv calls are needed.
>
> When netlink recv returns message length of 0, there will be
> no more messages for returning data so the while loop
> can end.
>
> Fixes: f7010770fbac ("tools/bpf: move bpf/lib netlink related
> functions into a new file")
> Reported-by: Björn Töpel <bjorn.topel@intel.com>
> Signed-off-by: Yonghong Song <yhs@fb.com>
>
> diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
> index 469e068dd0c5..37827319a50a 100644
> --- a/tools/lib/bpf/netlink.c
> +++ b/tools/lib/bpf/netlink.c
> @@ -77,6 +77,9 @@ static int bpf_netlink_recv(int sock, __u32 nl_pid,
> int seq,
> goto done;
> }
>
> + if (len == 0)
> + break;
> +
> for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
> nh = NLMSG_NEXT(nh, len)) {
> if (nh->nlmsg_pid != nl_pid) {
>
>
> >
> > Thanks!
> > Björn
> >
> > From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= <bjorn.topel@intel.com>
> > Date: Tue, 11 Sep 2018 12:35:44 +0200
> > Subject: [PATCH] tools/bpf: remove loop around netlink recv
> >
> > Commit f7010770fbac ("tools/bpf: move bpf/lib netlink related
> > functions into a new file") moved the bpf_set_link_xdp_fd and split it
> > up into multiple functions. The added receive function
> > bpf_netlink_recv added a loop around the recv syscall leading to
> > multiple recv calls. This resulted in all XDP samples in the
> > samples/bpf/ to stop working, since they were stuck in a blocking
> > recv.
> >
> > This commits removes the while (1)-statement.
> >
> > Fixes: f7010770fbac ("tools/bpf: move bpf/lib netlink related
> > functions into a new file")
> > Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
> > ---
> > tools/lib/bpf/netlink.c | 64 ++++++++++++++++++++---------------------
> > 1 file changed, 31 insertions(+), 33 deletions(-)
> >
> > diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
> > index 469e068dd0c5..0eae1fbf46c6 100644
> > --- a/tools/lib/bpf/netlink.c
> > +++ b/tools/lib/bpf/netlink.c
> > @@ -70,41 +70,39 @@ static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq,
> > char buf[4096];
> > int len, ret;
> >
> > - while (1) {
> > - len = recv(sock, buf, sizeof(buf), 0);
> > - if (len < 0) {
> > - ret = -errno;
> > + len = recv(sock, buf, sizeof(buf), 0);
> > + if (len < 0) {
> > + ret = -errno;
> > + goto done;
> > + }
> > +
> > + for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
> > + nh = NLMSG_NEXT(nh, len)) {
> > + if (nh->nlmsg_pid != nl_pid) {
> > + ret = -LIBBPF_ERRNO__WRNGPID;
> > goto done;
> > }
> > -
> > - for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
> > - nh = NLMSG_NEXT(nh, len)) {
> > - if (nh->nlmsg_pid != nl_pid) {
> > - ret = -LIBBPF_ERRNO__WRNGPID;
> > - goto done;
> > - }
> > - if (nh->nlmsg_seq != seq) {
> > - ret = -LIBBPF_ERRNO__INVSEQ;
> > - goto done;
> > - }
> > - switch (nh->nlmsg_type) {
> > - case NLMSG_ERROR:
> > - err = (struct nlmsgerr *)NLMSG_DATA(nh);
> > - if (!err->error)
> > - continue;
> > - ret = err->error;
> > - nla_dump_errormsg(nh);
> > - goto done;
> > - case NLMSG_DONE:
> > - return 0;
> > - default:
> > - break;
> > - }
> > - if (_fn) {
> > - ret = _fn(nh, fn, cookie);
> > - if (ret)
> > - return ret;
> > - }
> > + if (nh->nlmsg_seq != seq) {
> > + ret = -LIBBPF_ERRNO__INVSEQ;
> > + goto done;
> > + }
> > + switch (nh->nlmsg_type) {
> > + case NLMSG_ERROR:
> > + err = (struct nlmsgerr *)NLMSG_DATA(nh);
> > + if (!err->error)
> > + continue;
> > + ret = err->error;
> > + nla_dump_errormsg(nh);
> > + goto done;
> > + case NLMSG_DONE:
> > + return 0;
> > + default:
> > + break;
> > + }
> > + if (_fn) {
> > + ret = _fn(nh, fn, cookie);
> > + if (ret)
> > + return ret;
> > }
> > }
> > ret = 0;
> >
^ permalink raw reply
* Re: [PATCH] net/core/filter: fix unused-variable warning
From: Alexei Starovoitov @ 2018-09-11 22:13 UTC (permalink / raw)
To: Anders Roxell; +Cc: davem, ast, daniel, tehnerd, netdev, linux-kernel
In-Reply-To: <20180907125005.32383-1-anders.roxell@linaro.org>
On Fri, Sep 07, 2018 at 02:50:05PM +0200, Anders Roxell wrote:
> Building with CONFIG_INET=n will show the warning below:
> net/core/filter.c: In function ‘____bpf_getsockopt’:
> net/core/filter.c:4048:19: warning: unused variable ‘tp’ [-Wunused-variable]
> struct tcp_sock *tp;
> ^~
> net/core/filter.c:4046:31: warning: unused variable ‘icsk’ [-Wunused-variable]
> struct inet_connection_sock *icsk;
> ^~~~
> Move the variable declarations inside the {} block where they are used.
>
> Fixes: 1e215300f138 ("bpf: add TCP_SAVE_SYN/TCP_SAVED_SYN options for bpf_(set|get)sockopt")
> Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
> ---
> net/core/filter.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/core/filter.c b/net/core/filter.c
> index d301134bca3a..0ae7185b2207 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -4043,14 +4043,14 @@ static const struct bpf_func_proto bpf_setsockopt_proto = {
> BPF_CALL_5(bpf_getsockopt, struct bpf_sock_ops_kern *, bpf_sock,
> int, level, int, optname, char *, optval, int, optlen)
> {
> - struct inet_connection_sock *icsk;
> struct sock *sk = bpf_sock->sk;
> - struct tcp_sock *tp;
>
> if (!sk_fullsock(sk))
> goto err_clear;
> #ifdef CONFIG_INET
> if (level == SOL_TCP && sk->sk_prot->getsockopt == tcp_getsockopt) {
> + struct inet_connection_sock *icsk;
> + struct tcp_sock *tp;
> switch (optname) {
I've added empty line after variable decl and applied.
^ permalink raw reply
* Re: [PATCH net-next v3 02/17] zinc: introduce minimal cryptography library
From: Eric Biggers @ 2018-09-11 22:08 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Jason A. Donenfeld, Linux Kernel Mailing List,
<netdev@vger.kernel.org>, David S. Miller,
Greg Kroah-Hartman, Andy Lutomirski, Samuel Neves,
Jean-Philippe Aumasson,
open list:HARDWARE RANDOM NUMBER GENERATOR CORE
In-Reply-To: <CAKv+Gu9nSeo4PFVrtjtqGQ32eqyxUp3xVCczZfu+dhFz5yLM0A@mail.gmail.com>
On Tue, Sep 11, 2018 at 12:08:56PM +0200, Ard Biesheuvel wrote:
>
> I won't go into the 1000s lines of generated assembly again - you
> already know my position on that topic.
>
I'd strongly prefer the assembly to be readable too. Jason, I'm not sure if
you've actually read through the asm from the OpenSSL implementations, but the
generated .S files actually do lose a lot of semantic information that was in
the original .pl scripts. For example, in the Poly1305 NEON implementation
which I'm especially interested in (but you could check any of the other
generated files too), the original .pl script has register aliases showing the
meaning of each register. Just grabbing a random hunk:
vshr.u64 $T0,$D3,#26
vmovn.i64 $D3#lo,$D3
vshr.u64 $T1,$D0,#26
vmovn.i64 $D0#lo,$D0
vadd.i64 $D4,$D4,$T0 @ h3 -> h4
vbic.i32 $D3#lo,#0xfc000000
vsri.u32 $H4,$H3,#8 @ base 2^32 -> base 2^26
vadd.i64 $D1,$D1,$T1 @ h0 -> h1
vshl.u32 $H3,$H3,#18
vbic.i32 $D0#lo,#0xfc000000
(Yes, it's still not *that* readable, but D0-D4 and H0-H4 map directly to d0-d4
and h0-h4 in the C implementation. So someone familiar with Poly1305
implementations can figure it out.)
In contrast, the generated .S file just has the raw registers. It's difficult
to remember what each register is used for. In fact, someone who actually
wanted to figure it out would probably find themselves referring to the .pl
script -- which raises the question of why the .S file is the "source" and not
the .pl script...
vshr.u64 q15,q8,#26
vmovn.i64 d16,q8
vshr.u64 q4,q5,#26
vmovn.i64 d10,q5
vadd.i64 q9,q9,q15 @ h3 -> h4
vbic.i32 d16,#0xfc000000
vsri.u32 q14,q13,#8 @ base 2^32 -> base 2^26
vadd.i64 q6,q6,q4 @ h0 -> h1
vshl.u32 q13,q13,#18
vbic.i32 d10,#0xfc000000
- Eric
^ permalink raw reply
* Re: [PATCH net-next v3 05/17] zinc: ChaCha20 x86_64 implementation
From: Jason A. Donenfeld @ 2018-09-11 22:04 UTC (permalink / raw)
To: Eric Biggers
Cc: Thomas Gleixner, Samuel Neves, LKML, Netdev, David Miller,
Greg Kroah-Hartman, Andrew Lutomirski, Jean-Philippe Aumasson,
Andy Polyakov, mingo, X86 ML, Linux Crypto Mailing List
In-Reply-To: <20180911214837.GB81235@gmail.com>
On Tue, Sep 11, 2018 at 3:48 PM Eric Biggers <ebiggers@kernel.org> wrote:
> Please Cc linux-crypto on the whole patch series, including the cover letter.
Ack.
^ permalink raw reply
* Re: [PATCH net-next v3 02/17] zinc: introduce minimal cryptography library
From: Jason A. Donenfeld @ 2018-09-11 22:02 UTC (permalink / raw)
To: Eric Biggers
Cc: Greg Kroah-Hartman, Ard Biesheuvel, LKML, Netdev, David Miller,
Andrew Lutomirski, Samuel Neves, Jean-Philippe Aumasson,
Linux Crypto Mailing List
In-Reply-To: <20180911214737.GA81235@gmail.com>
On Tue, Sep 11, 2018 at 3:47 PM Eric Biggers <ebiggers@kernel.org> wrote:
> Of course, the real problem is that even after multiple revisions of this
> patchset, there's still no actual conversions of the existing crypto API
> algorithms over to use the new implementations. "Zinc" is still completely
> separate from the existing crypto API.
No this is not, "the real problem [...] after multiple revisions"
because I've offered to do this and stated pretty clearly my intent to
do so. But, as I've mentioned before, I'd really prefer to land this
series through net-next, and then after we can turn our attention to
integrating this into the existing crypto API. This series is already
big enough and I would really prefer not to further complicate it.
So, what you want is going to happen. There isn't some kind of
fundamental problem here. This is more of a discussion on
scheduling/trees/mergecycles than anything else.
^ permalink raw reply
* Re: [RFC] managing PHY carrier from user space
From: Florian Fainelli @ 2018-09-11 16:56 UTC (permalink / raw)
To: Joakim Tjernlund, netdev@vger.kernel.org, andrew@lunn.ch
In-Reply-To: <2fcf4c20a9adf410db98706f6f2508e46aade2c1.camel@infinera.com>
On 09/11/2018 09:41 AM, Joakim Tjernlund wrote:
> I am looking for a way to induce carrier state from user space, primarily
> for Fixed PHYs as these are always up. ifplugd/dhcp etc. does not behave properly
> if the link is up when it really isn't.
Was my suggestion in my email to you somehow not working? This is
obviously not acceptable for upstream, there is no reason, even for a
fixed PHY, to attempt to mangle with the carrier state for any
reasonable production purposes.
>
> I came up with a new 'phy_carrier' attribute in /sys/class/net/eth0/phydev
> where I can induce carrier state:
>
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index a1e7ea4d4b16..f82beeabdd75 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -612,10 +612,39 @@ phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
> }
> static DEVICE_ATTR_RO(phy_has_fixups);
>
> +static ssize_t
> +phy_carrier_show(struct device *dev, struct device_attribute *attr,
> + char *buf)
> +{
> + struct phy_device *phydev = to_phy_device(dev);
> + struct net_device *netdev = phydev->attached_dev;
> +
> + return sprintf(buf, "%d\n", netif_carrier_ok(netdev));
> +}
> +
> +static ssize_t phy_carrier_store(struct device *dev, struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + struct phy_device *phydev = to_phy_device(dev);
> + struct net_device *netdev = phydev->attached_dev;
> + bool enable;
> +
> + if (strtobool(buf, &enable))
> + return -EINVAL;
> +
> + if (enable)
> + netif_carrier_on(netdev);
> + else
> + netif_carrier_off(netdev);
> + return len;
> +}
> +static DEVICE_ATTR_RW(phy_carrier);
> +
> static struct attribute *phy_dev_attrs[] = {
> &dev_attr_phy_id.attr,
> &dev_attr_phy_interface.attr,
> &dev_attr_phy_has_fixups.attr,
> + &dev_attr_phy_carrier.attr,
> NULL,
> };
> ATTRIBUTE_GROUPS(phy_dev);
>
> I would like to know if this acceptable for linux proper or if there is
> a better way to do this?
>
> Jocke
>
--
Florian
^ permalink raw reply
* Editing 4
From: Aaron @ 2018-09-11 6:12 UTC (permalink / raw)
To: netdev
Hi,
If you have photos for editing, please send email to: hansrekan@outlook.com
We have 12 in house image editors and we can help you for cutting out your
photos, or path the photos.
Includes retouching if needed.
Used for products photos or portrait photos, catalog photos.
You may drop us one photo, we can send you the testing work.
Thanks,
Aaron Williams
Email: hansrekan@outlook.com
^ permalink raw reply
* Editing 4
From: Aaron @ 2018-09-11 6:22 UTC (permalink / raw)
To: netdev
Hi,
If you have photos for editing, please send email to: hansrekan@outlook.com
We have 12 in house image editors and we can help you for cutting out your
photos, or path the photos.
Includes retouching if needed.
Used for products photos or portrait photos, catalog photos.
You may drop us one photo, we can send you the testing work.
Thanks,
Aaron Williams
Email: hansrekan@outlook.com
^ permalink raw reply
* Re: [PATCH net-next v3 17/17] net: WireGuard secure network tunnel
From: Andrew Lunn @ 2018-09-11 21:55 UTC (permalink / raw)
To: Jason A. Donenfeld; +Cc: LKML, Netdev, David Miller, Greg Kroah-Hartman
In-Reply-To: <CAHmME9pwVSeE=4aUD6RKLjE+DrHY1=3OtBS7sAvdR66gaNhNtA@mail.gmail.com>
> Most uses of inline are this way after checking the compiler output on
> several platforms. (Generally my build-run-test cycle is actually
> build-IDAPro-run-test.) If you feel that's been done too liberally,
> I'm happy to spend time rechecking each use case.
Hi Jason
I really expect DaveM is going to come along and tell you to remove
them all.
You need a strong argument that they are needed, since this goes
against the general consensus in the kernel, that the compiler is
better at this than humans.
Andrew
^ permalink raw reply
* Re: kernels > v4.12 oops/crash with ipsec-traffic: bisected to b838d5e1c5b6e57b10ec8af2268824041e3ea911: ipv4: mark DST_NOGC and remove the operation of dst_free()
From: Wolfgang Walter @ 2018-09-11 16:53 UTC (permalink / raw)
To: Steffen Klassert
Cc: Kristian Evensen, Network Development, weiwan, Tobias Hommel,
edumazet
In-Reply-To: <20180911103334.GY23674@gauss3.secunet.de>
Am Dienstag, 11. September 2018, 12:33:34 schrieb Steffen Klassert:
> On Mon, Sep 10, 2018 at 10:18:47AM +0200, Kristian Evensen wrote:
> > Hi,
> >
> > Thanks everyone for all the effort in debugging this issue.
> >
> > On Mon, Sep 10, 2018 at 8:39 AM Steffen Klassert
> >
> > <steffen.klassert@secunet.com> wrote:
> > > The easy fix that could be backported to stable would be
> > > to check skb->dst for NULL and drop the packet in that case.
> >
> > Thought I should just chime in and say that we deployed this
> > work-around when we started observing the error back in June. Since
> > then we have not seen any crashes. Also, we have instrumented some of
> > our kernels to count the number of times the error is hit (overall +
> > consecutive). Compared to the overall number of packets, the error
> > happens very rarely. With our workloads, we on average see the error
> > once every couple of days.
>
> Thanks for letting us know!
>
> I plan to fix this in the ipsec tree with:
>
> Subject: [PATCH RFC] xfrm: Fix NULL pointer dereference when skb_dst_force
> clears the dst_entry.
>
> Since commit 222d7dbd258d ("net: prevent dst uses after free")
> skb_dst_force() might clear the dst_entry attached to the skb.
> The xfrm code don't expect this to happen, so we crash with
> a NULL pointer dereference in this case. Fix it by checking
> skb_dst(skb) for NULL after skb_dst_force() and drop the packet
> in cast the dst_entry was cleared.
>
> Fixes: 222d7dbd258d ("net: prevent dst uses after free")
> Reported-by: Tobias Hommel <netdev-list@genoetigt.de>
> Reported-by: Kristian Evensen <kristian.evensen@gmail.com>
> Reported-by: Wolfgang Walter <linux@stwm.de>
> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
> ---
> net/xfrm/xfrm_output.c | 4 ++++
> net/xfrm/xfrm_policy.c | 4 ++++
> 2 files changed, 8 insertions(+)
>
> diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
> index 89b178a78dc7..36d15a38ce5e 100644
> --- a/net/xfrm/xfrm_output.c
> +++ b/net/xfrm/xfrm_output.c
> @@ -101,6 +101,10 @@ static int xfrm_output_one(struct sk_buff *skb, int
> err) spin_unlock_bh(&x->lock);
>
> skb_dst_force(skb);
> + if (!skb_dst(skb)) {
> + XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
> + goto error_nolock;
> + }
>
> if (xfrm_offload(skb)) {
> x->type_offload->encap(x, skb);
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index 7c5e8978aeaa..626e0f4d1749 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -2548,6 +2548,10 @@ int __xfrm_route_forward(struct sk_buff *skb,
> unsigned short family) }
>
> skb_dst_force(skb);
> + if (!skb_dst(skb)) {
> + XFRM_INC_STATS(net, LINUX_MIB_XFRMFWDHDRERROR);
> + return 0;
> + }
>
> dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, XFRM_LOOKUP_QUEUE);
> if (IS_ERR(dst)) {
This patch fixes the problem here.
XfrmFwdHdrError gets around 80 at the very beginning and remains so. Probably
this happens when some route are changed/set then.
Regards and thanks,
--
Wolfgang Walter
Studentenwerk München
Anstalt des öffentlichen Rechts
^ permalink raw reply
* Re: [PATCH net-next v3 05/17] zinc: ChaCha20 x86_64 implementation
From: Eric Biggers @ 2018-09-11 21:48 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: Thomas Gleixner, Samuel Neves, LKML, Netdev, David Miller,
Greg Kroah-Hartman, Andrew Lutomirski, Jean-Philippe Aumasson,
Andy Polyakov, mingo, X86 ML, Linux Crypto Mailing List
In-Reply-To: <CAHmME9qPk7iOVspOJOhN0M+C=v+i6GNq9XkDnXXJ=puoFV0Gfg@mail.gmail.com>
On Tue, Sep 11, 2018 at 03:12:14PM -0600, Jason A. Donenfeld wrote:
> Hey Thomas,
>
> On Tue, Sep 11, 2018 at 3:09 AM Thomas Gleixner <tglx@linutronix.de> wrote:
> > > This is covered on the 02/17 commit message, whose relevant paragraph follows:
> > Well, being only cc'ed on only half of the patches does not really help.
>
> Sorry about that. I'm happy to Cc you on the whole series for next
> round if you want. Just let me know. In the meantime:
>
> https://patchwork.ozlabs.org/project/netdev/list/?series=65056
> https://lore.kernel.org/lkml/20180911010838.8818-1-Jason@zx2c4.com/T/
>
> Regards,
> Jason
Please Cc linux-crypto on the whole patch series, including the cover letter.
- Eric
^ permalink raw reply
* Re: tools/bpf regression causing samples/bpf/ to hang
From: Yonghong Song @ 2018-09-11 16:46 UTC (permalink / raw)
To: Björn Töpel, Netdev
Cc: ast, Daniel Borkmann, Jesper Dangaard Brouer
In-Reply-To: <CAJ+HfNh42UiWdMdtw=eM6LoHTWWJ5h+rnBdhOBdoatNS-8nFOQ@mail.gmail.com>
On 9/11/18 4:11 AM, Björn Töpel wrote:
> Hi Yonghong, I tried to run the XDP samples from the bpf-next tip
> today, and was hit by a regression.
>
> Commit f7010770fbac ("tools/bpf: move bpf/lib netlink related
> functions into a new file") adds a while(1) around the recv call in
> bpf_set_link_xdp_fd making that call getting stuck in an infinite
> loop.
>
> I simply removed the loop, and that solved my problem (patch below).
>
> However, I don't know if removing the loop would break bpftool for
> you. If not, I can submit the patch as a proper one for bpf-next.
Hi, Björn, thanks for reporting the problem.
The while loop is needed since the "recv" syscall buffer size
may not be big enough to hold all the returned information, in
which cases, multiple "recv" calls are needed.
Could you try the following patch to see whether it fixed your
issue? Thanks!
commit 3eb1c0249dfc3ea4ad61aa223dce32262af7e049 (HEAD -> fix)
Author: Yonghong Song <yhs@fb.com>
Date: Tue Sep 11 08:58:20 2018 -0700
tools/bpf: fix a netlink recv issue
Commit f7010770fbac ("tools/bpf: move bpf/lib netlink related
functions into a new file") introduced a while loop for the
netlink recv path. This while loop is needed since the
buffer in recv syscall may not be big enough to hold all the
information and in such cases multiple recv calls are needed.
When netlink recv returns message length of 0, there will be
no more messages for returning data so the while loop
can end.
Fixes: f7010770fbac ("tools/bpf: move bpf/lib netlink related
functions into a new file")
Reported-by: Björn Töpel <bjorn.topel@intel.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
index 469e068dd0c5..37827319a50a 100644
--- a/tools/lib/bpf/netlink.c
+++ b/tools/lib/bpf/netlink.c
@@ -77,6 +77,9 @@ static int bpf_netlink_recv(int sock, __u32 nl_pid,
int seq,
goto done;
}
+ if (len == 0)
+ break;
+
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
nh = NLMSG_NEXT(nh, len)) {
if (nh->nlmsg_pid != nl_pid) {
>
> Thanks!
> Björn
>
> From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= <bjorn.topel@intel.com>
> Date: Tue, 11 Sep 2018 12:35:44 +0200
> Subject: [PATCH] tools/bpf: remove loop around netlink recv
>
> Commit f7010770fbac ("tools/bpf: move bpf/lib netlink related
> functions into a new file") moved the bpf_set_link_xdp_fd and split it
> up into multiple functions. The added receive function
> bpf_netlink_recv added a loop around the recv syscall leading to
> multiple recv calls. This resulted in all XDP samples in the
> samples/bpf/ to stop working, since they were stuck in a blocking
> recv.
>
> This commits removes the while (1)-statement.
>
> Fixes: f7010770fbac ("tools/bpf: move bpf/lib netlink related
> functions into a new file")
> Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
> ---
> tools/lib/bpf/netlink.c | 64 ++++++++++++++++++++---------------------
> 1 file changed, 31 insertions(+), 33 deletions(-)
>
> diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
> index 469e068dd0c5..0eae1fbf46c6 100644
> --- a/tools/lib/bpf/netlink.c
> +++ b/tools/lib/bpf/netlink.c
> @@ -70,41 +70,39 @@ static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq,
> char buf[4096];
> int len, ret;
>
> - while (1) {
> - len = recv(sock, buf, sizeof(buf), 0);
> - if (len < 0) {
> - ret = -errno;
> + len = recv(sock, buf, sizeof(buf), 0);
> + if (len < 0) {
> + ret = -errno;
> + goto done;
> + }
> +
> + for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
> + nh = NLMSG_NEXT(nh, len)) {
> + if (nh->nlmsg_pid != nl_pid) {
> + ret = -LIBBPF_ERRNO__WRNGPID;
> goto done;
> }
> -
> - for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
> - nh = NLMSG_NEXT(nh, len)) {
> - if (nh->nlmsg_pid != nl_pid) {
> - ret = -LIBBPF_ERRNO__WRNGPID;
> - goto done;
> - }
> - if (nh->nlmsg_seq != seq) {
> - ret = -LIBBPF_ERRNO__INVSEQ;
> - goto done;
> - }
> - switch (nh->nlmsg_type) {
> - case NLMSG_ERROR:
> - err = (struct nlmsgerr *)NLMSG_DATA(nh);
> - if (!err->error)
> - continue;
> - ret = err->error;
> - nla_dump_errormsg(nh);
> - goto done;
> - case NLMSG_DONE:
> - return 0;
> - default:
> - break;
> - }
> - if (_fn) {
> - ret = _fn(nh, fn, cookie);
> - if (ret)
> - return ret;
> - }
> + if (nh->nlmsg_seq != seq) {
> + ret = -LIBBPF_ERRNO__INVSEQ;
> + goto done;
> + }
> + switch (nh->nlmsg_type) {
> + case NLMSG_ERROR:
> + err = (struct nlmsgerr *)NLMSG_DATA(nh);
> + if (!err->error)
> + continue;
> + ret = err->error;
> + nla_dump_errormsg(nh);
> + goto done;
> + case NLMSG_DONE:
> + return 0;
> + default:
> + break;
> + }
> + if (_fn) {
> + ret = _fn(nh, fn, cookie);
> + if (ret)
> + return ret;
> }
> }
> ret = 0;
>
^ permalink raw reply related
* Re: [PATCH net-next v3 02/17] zinc: introduce minimal cryptography library
From: Eric Biggers @ 2018-09-11 21:47 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Ard Biesheuvel, Jason A. Donenfeld, Linux Kernel Mailing List,
<netdev@vger.kernel.org>, David S. Miller, Andy Lutomirski,
Samuel Neves, Jean-Philippe Aumasson,
open list:HARDWARE RANDOM NUMBER GENERATOR CORE
In-Reply-To: <20180911145624.GA21635@kroah.com>
On Tue, Sep 11, 2018 at 04:56:24PM +0200, Greg Kroah-Hartman wrote:
> On Tue, Sep 11, 2018 at 12:08:56PM +0200, Ard Biesheuvel wrote:
> > > As Zinc is simply library code, its config options are un-menued, with
> > > the exception of CONFIG_ZINC_DEBUG, which enables various selftests and
> > > BUG_ONs.
> > >
> >
> > In spite of the wall of text, you fail to point out exactly why the
> > existing AEAD API in unsuitable, and why fixing it is not an option.
> >
> > As I pointed out in a previous version, I don't think we need a
> > separate crypto API/library in the kernel, and I don't think you have
> > convinced anyone else yet either.
>
> Um, then why do people keep sprinkling new crypto/hash code all around
> the kernel tree? It's because what we have as a crypto api is complex
> and is hard to use for many in-kernel users.
>
> Something like this new interface (zinc) is a much "saner" api for
> writing kernel code that has to interact with crypto/hash primitives.
>
> I see no reason why the existing crypto code can be redone to use the
> zinc crypto primitives over time, making there only be one main location
> for the crypto algorithms. But to do it the other way around is pretty
> much impossible given the complexities in the existing api that has been
> created over time.
>
> Not to say that the existing api is not a viable one, but ugh, really?
> You have to admit it is a pain to try to use in any "normal" type of
> "here's a bytestream, go give me a hash" type of method, right?
>
> Also there is the added benefit that the crypto primitives here have
> been audited by a number of people (so Jason stated), and they are
> written in a way that the crypto community can more easily interact and
> contribute to. Which is _way_ better than what we have today.
>
> So this gets my "stamp of approval" for whatever it is worth :)
>
I think you mean you see no reason why it *cannot* be converted? The
conversions definitely *should* be done, just like how some of the existing
crypto API algorithms like SHA-256 already wrap implementations in lib/. In my
view, lib/zinc/ isn't fundamentally different from what we already have for some
algorithms. So it's misguided to design/present it as some novel thing, which
unfortunately this patchset still does to a large extent. (The actual new thing
is how architecture-specific implementations are handled.)
Of course, the real problem is that even after multiple revisions of this
patchset, there's still no actual conversions of the existing crypto API
algorithms over to use the new implementations. "Zinc" is still completely
separate from the existing crypto API.
So, it's not yet clear that the conversions will actually work out without
problems that would require changes in "Zinc". I don't think it makes sense to
merge all this stuff without doing the conversions, or at the very least
demonstrating how they will be done.
In particular, in its current form "Zinc" is useless for anyone that needs the
existing crypto API. For example, for HPolyC,
(https://lkml.org/lkml/2018/8/6/857), I need to make improvements to ChaCha and
Poly1305 in the existing crypto API, e.g. to add support for XChaCha and
NEON-accelerated Poly1305. Having completely separate ChaCha and Poly1305
implementations in Zinc doesn't help at all. If anything, it makes things
harder because people will have to review/maintain both sets of implementations;
and when trying to make the improvements I need, I'll find myself in the middle
of a holy war between two competing camps who each have their own opinion about
The Right Way To Do Crypto, and their own crypto implementations and APIs in the
kernel.
- Eric
^ permalink raw reply
* Re: [PATCH v2 net-next 05/12] net: ethernet: genet: Fix speed selection
From: Florian Fainelli @ 2018-09-11 16:41 UTC (permalink / raw)
To: Andrew Lunn, David Miller; +Cc: netdev
In-Reply-To: <1536616350-15442-6-git-send-email-andrew@lunn.ch>
On 09/10/2018 02:52 PM, Andrew Lunn wrote:
> The phy supported speed is being used to determine if the MAC should
> be configured to 100 or 1G. The masking logic is broken. Instead, look
> 1G supported speeds to enable 1G MAC support.
Since you likely need to respin to address the kbuild test robot report
of patch 10, do you mind changing the subject to:
net: bcmgenet: Fix speed selection for reverse MII
to match the subject prefix used throughout past submissions?
Thank you!
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> drivers/net/ethernet/broadcom/genet/bcmmii.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
> index b11d58f1bf45..b756fc79424e 100644
> --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
> +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
> @@ -226,11 +226,10 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
> * capabilities, use that knowledge to also configure the
> * Reverse MII interface correctly.
> */
> - if ((dev->phydev->supported & PHY_BASIC_FEATURES) ==
> - PHY_BASIC_FEATURES)
> - port_ctrl = PORT_MODE_EXT_RVMII_25;
> - else
> + if (dev->phydev->supported & PHY_1000BT_FEATURES)
> port_ctrl = PORT_MODE_EXT_RVMII_50;
> + else
> + port_ctrl = PORT_MODE_EXT_RVMII_25;
> bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
> break;
>
>
--
Florian
^ permalink raw reply
* [RFC] managing PHY carrier from user space
From: Joakim Tjernlund @ 2018-09-11 16:41 UTC (permalink / raw)
To: netdev@vger.kernel.org, f.fainelli@gmail.com, andrew@lunn.ch
I am looking for a way to induce carrier state from user space, primarily
for Fixed PHYs as these are always up. ifplugd/dhcp etc. does not behave properly
if the link is up when it really isn't.
I came up with a new 'phy_carrier' attribute in /sys/class/net/eth0/phydev
where I can induce carrier state:
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index a1e7ea4d4b16..f82beeabdd75 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -612,10 +612,39 @@ phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(phy_has_fixups);
+static ssize_t
+phy_carrier_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct phy_device *phydev = to_phy_device(dev);
+ struct net_device *netdev = phydev->attached_dev;
+
+ return sprintf(buf, "%d\n", netif_carrier_ok(netdev));
+}
+
+static ssize_t phy_carrier_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct phy_device *phydev = to_phy_device(dev);
+ struct net_device *netdev = phydev->attached_dev;
+ bool enable;
+
+ if (strtobool(buf, &enable))
+ return -EINVAL;
+
+ if (enable)
+ netif_carrier_on(netdev);
+ else
+ netif_carrier_off(netdev);
+ return len;
+}
+static DEVICE_ATTR_RW(phy_carrier);
+
static struct attribute *phy_dev_attrs[] = {
&dev_attr_phy_id.attr,
&dev_attr_phy_interface.attr,
&dev_attr_phy_has_fixups.attr,
+ &dev_attr_phy_carrier.attr,
NULL,
};
ATTRIBUTE_GROUPS(phy_dev);
I would like to know if this acceptable for linux proper or if there is
a better way to do this?
Jocke
^ permalink raw reply related
* Re: bpf: btf: Change how section is supported in btf_header
From: Dmitry Vyukov @ 2018-09-11 16:40 UTC (permalink / raw)
To: Martin KaFai Lau, Daniel Borkmann, Alexei Starovoitov; +Cc: netdev
Hi Martin,
I am looking at the subj commit:
static int btf_add_type(struct btf_verifier_env *env, struct btf_type *t)
@@ -1754,9 +1756,9 @@ static int btf_check_all_metas(struct
btf_verifier_env *env)
struct btf_header *hdr;
void *cur, *end;
- hdr = btf->hdr;
+ hdr = &btf->hdr;
cur = btf->nohdr_data + hdr->type_off;
- end = btf->nohdr_data + hdr->str_off;
+ end = btf->nohdr_data + hdr->type_len;
Shouldn't this be:
+ end = cur + hdr->type_len;
? Or otherwise I am having trouble understanding meaning of fields.
On a related note, what's between header and type_off? Is type_off
supposed to be 0 always?
Thanks
^ permalink raw reply
* Re: [PATCH net-next v3 05/17] zinc: ChaCha20 x86_64 implementation
From: Jason A. Donenfeld @ 2018-09-11 21:28 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Samuel Neves, LKML, Netdev, David Miller, Greg Kroah-Hartman,
Andrew Lutomirski, Jean-Philippe Aumasson, Andy Polyakov, mingo,
X86 ML, Linux Crypto Mailing List
In-Reply-To: <alpine.DEB.2.21.1809112322060.1427@nanos.tec.linutronix.de>
On Tue, Sep 11, 2018 at 3:27 PM Thomas Gleixner <tglx@linutronix.de> wrote:
> Na, all good. I'm fine with the answer and reviewing that ASM maze is way
> over my limited crypto knowledge anyway. I definitely would enjoy
> refreshing the math behind it, but that surely would be way outside of your
> envisioned time frame for getting this merged :)
Well, if you're at LPC, we can nerd out a bit on some crypto math if
you want. :-P
^ permalink raw reply
* Re: [PATCH net-next v3 05/17] zinc: ChaCha20 x86_64 implementation
From: Thomas Gleixner @ 2018-09-11 21:27 UTC (permalink / raw)
To: Jason A. Donenfeld
Cc: Samuel Neves, LKML, Netdev, David Miller, Greg Kroah-Hartman,
Andrew Lutomirski, Jean-Philippe Aumasson, Andy Polyakov, mingo,
X86 ML, Linux Crypto Mailing List
In-Reply-To: <CAHmME9qPk7iOVspOJOhN0M+C=v+i6GNq9XkDnXXJ=puoFV0Gfg@mail.gmail.com>
On Tue, 11 Sep 2018, Jason A. Donenfeld wrote:
> Hey Thomas,
>
> On Tue, Sep 11, 2018 at 3:09 AM Thomas Gleixner <tglx@linutronix.de> wrote:
> > > This is covered on the 02/17 commit message, whose relevant paragraph follows:
> > Well, being only cc'ed on only half of the patches does not really help.
>
> Sorry about that. I'm happy to Cc you on the whole series for next
> round if you want. Just let me know. In the meantime:
Na, all good. I'm fine with the answer and reviewing that ASM maze is way
over my limited crypto knowledge anyway. I definitely would enjoy
refreshing the math behind it, but that surely would be way outside of your
envisioned time frame for getting this merged :)
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH net-next v3 02/17] zinc: introduce minimal cryptography library
From: Jason A. Donenfeld @ 2018-09-11 21:22 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: LKML, Netdev, David Miller, Greg Kroah-Hartman, Andrew Lutomirski,
Samuel Neves, Jean-Philippe Aumasson, Linux Crypto Mailing List
In-Reply-To: <CAKv+Gu9nSeo4PFVrtjtqGQ32eqyxUp3xVCczZfu+dhFz5yLM0A@mail.gmail.com>
Hello Ard,
I realize you've put a lot of good and hard work into the existing
crypto API, and that my writing in these commit messages might be a
bit too bristly and dismissive of that hard work. So I think in a
sense it's understandable that you've responded as such here. But
hopefully I can address your concerns. One thing to keep in mind is
that Zinc endeavors to provide the basis for simple and direct
functions to software algorithms. This is fairly modest goal. Just
some functions that do some stuff in software. Around these you'll
still be able to have complicated and impressive dynamic dispatch and
asynchronous mechanisms such as the present crypto API. Zinc is merely
getting the software implementation side done in a very simple and
direct way. So I don't think there's a good reason for so much
antagonism, despite a perhaps overbearing tone of my commit messages.
Rather, I expect that we'll wind up working together on this quite a
bit down the line.
> In spite of the wall of text, you fail to point out exactly why the
> existing AEAD API in unsuitable, and why fixing it is not an option.
I thought I had addressed this. Firstly, there's a need for more than
just AEAD, but ignoring that, the AEAD API is a big full API that does
lots of things, makes allocations, parses descriptors, and so forth.
I'm sure this kind of highly-engineered approach will continue to
improve over time in that highly engineered direction. Zinc is doing
something a bit different: it's providing a series of simple functions
for various cryptographic routines. This is a considerably different
goal -- perhaps even a complementary one -- to the AEAD API.
> I don't think you have
> convinced anyone else yet either.
Please only speak for yourself and refrain from rhetoric like this,
which is patently false.
> Please refrain from sending a v4 with just a couple of more tweaks on
> top
Sorry, no, I'm not going to stop working hard on this because you're
wary of a new approach. I will continue to improve the submission
until it is mergable, and I do not intend to stop.
Anyway, it sounds like this whole thing may have ruffled your feathers
a bit. Will you be at Linux Plumbers Conference in November? I'm
planning on attending, and perhaps we could find some time there to
sit down and talk one on one a bit.
Regards,
Jason
^ permalink raw reply
* Editing 1
From: Aaron @ 2018-09-11 5:56 UTC (permalink / raw)
To: netdev
Hi,
If you have photos for editing, please send email to: hansrekan@outlook.com
We have 12 in house image editors and we can help you for cutting out your
photos, or path the photos.
Includes retouching if needed.
Used for products photos or portrait photos, catalog photos.
You may drop us one photo, we can send you the testing work.
Thanks,
Aaron Williams
Email: hansrekan@outlook.com
^ permalink raw reply
* [PATCH] knav: qmss: Introduce queue descriptors monitor
From: Vasyl Gomonovych @ 2018-09-11 21:15 UTC (permalink / raw)
To: w-kwok2, m-karicheri2, davem, grygorii.strashko
Cc: Vasyl Gomonovych, Vasyl Gomonovych, Santosh Shilimkar,
linux-kernel, netdev, linux-arm-kernel
Monitor and record available descriptors in knav_qmss queues
Get amount of available descriptors in free-descriptor queue
base on event-triggered RX traffic.
Also monitor free-descriptor queue base on periodic time interval
in kernel thread.
To start monitoring available descriptors in queue earlyi,
module parameters, enable start monitoring in boottime
This queue descriptor monitor helps debugging starvation issue.
The monitor should help debug queue under traffic pressure
and can describe the shape of this pressure when a queue
faced descriptors starvation.
Monitor helpful for IP blocks which do not have dedicated
descriptor starvation interrupt like RapidIO IP.
Registration and enable file in debugfs hierarchy
|-/sys/kernel/debug
|-- knav_qmssm_soc:hwqueue@2a40000
| |-- 8710
| | |-- buffer_size
| | |-- enable
| | |-- monitor_stats
| | -- unregister
---
The current implementation is the first iteration
and require additional work.
By this patch I would like to know does this could be
helpful for other components and continue my work in a right way.
Signed-off-by: Vasyl Gomonovych <vasyl.gomonovych@nokia.com>
---
drivers/net/ethernet/ti/netcp_core.c | 14 +
drivers/soc/ti/Makefile | 2 +-
drivers/soc/ti/knav_qmss.h | 3 +
drivers/soc/ti/knav_qmss_queue.c | 18 +
drivers/soc/ti/knav_qmssm.c | 1147 ++++++++++++++++++++++++++++++++++
drivers/soc/ti/knav_qmssm.h | 145 +++++
include/linux/soc/ti/knav_qmss.h | 19 +-
7 files changed, 1346 insertions(+), 2 deletions(-)
create mode 100644 drivers/soc/ti/knav_qmssm.c
create mode 100644 drivers/soc/ti/knav_qmssm.h
diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
index e40aa3e31af2..d270901c48e1 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -1592,12 +1592,15 @@ static void netcp_free_navigator_resources(struct netcp_intf *netcp)
knav_pool_destroy(netcp->tx_pool);
netcp->tx_pool = NULL;
}
+
+ knav_queue_device_control(netcp->rx_queue, KNAV_QUEUE_SET_MONITOR, 0);
}
static int netcp_setup_navigator_resources(struct net_device *ndev)
{
struct netcp_intf *netcp = netdev_priv(ndev);
struct knav_queue_notify_config notify_cfg;
+ struct knav_queue_monitor_config monitor_cfg;
struct knav_dma_cfg config;
u32 last_fdq = 0;
u8 name[16];
@@ -1664,6 +1667,9 @@ static int netcp_setup_navigator_resources(struct net_device *ndev)
knav_queue_disable_notify(netcp->rx_queue);
/* open Rx FDQs */
+ for (i = 0; i < KNAV_DMA_FDQ_PER_CHAN; i++)
+ monitor_cfg.fdq_arg[i] = NULL;
+
for (i = 0; i < KNAV_DMA_FDQ_PER_CHAN && netcp->rx_queue_depths[i];
++i) {
snprintf(name, sizeof(name), "rx-fdq-%s-%d", ndev->name, i);
@@ -1672,8 +1678,16 @@ static int netcp_setup_navigator_resources(struct net_device *ndev)
ret = PTR_ERR(netcp->rx_fdq[i]);
goto fail;
}
+ monitor_cfg.fdq_arg[i] = netcp->rx_fdq[i];
}
+ /* Set monitor for Rx queue */
+ monitor_cfg.fn = knav_qmssm_event_callback;
+ ret = knav_queue_device_control(netcp->rx_queue,
+ KNAV_QUEUE_SET_MONITOR, &monitor_cfg);
+ if (ret)
+ dev_err(netcp->ndev_dev, "fail set qmms %d", netcp->rx_queue_id);
+
memset(&config, 0, sizeof(config));
config.direction = DMA_DEV_TO_MEM;
config.u.rx.einfo_present = true;
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
index a22edc0b258a..4375f3c4f013 100644
--- a/drivers/soc/ti/Makefile
+++ b/drivers/soc/ti/Makefile
@@ -3,7 +3,7 @@
# TI Keystone SOC drivers
#
obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS) += knav_qmss.o
-knav_qmss-y := knav_qmss_queue.o knav_qmss_acc.o
+knav_qmss-y := knav_qmss_queue.o knav_qmss_acc.o knav_qmssm.o
obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA) += knav_dma.o
obj-$(CONFIG_AMX3_PM) += pm33xx.o
obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o
diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h
index 3efc47e82973..a05b6174ab3a 100644
--- a/drivers/soc/ti/knav_qmss.h
+++ b/drivers/soc/ti/knav_qmss.h
@@ -289,6 +289,8 @@ struct knav_queue {
knav_queue_notify_fn notifier_fn;
void *notifier_fn_arg;
atomic_t notifier_enabled;
+ struct knav_queue_monitor_config *monitor_cfg;
+ atomic_t monitor_enabled;
struct rcu_head rcu;
unsigned flags;
struct list_head list;
@@ -313,6 +315,7 @@ struct knav_device {
struct list_head pdsps;
struct list_head qmgrs;
enum qmss_version version;
+ struct knav_qmssm *qmon;
};
struct knav_range_ops {
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index 6755f2af5619..9516bba9261e 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -30,6 +30,7 @@
#include <linux/soc/ti/knav_qmss.h>
#include "knav_qmss.h"
+#include "knav_qmssm.h"
static struct knav_device *kdev;
static DEFINE_MUTEX(knav_dev_lock);
@@ -101,6 +102,12 @@ void knav_queue_notify(struct knav_queue_inst *inst)
continue;
this_cpu_inc(qh->stats->notifies);
qh->notifier_fn(qh->notifier_fn_arg);
+
+ if (atomic_read(&qh->monitor_enabled) == KNAV_QMSSM_DISABLE)
+ continue;
+ if (WARN_ON(!qh->monitor_cfg))
+ continue;
+ qh->monitor_cfg->fn(qh);
}
rcu_read_unlock();
}
@@ -600,6 +607,7 @@ int knav_queue_device_control(void *qhandle, enum knav_queue_ctrl_cmd cmd,
{
struct knav_queue *qh = qhandle;
struct knav_queue_notify_config *cfg;
+ struct knav_queue_monitor_config *mcfg;
int ret;
switch ((int)cmd) {
@@ -628,6 +636,11 @@ int knav_queue_device_control(void *qhandle, enum knav_queue_ctrl_cmd cmd,
ret = knav_queue_get_count(qh);
break;
+ case KNAV_QUEUE_SET_MONITOR:
+ mcfg = (void *)arg;
+ ret = knav_queue_set_monitor(qh, mcfg);
+ break;
+
default:
ret = -ENOTSUPP;
break;
@@ -1874,6 +1887,10 @@ static int knav_queue_probe(struct platform_device *pdev)
goto err;
}
+ ret = knav_qmssm_register(kdev);
+ if (ret < 0)
+ dev_err(dev, "knav qmssm registration failed\n");
+
debugfs_create_file("qmss", S_IFREG | S_IRUGO, NULL, NULL,
&knav_queue_debug_ops);
device_ready = true;
@@ -1891,6 +1908,7 @@ static int knav_queue_probe(struct platform_device *pdev)
static int knav_queue_remove(struct platform_device *pdev)
{
/* TODO: Free resources */
+ knav_qmssm_unregister(kdev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return 0;
diff --git a/drivers/soc/ti/knav_qmssm.c b/drivers/soc/ti/knav_qmssm.c
new file mode 100644
index 000000000000..2d249a998819
--- /dev/null
+++ b/drivers/soc/ti/knav_qmssm.c
@@ -0,0 +1,1147 @@
+/*
+ * Texas Instruments Keystone Navigator Queue Management SubSystem
+ * Queue Managers Monitor Implementation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/rhashtable.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/tick.h>
+#include <linux/ktime.h>
+#include <linux/io.h>
+#include <linux/stat.h>
+#include <linux/moduleparam.h>
+#include <linux/sched/signal.h>
+#include "knav_qmssm.h"
+
+static char *knav_qmssm_name;
+module_param(knav_qmssm_name, charp, 0644);
+MODULE_PARM_DESC(knav_qmssm_name, "Knav queue monitor name");
+
+#define MAX_BOOTIME_MQ 4
+static int knav_qmssm_qid[MAX_BOOTIME_MQ] = {-1, -1, -1, -1};
+module_param_array(knav_qmssm_qid, int, NULL, 0644);
+MODULE_PARM_DESC(knav_qmssm_qid, "Predefine knav queue ID for early monitoring start");
+
+static u64 knav_qmssm_interval_ms;
+module_param(knav_qmssm_interval_ms, ullong, 0644);
+MODULE_PARM_DESC(knav_qmssm_interval_ms, "Knav queue logger interval");
+
+static LIST_HEAD(knav_qmssm_list);
+static DEFINE_MUTEX(knav_qmssm_lock);
+
+#define TEMP_BUFF_SIZE 128
+
+static const char knav_qmssm_prefix[] = "knav_qmssm";
+static const char knav_qmssm_register_str[] = "register";
+static const char knav_qmssm_unregister_str[] = "unregister";
+static const char knav_qmssm_interval[] = "interval_ms";
+
+static const char knav_qmssm_qid_enable[] = "enable";
+static const char knav_qmssm_qid_wmark[] = "watermark";
+static const char knav_qmssm_qid_bufsize[] = "buffer_size";
+static const char knav_qmssm_qid_stats[] = "monitor_stats";
+
+#define MONITOR_WMARK_MIN 64
+#define MONITOR_WMARK_LOW 128
+#define MONITOR_WMARK_HIGH 256
+
+#define MONITOR_INTERVAL_MS (10*1000) /* 10 sec */
+
+#define MONITOR_BS 8192
+#define MONITOR_BS_MAX (64*1024)
+
+#define qmssm_dev(qmon) (qmon->kdev->dev)
+#define mqd_dev(mqd) (qmssm_dev(mqd->qmon))
+#define data_dev(data) (mqd_dev(data->mqd))
+#define mqd_kdev(mqd) (mqd->qmon->kdev)
+
+#define property(mqd) (mqd->mqe->data->property)
+
+#define INT_PTR(x) ((void *)(unsigned long)x)
+#define PTR_INT(x) ((int)(unsigned long)x)
+
+static inline void knav_qmssm_property_dump(struct monitor_queue_dentry *mqd)
+{
+ dev_dbg(mqd_dev(mqd), "dump: qid %d bs=%d, enable=%d, wmark=[%d %d %d]\n",
+ mqd->qid,
+ property(mqd).buffsize,
+ atomic_read(&property(mqd).enable),
+ property(mqd).wmark[WM_MIN],
+ property(mqd).wmark[WM_LOW],
+ property(mqd).wmark[WM_HIGH]);
+}
+
+static void knav_qmssm_dump(struct knav_qmssm *qmon)
+{
+ struct monitor_queue_dentry *mqd;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(mqd, &qmon->mqlist, list) {
+ if (mqd->mqe)
+ knav_qmssm_property_dump(mqd);
+ }
+ rcu_read_unlock();
+}
+
+static struct knav_queue *knav_qmssm_get_queue(struct knav_device *kdev,
+ unsigned int qid)
+{
+ struct knav_queue *qh = NULL;
+ struct knav_queue_inst *inst = NULL;
+
+ if (!kdev)
+ return NULL;
+
+ if (kdev->base_id <= qid && kdev->base_id + kdev->num_queues > qid) {
+ qid -= kdev->base_id;
+ inst = kdev->instances + (qid << kdev->inst_shift);
+ }
+
+ if (!inst)
+ return NULL;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(qh, &inst->handles, list) {
+ if (knav_queue_device_control(qh, KNAV_QUEUE_GET_ID, 0) == qid)
+ break;
+ }
+ rcu_read_unlock();
+
+ return qh;
+}
+
+static int knav_qmssm_thread_logger(void *arg)
+{
+ struct knav_qmssm *qmon;
+ struct monitor_queue_dentry *mqd;
+ struct knav_queue *qh, *q[KNAV_QMSSM_FDQ_PER_CHAN];
+ unsigned int count[KNAV_QMSSM_FDQ_PER_CHAN];
+ unsigned int i = 0;
+ unsigned int qid[KNAV_QMSSM_FDQ_PER_CHAN];
+ ktime_t delay;
+ int ret;
+
+ qmon = (struct knav_qmssm *) arg;
+
+ while (!kthread_should_stop()) {
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(mqd, &qmon->mqlist, list) {
+
+ qh = mqd->qh;
+ if (!qh || !qh->inst)
+ continue;
+
+ if (!qh->monitor_cfg) {
+ count[0] = knav_queue_device_control(qh,
+ KNAV_QUEUE_GET_COUNT, 0);
+ dev_info(qmssm_dev(qmon), "%d:%d",
+ mqd->qid, count[0]);
+ continue;
+ }
+
+ for (i = 0; i < KNAV_QMSSM_FDQ_PER_CHAN; i++) {
+ q[i] = qh->monitor_cfg->fdq_arg[i];
+ count[i] = 0;
+ qid[i] = 0;
+ if (!q[i] || !q[i]->inst)
+ continue;
+
+ count[i] = knav_queue_device_control(q[i],
+ KNAV_QUEUE_GET_COUNT, 0);
+ qid[i] = knav_queue_device_control(qh,
+ KNAV_QUEUE_GET_ID, 0);
+ }
+ dev_info(qmssm_dev(qmon), "%d:%d %d:%d %d:%d %d:%d",
+ qid[0], count[0], qid[1], count[1],
+ qid[2], count[2], qid[3], count[3]);
+ }
+ rcu_read_unlock();
+
+ delay = ms_to_ktime(qmon->ilogger.interval_ms);
+ set_current_state(TASK_INTERRUPTIBLE);
+ ret = schedule_hrtimeout(&delay, HRTIMER_MODE_REL);
+ set_current_state(TASK_RUNNING);
+ }
+
+ return 0;
+}
+
+static int knav_qmssm_logger_start(struct knav_qmssm *qmon)
+{
+ struct task_struct *thread;
+ char name[TEMP_BUFF_SIZE] = {0};
+ int len = 0;
+ int ret = 0;
+
+ if (!qmon)
+ return -EINVAL;
+
+ mutex_lock(&qmon->mqlock);
+
+ if (qmon->ilogger.thread)
+ goto out;
+
+ len = snprintf(name, TEMP_BUFF_SIZE, "kthread_%s/%s\n",
+ knav_qmssm_prefix,
+ dev_name(qmssm_dev(qmon)));
+ name[len] = '\0';
+
+ thread = kthread_run(knav_qmssm_thread_logger, qmon, name);
+
+ if (IS_ERR(thread)) {
+ ret = PTR_ERR(thread);
+ goto out;
+ }
+
+ qmon->ilogger.thread = thread;
+
+out:
+ mutex_unlock(&qmon->mqlock);
+
+ return ret;
+}
+
+static void knav_qmssm_logger_stop(struct knav_qmssm *qmon)
+{
+ int ret;
+
+ if (!qmon)
+ return;
+
+ mutex_lock(&qmon->mqlock);
+
+ if (WARN_ON(!qmon->ilogger.thread)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ send_sig(SIGTERM, qmon->ilogger.thread, 1);
+ ret = kthread_stop(qmon->ilogger.thread);
+ qmon->ilogger.thread = NULL;
+
+out:
+ mutex_unlock(&qmon->mqlock);
+}
+
+static int knav_qmssm_alloc_rb(struct knav_qmssm_qdata *data)
+{
+ int size;
+
+ if (!data)
+ return -EINVAL;
+
+ size = data->property.buffsize;
+ (*data).ring_buffer = ring_buffer_alloc(size, RB_FL_OVERWRITE);
+ if (!data->ring_buffer) {
+ dev_dbg(data_dev(data), "cannot allocate log buffer\n");
+ return -ENOMEM;
+ }
+ dev_dbg(data_dev(data), "ring buffer allocated\n");
+
+ return 0;
+}
+
+static int knav_qmssm_free_rb(struct knav_qmssm_qdata *data)
+{
+ if (!data) {
+ dev_warn(data_dev(data), "%s() null data pointer\n", __func__);
+ return -EINVAL;
+ }
+
+ if (data->ring_buffer) {
+ ring_buffer_free(data->ring_buffer);
+ data->ring_buffer = NULL;
+ dev_dbg(data_dev(data), "ring buffer freed\n");
+ }
+
+ return 0;
+}
+
+static int knav_qmssm_write_rb(struct ring_buffer *buffer, void *entry,
+ unsigned long size)
+{
+ int ret = 0;
+
+ if (!buffer || !entry) {
+ pr_err("%s() rb=%p entry=%p", __func__, buffer, entry);
+ return -EINVAL;
+ }
+
+ ret = ring_buffer_write(buffer, size, entry);
+ if (ret)
+ pr_err("dropped log event %p size %lu\n", buffer, size);
+
+ return 0;
+}
+
+static void knav_qmssm_read_rb(struct seq_file *filp,
+ struct knav_qmssm_qdata *data)
+{
+ struct ring_buffer_event *event;
+ struct knav_qmssm_record_item *entry;
+ struct ring_buffer *rb;
+ int cpu;
+ int found = 1;
+ u64 ts;
+ unsigned long lost;
+ unsigned long rem_nsec;
+
+ rb = data->ring_buffer;
+
+ if (!rb) {
+ dev_err(data_dev(data), "%s null data\n", __func__);
+ return;
+ }
+
+ if (ring_buffer_empty(rb)) {
+ dev_dbg(data_dev(data), "log buffer empty qid %d\n",
+ data->mqd->qid);
+ found = 0;
+ }
+
+ while (found) {
+
+ found = 0;
+ for_each_online_cpu(cpu) {
+
+ event = ring_buffer_consume(rb, cpu, &ts, &lost);
+ if (!event)
+ continue;
+ else {
+ entry = ring_buffer_event_data(event);
+ found = 1;
+ if (!entry)
+ continue;
+
+ rem_nsec = do_div(ts, 1000000000);
+ seq_printf(filp, "[%5lu.%06lu]\t\t%d\t\t%d\n",
+ (unsigned long)ts, rem_nsec,
+ entry->qid, entry->count);
+ }
+ }
+ }
+}
+
+static void knav_qmssm_write_data(struct knav_qmssm_qdata *data,
+ struct knav_qmssm_record_item *entry)
+{
+ int ret = 0;
+
+ if (!data || !entry) {
+ pr_err("error ring buffer write\n");
+ return;
+ }
+
+ ret = knav_qmssm_write_rb(data->ring_buffer, entry, sizeof(*entry));
+ if (ret) {
+ pr_err("ring buffer error to write qid %d\n", data->mqd->qid);
+ return;
+ }
+}
+
+static void knav_qmssm_start_rb(struct knav_qmssm_qdata *data)
+{
+ if (!data->ring_buffer)
+ return;
+ ring_buffer_record_on(data->ring_buffer);
+ dev_dbg(data_dev(data), "%s() ring buffer start\n", __func__);
+}
+
+static void knav_qmssm_stop_rb(struct knav_qmssm_qdata *data)
+{
+ if (!data->ring_buffer)
+ return;
+ ring_buffer_record_off(data->ring_buffer);
+ dev_dbg(data_dev(data), "%s() ring buffer stop\n", __func__);
+}
+
+static int knav_qmssm_start(struct monitor_queue_dentry *mqd)
+{
+ struct knav_qmssm_qdata *data;
+ int ret = 0;
+
+ if (!mqd || WARN_ON(!mqd->mqe))
+ return -EINVAL;
+
+ mutex_lock(&mqd->lock);
+
+ data = mqd->mqe->data;
+ if (!data)
+ goto out0;
+
+ if (!(&mqd->mqe->data->property.enable)) //TODO
+ goto out0;
+
+ if (atomic_read(&property(mqd).enable) == KNAV_QMSSM_ENABLE)
+ goto out0;
+
+ ret = knav_qmssm_free_rb(data);
+ if (ret)
+ goto out0;
+
+ ret = knav_qmssm_alloc_rb(data);
+ if (ret)
+ goto out0;
+
+ knav_qmssm_start_rb(data);
+ ret = knav_queue_enable_monitor(mqd->qh);
+ if (ret) {
+ dev_dbg(mqd_dev(mqd), "cannot start not event-driven queue\n");
+ goto out1;
+ }
+ dev_dbg(mqd_dev(mqd), "%s(%d) success\n", __func__, mqd->qid);
+ atomic_set(&property(mqd).enable, KNAV_QMSSM_ENABLE);
+
+out0:
+ mutex_unlock(&mqd->lock);
+ return ret;
+
+out1:
+ knav_qmssm_stop_rb(data);
+ knav_qmssm_free_rb(data);
+ mutex_unlock(&mqd->lock);
+ return ret;
+}
+
+static int knav_qmssm_stop(struct monitor_queue_dentry *mqd)
+{
+ struct knav_qmssm_qdata *data;
+ int ret = 0;
+
+ if (!mqd)
+ return -EINVAL;
+
+ if (!mqd->mqe) {
+ dev_err(mqd_dev(mqd), "skip not event-driven queue");
+ return -EINVAL;
+ }
+
+ mutex_lock(&mqd->lock);
+ data = mqd->mqe->data;
+ if (atomic_read(&property(mqd).enable) == KNAV_QMSSM_DISABLE)
+ goto out;
+
+ ret = knav_queue_disable_monitor(mqd->qh);
+ if (ret) {
+ dev_dbg(mqd_dev(mqd), "%s(%d) error\n", __func__, mqd->qid);
+ goto out;
+ }
+ knav_qmssm_stop_rb(data);
+ atomic_set(&property(mqd).enable, KNAV_QMSSM_DISABLE);
+ dev_dbg(mqd_dev(mqd), "%s(%d) success\n", __func__, mqd->qid);
+
+out:
+ mutex_unlock(&mqd->lock);
+ return ret;
+}
+
+static int knav_qmssm_init_data(struct monitor_queue_dentry **mqd)
+{
+ struct knav_qmssm_qdata *data;
+ struct knav_qmssm *qmon;
+
+ if (!*mqd || !(*mqd)->mqe)
+ return -EINVAL;
+
+ qmon = (*mqd)->qmon;
+
+ data = devm_kzalloc(qmssm_dev(qmon), sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ (*mqd)->mqe->data = data;
+ data->mqd = *mqd;
+ data->property.buffsize = MONITOR_BS;
+ data->property.wmark[WM_MIN] = MONITOR_WMARK_MIN;
+ data->property.wmark[WM_LOW] = MONITOR_WMARK_LOW;
+ data->property.wmark[WM_HIGH] = MONITOR_WMARK_HIGH;
+ atomic_set(&data->property.enable, KNAV_QMSSM_DISABLE);
+ data->ring_buffer = NULL;
+ memset(&data->lchachee, 0, sizeof(data->lchachee));
+
+ return 0;
+}
+
+static int knav_qmssm_free_data(struct monitor_queue_dentry *mqd)
+{
+ struct knav_qmssm_qdata *data;
+
+ if (!mqd || !mqd->mqe)
+ return -EINVAL;
+
+ data = mqd->mqe->data;
+ mqd->mqe->data = NULL;
+
+ knav_qmssm_free_rb(data);
+ devm_kfree(mqd_dev(mqd), data);
+
+ return 0;
+}
+
+
+static int knav_qmssm_set_enable(void *d, u64 enable)
+{
+ struct monitor_queue_dentry *mqd = d;
+ int ret = 0;
+
+ if (enable == KNAV_QMSSM_ENABLE)
+ ret = knav_qmssm_start(mqd);
+ else if (enable == KNAV_QMSSM_DISABLE)
+ ret = knav_qmssm_stop(mqd);
+
+ return ret;
+}
+
+static int knav_qmssm_get_enable(void *d, u64 *enable)
+{
+ struct monitor_queue_dentry *mqd = d;
+ *enable = atomic_read(&property(mqd).enable);
+ return 0;
+}
+
+static int knav_qmssm_set_bufsize(void *d, u64 bufsize)
+{
+ struct monitor_queue_dentry *mqd = d;
+
+ mutex_lock(&mqd->lock);
+ if (atomic_read(&property(mqd).enable) == KNAV_QMSSM_ENABLE)
+ goto out;
+ property(mqd).buffsize =
+ bufsize > MONITOR_BS_MAX ? MONITOR_BS_MAX : bufsize;
+
+out:
+ mutex_unlock(&mqd->lock);
+ return 0;
+}
+
+static int knav_qmssm_get_bufsize(void *d, u64 *bufsize)
+{
+ struct monitor_queue_dentry *mqd = d;
+ struct ring_buffer *rb;
+ long size;
+
+ mutex_lock(&mqd->lock);
+ rb = mqd->mqe->data->ring_buffer;
+ if (rb)
+ size = ring_buffer_size(rb, smp_processor_id());
+ else
+ size = property(mqd).buffsize;
+ *bufsize = size;
+ mutex_unlock(&mqd->lock);
+ return 0;
+}
+
+/**
+ * knav_qmssm_set_watermark() - write watermark vector
+ */
+static ssize_t knav_qmssm_set_watermark(struct file *filp,
+ const char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct monitor_queue_dentry *mqd;
+ char buff[TEMP_BUFF_SIZE] = {0};
+ ssize_t len = 0;
+ int num = 0;
+ unsigned int wmark[NR_WATERMARK] = {0};
+ unsigned int i = 0;
+ int ret = count;
+
+ if (!filp || *ppos != 0)
+ return -EINVAL;
+
+ mqd = (struct monitor_queue_dentry *)filp->private_data;
+
+ if (count >= sizeof(buff))
+ return -ENOSPC;
+
+ mutex_lock(&mqd->lock);
+
+ len = simple_write_to_buffer(buff, sizeof(buff)-1, ppos, buffer, count);
+
+ if (len < 0) {
+ ret = len;
+ goto out;
+ }
+
+ buff[len] = '\n';
+
+ num = sscanf(buff, "%u %u %u",
+ &wmark[WM_MIN], &wmark[WM_LOW], &wmark[WM_HIGH]);
+ if (num != NR_WATERMARK) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < NR_WATERMARK; ++i) {
+ wmark[i] = wmark[i] < KNAV_QMSSM_WM_MIN ?
+ KNAV_QMSSM_WM_MIN : wmark[i];
+ wmark[i] = wmark[i] > KNAV_QMSSM_WM_MAX ?
+ KNAV_QMSSM_WM_MAX : wmark[i];
+ property(mqd).wmark[i] = wmark[i];
+ }
+out:
+ mutex_unlock(&mqd->lock);
+ return ret;
+}
+
+/**
+ * knav_qmssm_get_watermark() - read watermark vector
+ */
+static ssize_t knav_qmssm_get_watermark(struct file *filp,
+ char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct monitor_queue_dentry *mqd;
+ char buff[TEMP_BUFF_SIZE] = {0};
+ ssize_t len = 0;
+ int ret = 0;
+
+ if (*ppos != 0 || !filp)
+ return -EINVAL;
+
+ mqd = (struct monitor_queue_dentry *)filp->private_data;
+
+ mutex_lock(&mqd->lock);
+ len = snprintf(buff, TEMP_BUFF_SIZE, "%u %u %u\n",
+ property(mqd).wmark[WM_MIN],
+ property(mqd).wmark[WM_LOW],
+ property(mqd).wmark[WM_HIGH]);
+
+ if (count < strlen(buff)) {
+ ret = -ENOSPC;
+ goto out;
+ }
+ ret = simple_read_from_buffer(buffer, count, ppos, buff, len);
+out:
+ mutex_unlock(&mqd->lock);
+ return ret;
+}
+
+static ssize_t knav_qmssm_show_statistics(struct seq_file *filp, void *d)
+{
+ struct monitor_queue_dentry *mqd = filp->private;
+
+ if (!mqd)
+ return -EINVAL;
+
+ if (atomic_read(&property(mqd).enable) == KNAV_QMSSM_DISABLE) {
+ seq_printf(filp, "%s to enable use:\n", mqd->qmon->name);
+ seq_printf(filp, "echo 1 > /sys/kernel/debug/%s/%d/enable\n\n",
+ mqd->qmon->name, mqd->qid);
+ }
+
+ seq_puts(filp, "timestamp\t\t\tfdq number\tsubmit count\n");
+ knav_qmssm_read_rb(filp, mqd->mqe->data);
+
+ return 0;
+}
+
+static int knav_qmssm_open_statistics(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, knav_qmssm_show_statistics, inode->i_private);
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(queue_enable_fops, knav_qmssm_get_enable,
+ knav_qmssm_set_enable, "%llu\n");
+
+DEFINE_DEBUGFS_ATTRIBUTE(queue_bufsize_fops, knav_qmssm_get_bufsize,
+ knav_qmssm_set_bufsize, "%llu\n");
+
+static const struct file_operations knav_qmssm_watermark_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = knav_qmssm_get_watermark,
+ .write = knav_qmssm_set_watermark,
+};
+
+static const struct file_operations knav_qmssm_stats_fops = {
+ .owner = THIS_MODULE,
+ .open = knav_qmssm_open_statistics,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static inline bool knav_qmssm_int_queue(struct knav_queue *qh)
+{
+ unsigned int acc;
+
+ if (!qh)
+ return false;
+
+ acc = qh->inst->range->flags;
+ if (acc & RANGE_HAS_IRQ)
+ return true;
+
+ return false;
+}
+
+static int knav_qmssm_register_queue(void *arg, u64 qid)
+{
+ struct knav_qmssm *qmon = NULL;
+ struct monitor_queue_dentry *mqd = NULL;
+ struct monitor_queue_entry *mqe = NULL;
+ char hwq_monitor_qid[TEMP_BUFF_SIZE] = {0};
+ int ret = 0;
+ int len = 0;
+
+ if (!arg)
+ return -EINVAL;
+
+ qmon = (struct knav_qmssm *)arg;
+
+ if (qmon->kdev->num_queues <= qid)
+ return ret;
+
+ mutex_lock(&qmon->mqlock);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(mqd, &qmon->mqlist, list) {
+ if (qid == mqd->qid) {
+ dev_info(qmssm_dev(qmon),
+ "%llu already registered\n", qid);
+ ret = -EEXIST;
+ break;
+ }
+ }
+ rcu_read_unlock();
+ if (ret)
+ goto out0;
+
+ mqd = devm_kzalloc(qmssm_dev(qmon), sizeof(*mqd), GFP_KERNEL);
+ if (!mqd) {
+ ret = -ENOMEM;
+ goto out0;
+ }
+ len = snprintf(hwq_monitor_qid, TEMP_BUFF_SIZE, "%llu", qid);
+ hwq_monitor_qid[len] = '\0';
+
+ mqd->root_qid = debugfs_create_dir(hwq_monitor_qid, qmon->mq_root);
+ mqd->qid = qid;
+ mqd->qmon = qmon;
+ mutex_init(&mqd->lock);
+ mqd->mqe = NULL;
+ mqd->qh = knav_qmssm_get_queue(qmon->kdev, qid);
+ if (!mqd->qh)
+ goto out1;
+
+ if (knav_qmssm_int_queue(mqd->qh)) {
+
+ mqe = devm_kzalloc(qmssm_dev(qmon), sizeof(*mqe), GFP_KERNEL);
+ if (!mqe)
+ goto out1;
+
+ mqe->enable = debugfs_create_file(knav_qmssm_qid_enable,
+ 0660, mqd->root_qid, mqd, &queue_enable_fops);
+ mqe->wmark = debugfs_create_file(knav_qmssm_qid_wmark,
+ 0660, mqd->root_qid, mqd, &knav_qmssm_watermark_fops);
+ mqe->bufsize = debugfs_create_file(knav_qmssm_qid_bufsize,
+ 0660, mqd->root_qid, mqd, &queue_bufsize_fops);
+ mqe->monitor_stats = debugfs_create_file(knav_qmssm_qid_stats,
+ 0440, mqd->root_qid, mqd, &knav_qmssm_stats_fops);
+
+ mqd->mqe = mqe;
+
+ ret = knav_qmssm_init_data(&mqd);
+ if (ret)
+ goto out2;
+ }
+
+ list_add_rcu(&mqd->list, &qmon->mqlist);
+
+ knav_qmssm_dump(qmon);
+
+ mutex_unlock(&qmon->mqlock);
+
+ if (!qmon->ilogger.thread) {
+ ret = knav_qmssm_logger_start(qmon);
+ if (ret)
+ dev_err(qmssm_dev(qmon), "cannot run monitor thread\n");
+ }
+
+ dev_dbg(qmssm_dev(qmon), "%s(%d)\n", __func__, mqd->qid);
+
+ return PTR_INT(mqd);
+
+out2:
+ devm_kfree(qmssm_dev(qmon), mqe);
+
+out1:
+ debugfs_remove_recursive(mqd->root_qid);
+ devm_kfree(qmssm_dev(qmon), mqd);
+ ret = -EINVAL;
+ dev_err(qmssm_dev(qmon), "cannot initialize monitor data\n");
+
+out0:
+ mutex_unlock(&qmon->mqlock);
+ return ret;
+}
+
+static int knav_qmssm_unregister_queue_item(struct knav_qmssm *qmon,
+ struct monitor_queue_dentry *mqd)
+{
+ int ret = 0;
+
+ list_del_rcu(&mqd->list);
+ synchronize_rcu();
+
+ if (!mqd->mqe) {
+ dev_info(mqd_dev(mqd), "free not event-driven queue");
+ goto out;
+ }
+
+ ret = knav_qmssm_stop(mqd);
+ if (ret)
+ dev_err(qmssm_dev(qmon), "error stop monitoring\n");
+ dev_info(qmssm_dev(qmon), "stop event-driven queue\n");
+
+ ret = knav_qmssm_free_data(mqd);
+ if (ret)
+ dev_err(qmssm_dev(qmon), "error free monitoring data\n");
+
+ debugfs_remove_recursive(mqd->root_qid);
+
+ devm_kfree(qmssm_dev(qmon), mqd->mqe);
+
+ dev_dbg(qmssm_dev(qmon), "free event-driven queue %d", mqd->qid);
+
+out:
+ devm_kfree(qmssm_dev(qmon), mqd);
+
+ return ret;
+}
+
+static int knav_qmssm_unregister_queue(void *arg, u64 qid)
+{
+ struct knav_qmssm *qmon = NULL;
+ struct monitor_queue_dentry *mqd = NULL;
+ struct list_head *curr, *next;
+
+ if (!arg)
+ return -ENOENT;
+
+ qmon = (struct knav_qmssm *)arg;
+
+ mutex_lock(&qmon->mqlock);
+
+ if (list_empty(&qmon->mqlist)) {
+ dev_dbg(qmssm_dev(qmon), "no queues under monitoring\n");
+ goto out;
+ }
+
+ list_for_each_safe(curr, next, &qmon->mqlist) {
+
+ mqd = list_entry(curr, struct monitor_queue_dentry, list);
+ if (mqd->qid != qid)
+ continue;
+
+ knav_qmssm_unregister_queue_item(qmon, mqd);
+ break;
+ }
+
+ dev_dbg(qmssm_dev(qmon), "queue %llu unregistered\n", qid);
+
+out:
+ mutex_unlock(&qmon->mqlock);
+
+ if (list_empty(&qmon->mqlist))
+ knav_qmssm_logger_stop(qmon);
+
+ return 0;
+}
+
+static int knav_qmssm_setup_parm_base_queue(struct knav_qmssm *qmon)
+{
+ struct monitor_queue_dentry *mqd;
+ int i = 0, ret = 0;
+
+ dev_dbg(qmssm_dev(qmon), "%s %s %llu", __func__,
+ knav_qmssm_name,
+ knav_qmssm_interval_ms);
+
+ if (!knav_qmssm_name || strcmp(qmon->name, knav_qmssm_name))
+ return 0;
+
+ qmon->ilogger.interval_ms = knav_qmssm_interval_ms;
+
+ for (i = 0; i < MAX_BOOTIME_MQ && knav_qmssm_qid[i] > 0; i++) {
+ dev_dbg(qmssm_dev(qmon), "register boottime queue %d monitor %s\n",
+ knav_qmssm_qid[i], knav_qmssm_name);
+ ret = knav_qmssm_register_queue(qmon, knav_qmssm_qid[i]);
+ mqd = INT_PTR(ret);
+ if (IS_ERR(mqd))
+ continue;
+ knav_qmssm_start(mqd);
+ }
+
+ return 0;
+}
+
+static int knav_qmssm_set_interval(void *arg, u64 interval)
+{
+ struct knav_qmssm *qmon = arg;
+
+ qmon->ilogger.interval_ms = interval;
+
+ return 0;
+}
+
+static int knav_qmssm_get_interval(void *arg, u64 *interval)
+{
+ struct knav_qmssm *qmon = arg;
+
+ *interval = qmon->ilogger.interval_ms;
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(knav_register_queue_fops,
+ NULL, knav_qmssm_register_queue, "%llu\n");
+
+DEFINE_DEBUGFS_ATTRIBUTE(knav_unregister_queue_fops,
+ NULL, knav_qmssm_unregister_queue, "%llu\n");
+
+DEFINE_DEBUGFS_ATTRIBUTE(knav_interval_legger_fops,
+ knav_qmssm_get_interval, knav_qmssm_set_interval, "%llu\n");
+
+/**
+ * knav_qmssm_event_callback() - Main monitor handler callback
+ */
+void knav_qmssm_event_callback(void *arg)
+{
+ struct knav_queue *qh;
+ struct knav_queue *q_submit;
+ struct knav_device *kdev;
+ struct knav_qmssm *qmon;
+ struct monitor_queue_dentry *mqd;
+ struct knav_qmssm_record_item itm;
+
+ int count = 0;
+ int cdiff = 0, pdiff = 0;
+ uint16_t qid = 0;
+ int i = 0, j = 0;
+
+ qh = (struct knav_queue *)arg;
+ kdev = qh->inst->kdev;
+ qmon = kdev->qmon;
+ qid = knav_queue_device_control(qh, KNAV_QUEUE_GET_ID, 0);
+ if (!qh->monitor_cfg)
+ return;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(mqd, &qmon->mqlist, list) {
+
+ if (mqd->qid != qid)
+ continue;
+
+ for (i = 0; i < KNAV_QMSSM_FDQ_PER_CHAN; i++) {
+
+ if (!qh->monitor_cfg->fdq_arg[i])
+ break;
+
+ q_submit = qh->monitor_cfg->fdq_arg[i];
+ itm.count = knav_queue_device_control(q_submit,
+ KNAV_QUEUE_GET_COUNT, 0);
+ count = mqd->mqe->data->lchachee[i].count;
+
+ for (j = WM_MIN; j < NR_WATERMARK; j++) {
+
+ cdiff = property(mqd).wmark[j] - itm.count;
+ pdiff = property(mqd).wmark[j] - count;
+
+ if (!((cdiff < 0 && pdiff > 0) ||
+ (cdiff > 0 && pdiff < 0)))
+ continue;
+
+ itm.qid = knav_queue_device_control(q_submit,
+ KNAV_QUEUE_GET_ID, 0);
+ knav_qmssm_write_data(mqd->mqe->data, &itm);
+ memcpy(&mqd->mqe->data->lchachee[i],
+ &itm, sizeof(itm));
+ }
+ }
+ }
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL(knav_qmssm_event_callback);
+
+int knav_queue_enable_monitor(struct knav_queue *qh)
+{
+ if (!qh || WARN_ON(!qh->monitor_cfg))
+ return -EINVAL;
+
+ atomic_set(&qh->monitor_enabled, KNAV_QMSSM_ENABLE);
+
+ return 0;
+}
+
+int knav_queue_disable_monitor(struct knav_queue *qh)
+{
+ if (!qh || WARN_ON(!qh->monitor_cfg))
+ return -EINVAL;
+
+ atomic_set(&qh->monitor_enabled, KNAV_QMSSM_DISABLE);
+
+ return 0;
+}
+
+int knav_queue_set_monitor(struct knav_queue *qh,
+ struct knav_queue_monitor_config *cfg)
+{
+ int i = 0, j = 0, k = 0;
+ unsigned int qid;
+ bool diff;
+
+ if (!qh)
+ return -EINVAL;
+
+ if (!knav_qmssm_int_queue(qh))
+ return -ENOTSUPP;
+
+ knav_queue_disable_monitor(qh);
+
+ if (!cfg && qh->monitor_cfg) {
+ kzfree(qh->monitor_cfg);
+ return 0;
+ }
+
+ qh->monitor_cfg = kzalloc(sizeof(*(qh->monitor_cfg)), GFP_KERNEL);
+ if (!qh->monitor_cfg)
+ return -ENOMEM;
+
+ qh->monitor_cfg->fn = cfg->fn;
+ for (i = 0; i < KNAV_QMSSM_FDQ_PER_CHAN; i++) {
+
+ if (!cfg->fdq_arg[i])
+ continue;
+
+ diff = true;
+ for (j = 0; j < i; j++)
+ if (cfg->fdq_arg[i] == qh->monitor_cfg->fdq_arg[j]) {
+ diff = false;
+ break;
+ }
+
+ if (diff)
+ qh->monitor_cfg->fdq_arg[k++] = cfg->fdq_arg[i];
+ }
+
+ qid = knav_queue_device_control(qh, KNAV_QUEUE_GET_ID, 0);
+ dev_dbg(qh->inst->kdev->dev, "%s %d [%p %p %p %p]", __func__, qid,
+ qh->monitor_cfg->fdq_arg[0],
+ qh->monitor_cfg->fdq_arg[1],
+ qh->monitor_cfg->fdq_arg[2],
+ qh->monitor_cfg->fdq_arg[3]);
+
+ return 0;
+}
+
+void knav_qmssm_unregister(struct knav_device *kdev)
+{
+ struct list_head *cd, *nd;
+ struct list_head *cq, *nq;
+ struct knav_qmssm *qmon;
+ struct monitor_queue_dentry *mqd;
+
+ if (WARN_ON(!kdev))
+ return;
+
+ mutex_lock(&knav_qmssm_lock);
+
+ if (list_empty(&knav_qmssm_list))
+ goto out;
+
+ list_for_each_safe(cd, nd, &knav_qmssm_list) {
+
+ qmon = list_entry(cd, struct knav_qmssm, list);
+ if (qmon->kdev != kdev)
+ continue;
+
+ list_for_each_safe(cq, nq, &qmon->mqlist) {
+ mqd = list_entry(cq, struct monitor_queue_dentry, list);
+ knav_qmssm_unregister_queue_item(qmon, mqd);
+ }
+
+ debugfs_remove_recursive(qmon->mq_root);
+ list_del(cd);
+ kfree(qmon->name);
+ devm_kfree(qmssm_dev(qmon), qmon);
+ }
+out:
+ mutex_unlock(&knav_qmssm_lock);
+}
+EXPORT_SYMBOL(knav_qmssm_unregister);
+
+int knav_qmssm_register(struct knav_device *kdev)
+{
+ struct knav_qmssm *qmon = NULL;
+ int ret = 0;
+ int len = 0;
+
+ char buff[TEMP_BUFF_SIZE] = {0};
+
+ if (WARN_ON(!kdev))
+ return -ENODEV;
+
+ mutex_lock(&knav_qmssm_lock);
+
+ qmon = devm_kzalloc(kdev->dev, sizeof(*qmon), GFP_KERNEL);
+ if (!qmon) {
+ ret = -ENOSPC;
+ goto out;
+ }
+
+ qmon->kdev = kdev;
+
+ len = snprintf(buff, TEMP_BUFF_SIZE, "%s_%s", knav_qmssm_prefix,
+ dev_name(kdev->dev));
+ buff[len] = '\0';
+ qmon->name = kstrdup(buff, GFP_KERNEL);
+ if (!qmon->name) {
+ devm_kfree(kdev->dev, qmon);
+ goto out;
+ }
+
+ qmon->mq_root = debugfs_create_dir(buff, NULL);
+
+ qmon->mq_register = debugfs_create_file(knav_qmssm_register_str,
+ 0220, qmon->mq_root, qmon, &knav_register_queue_fops);
+
+ qmon->mq_unregister = debugfs_create_file(knav_qmssm_unregister_str,
+ 0220, qmon->mq_root, qmon, &knav_unregister_queue_fops);
+
+ qmon->ilogger.mq_interval = debugfs_create_file(knav_qmssm_interval,
+ 0220, qmon->mq_root, qmon, &knav_interval_legger_fops);
+
+ qmon->ilogger.interval_ms = MONITOR_INTERVAL_MS;
+
+ INIT_LIST_HEAD(&qmon->mqlist);
+ mutex_init(&qmon->mqlock);
+ list_add(&qmon->list, &knav_qmssm_list);
+ kdev->qmon = qmon;
+ dev_info(kdev->dev, "register %s\n", qmon->name);
+
+ knav_qmssm_setup_parm_base_queue(qmon);
+
+out:
+ mutex_unlock(&knav_qmssm_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(knav_qmssm_register);
diff --git a/drivers/soc/ti/knav_qmssm.h b/drivers/soc/ti/knav_qmssm.h
new file mode 100644
index 000000000000..5360ae9eca73
--- /dev/null
+++ b/drivers/soc/ti/knav_qmssm.h
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Texas Instruments Keystone Navigator Queue Management SubSystem
+ * Queue Managers Monitor Header
+ */
+
+#ifndef __KNAV_QMSSM_H
+#define __KNAV_QMSSM_H
+
+#include <linux/rbtree.h>
+#include <linux/rhashtable.h>
+#include <linux/ring_buffer.h>
+#include <linux/soc/ti/knav_qmss.h>
+#include "knav_qmss.h"
+
+enum knav_mqmss_watermark {
+ WM_MIN,
+ WM_LOW,
+ WM_HIGH,
+ NR_WATERMARK
+};
+
+#define KNAV_QMSSM_WM_MIN 1
+#define KNAV_QMSSM_WM_MAX 4096
+
+#define KNAV_QMSSM_ENABLE 1
+#define KNAV_QMSSM_DISABLE 0
+
+/*
+ * knav_qmssm_record_item - statistics entry descriptor
+ * qid - queue number
+ * count - keep amount of available descriptors in a hardware queue qid
+ */
+struct knav_qmssm_record_item {
+ uint16_t qid;
+ uint16_t count;
+} __packed;
+
+/*
+ * knav_qmssm_queue_property - describe property for queue under monitoring
+ * new features and functionality could be added here
+ * wmark - watermakr vector
+ * enable - enable tracing
+ * buffsize - sizeof buffer
+ */
+struct knav_qmssm_queue_property {
+ atomic_t enable;
+ unsigned int wmark[NR_WATERMARK];
+ unsigned int buffsize;
+};
+
+/*
+ * knav_qmssm_qdata - logical data struct to get/set property for queue
+ * property - property for this knav queue entry
+ * ring_buffer - buffer with collected statistics/logs
+ * lchachee - last cache entry keep entry from rb to calc logging threshold
+ * mqd - pointer to relative queue dentry
+ */
+struct knav_qmssm_qdata {
+ struct knav_qmssm_queue_property property;
+ struct ring_buffer *ring_buffer;
+ struct knav_qmssm_record_item lchachee[KNAV_QMSSM_FDQ_PER_CHAN];
+ struct monitor_queue_dentry *mqd;
+};
+
+/*
+ * struct monitor_queue_entry - descride extended entry
+ * wmark - dentry represent watermark file
+ * enable - interface to enable/disable statistics collection
+ * bufsize - change buffer size for current queue statistics collection
+ * monitor_statas - show collected statistics
+ * data - pointer to relative data
+ */
+struct monitor_queue_entry {
+ struct dentry *wmark;
+ struct dentry *enable;
+ struct dentry *bufsize;
+ struct dentry *monitor_stats;
+ struct knav_qmssm_qdata *data;
+};
+
+/*
+ * monitor_queue_dentry - struct represent item for registered queue
+ * list - link all registered queues for monitoring for current device
+ * qid - queue id number
+ * qh - keep knav queue
+ * lock - protect property access
+ * root_qid - root dentry for queue
+ * qmon - point to parent monitor device
+ */
+struct monitor_queue_dentry {
+ struct list_head list;
+ unsigned int qid;
+ struct knav_queue *qh;
+ struct mutex lock;
+ struct dentry *root_qid;
+ struct monitor_queue_entry *mqe;
+ struct knav_qmssm *qmon;
+};
+
+/*
+ * struct knav_qmssm_ilogger - interval logger periodic interval monitor
+ * thread - kthread descriptor
+ * mq_interval - dentry descriptor for interval
+ * interval_ms - interval define monitor thread work cycle
+ */
+struct knav_qmssm_ilogger {
+ struct task_struct *thread;
+ struct dentry *mq_interval;
+ u64 interval_ms;
+};
+
+/*
+ * knav_qmssm - describe monitor for hardware queue device
+ * hdev - device which is under monitoring
+ * name - monitor instance name
+ * mqlist - monitoring queues list queue_dentry HEAD is a list to keep queues
+ * mqlock - protect for each list mqd for current device monitor
+ * list - link hardware queue devices monitors in a list
+ * mq_root - hwq_monitor_%device_name% root debugfs dentry for monitored device
+ * mq_register - interface for new queue register to monitor
+ * mq_unregister - interface for queue unregister and stop monitoring
+ * ilogger - interval thread logger for monitor device
+ */
+struct knav_qmssm {
+ struct knav_device *kdev;
+ unsigned char *name;
+ struct list_head mqlist;
+ struct mutex mqlock;
+ struct list_head list;
+ struct dentry *mq_root;
+ struct dentry *mq_register;
+ struct dentry *mq_unregister;
+ struct knav_qmssm_ilogger ilogger;
+};
+
+int knav_queue_enable_monitor(struct knav_queue *qh);
+int knav_queue_disable_monitor(struct knav_queue *qh);
+int knav_queue_set_monitor(struct knav_queue *qh,
+ struct knav_queue_monitor_config *mcfg);
+
+int knav_qmssm_register(struct knav_device *kdev);
+void knav_qmssm_unregister(struct knav_device *kdev);
+
+#endif /*__KNAV_QMSSM_H*/
diff --git a/include/linux/soc/ti/knav_qmss.h b/include/linux/soc/ti/knav_qmss.h
index 9745df6ed9d3..cc7cf27f58b3 100644
--- a/include/linux/soc/ti/knav_qmss.h
+++ b/include/linux/soc/ti/knav_qmss.h
@@ -34,6 +34,8 @@
/* queue flags */
#define KNAV_QUEUE_SHARED 0x0001 /* Queue can be shared */
+#define KNAV_QMSSM_FDQ_PER_CHAN 4
+
/**
* enum knav_queue_ctrl_cmd - queue operations.
* @KNAV_QUEUE_GET_ID: Get the ID number for an open queue
@@ -49,7 +51,9 @@ enum knav_queue_ctrl_cmd {
KNAV_QUEUE_SET_NOTIFIER,
KNAV_QUEUE_ENABLE_NOTIFY,
KNAV_QUEUE_DISABLE_NOTIFY,
- KNAV_QUEUE_GET_COUNT
+ KNAV_QUEUE_GET_COUNT,
+ KNAV_QUEUE_SET_MONITOR,
+ KNAV_QUEUE_ENABLE_MONITOR
};
/* Queue notifier callback prototype */
@@ -65,6 +69,19 @@ struct knav_queue_notify_config {
void *fn_arg;
};
+/* Queue monitor callback prototype */
+typedef void (*knav_queue_monitor_fn)(void *arg);
+
+/**
+ * struct knav_queue_moncfg: Monitor configuration
+ * @fn: Monitor function
+ * @fdq_arg: Monitor fdq
+ */
+struct knav_queue_monitor_config {
+ knav_queue_monitor_fn fn;
+ void *fdq_arg[KNAV_QMSSM_FDQ_PER_CHAN];
+};
+
void *knav_queue_open(const char *name, unsigned id,
unsigned flags);
void knav_queue_close(void *qhandle);
--
2.14.1
^ permalink raw reply related
* Re: [PATCH net-next v3 05/17] zinc: ChaCha20 x86_64 implementation
From: Jason A. Donenfeld @ 2018-09-11 21:12 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Samuel Neves, LKML, Netdev, David Miller, Greg Kroah-Hartman,
Andrew Lutomirski, Jean-Philippe Aumasson, Andy Polyakov, mingo,
X86 ML, Linux Crypto Mailing List
In-Reply-To: <alpine.DEB.2.21.1809111106420.5110@nanos.tec.linutronix.de>
Hey Thomas,
On Tue, Sep 11, 2018 at 3:09 AM Thomas Gleixner <tglx@linutronix.de> wrote:
> > This is covered on the 02/17 commit message, whose relevant paragraph follows:
> Well, being only cc'ed on only half of the patches does not really help.
Sorry about that. I'm happy to Cc you on the whole series for next
round if you want. Just let me know. In the meantime:
https://patchwork.ozlabs.org/project/netdev/list/?series=65056
https://lore.kernel.org/lkml/20180911010838.8818-1-Jason@zx2c4.com/T/
Regards,
Jason
^ permalink raw reply
* Re: [PATCH net-next v3 17/17] net: WireGuard secure network tunnel
From: Jason A. Donenfeld @ 2018-09-11 21:08 UTC (permalink / raw)
To: Andrew Lunn; +Cc: LKML, Netdev, David Miller, Greg Kroah-Hartman
In-Reply-To: <20180911133017.GJ30395@lunn.ch>
Hello Andrew,
On Tue, Sep 11, 2018 at 7:30 AM Andrew Lunn <andrew@lunn.ch> wrote:
> I don't know if any of the crypto people are reviewing the networking
> code, but i don't think there are many networking people reviewing the
> crypto code.
>
> So please can you put the change log between versions for the
> networking code here, where we can easily see it.
All submissions >v1 have had a changelog in the 00/17 commit.
> I see you have yet again completely ignored my request to either
> 1) Remove the inline
> 2) Argue why it should be kept.
Most uses of inline are this way after checking the compiler output on
several platforms. (Generally my build-run-test cycle is actually
build-IDAPro-run-test.) If you feel that's been done too liberally,
I'm happy to spend time rechecking each use case.
^ 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