Re: [PATCH v3 49/56] refcount.h: fix a kernel-doc markup

Mauro Carvalho Chehab
2020-10-24T06:28:35Z

Em Fri, 23 Oct 2020 13:47:57 -0600
Jonathan Corbet <corbet@lwn.net> escreveu:

> On Fri, 23 Oct 2020 21:39:07 +0200
> Peter Zijlstra <peterz@infradead.org> wrote:
>
> > > > /**
> > > > - * struct refcount_t - variant of atomic_t specialized for reference counts
> > > > + * struct refcount_struct - variant of atomic_t specialized for reference counts
> > >
> > > Hm, this is a weird one. Yes, it's actually "struct refcount_struct",
> > > but the usage should be refcount_t (through the typedef). I'm not sure
> > > what the right way to document this is.
> >
> > Yeah, this is wrong. If this is due to a kernel doc warning, the kernel
> > doc machinery is wrong *again*.

This issue has nothing to do with warnings. The problem here is that
"struct" is a markup for structs, and not for typedefs.

>
> ...except that, since refcount_t is a typedef, "struct refcount_t" doesn't
> actually exist. Whether it works properly after doing s/struct// remains
> to be seen...

If the intent is to document the struct and its internal fields,
this kernel-doc should work:

/**
* struct refcount_struct - variant of atomic_t specialized for reference counts
* @refs: atomic_t counter field
*
* The counter saturates at REFCOUNT_SATURATED and will not move once
* there. This avoids wrapping the counter and causing 'spurious'
* use-after-free bugs.
*/

Which produces this result:

.. c:struct:: refcount_struct

variant of atomic_t specialized for reference counts

**Definition**

::

struct refcount_struct {
atomic_t refs;
};

**Members**

``refs``
atomic_t counter field

(description)

See, in this case, the identifier is not opaque: its members are
documented at the html (or man) output.

If you want, instead, to document the typedef, this is the
proper way:

/**
* typedef refcount_t - variant of atomic_t specialized for reference counts
*
* The counter saturates at REFCOUNT_SATURATED and will not move once
* there. This avoids wrapping the counter and causing 'spurious'
* use-after-free bugs.
*/

It will handle this one as an opaque type, meaning that it won't be
showing the "refs" field - even if you forget to drop the @refs:
at the markup. The result will be:

.. c:type:: refcount_t

variant of atomic_t specialized for reference counts

(description)

-

If you want both, then you would either split struct and typedef, e. g.
with something like:

/**
* struct refcount_struct - variant of atomic_t specialized for reference counts
* @refs: atomic_t counter field
*
* The counter saturates at REFCOUNT_SATURATED and will not move once
* there. This avoids wrapping the counter and causing 'spurious'
* use-after-free bugs.
*/
struct refcount_struct {
atomic_t refs;
};

/**
* typedef refcount_t - variant of atomic_t specialized for reference counts
* @refs: atomic_t counter field
*
* The counter saturates at REFCOUNT_SATURATED and will not move once
* there. This avoids wrapping the counter and causing 'spurious'
* use-after-free bugs.
*/
typedef struct refcount_struct refcount_t;

Or, you could add the member at the description field. E. g. something
like this:

/**
* typedef refcount_t - variant of atomic_t specialized for reference counts
*
* The counter saturates at REFCOUNT_SATURATED and will not move once
* there. This avoids wrapping the counter and causing 'spurious'
* use-after-free bugs.
*
* Members:
* ``refs``
* atomic_t counter field
*/
typedef struct refcount_struct {
atomic_t refs;
} refcount_t;

If you want to test it, you can run kernel-doc directly, to see how
it will parse it. For ReST output, that's the syntax:

./scripts/kernel-doc --sphinx-version 3 include/linux/refcount.h

Thanks,
Mauro