|
|
Message-ID: <CAEXv5_jnsM8z9kNF5Woq-u3m2_Wi3Lnep-aWKNqzULHSqvF0EQ@mail.gmail.com>
Date: Wed, 7 Dec 2016 14:03:16 -0500
From: David Windsor <dwindsor@...il.com>
To: Peter Zijlstra <peterz@...radead.org>
Cc: Boqun Feng <boqun.feng@...il.com>, Kees Cook <keescook@...omium.org>,
"Reshetova, Elena" <elena.reshetova@...el.com>,
"kernel-hardening@...ts.openwall.com" <kernel-hardening@...ts.openwall.com>, Greg KH <gregkh@...uxfoundation.org>,
"will.deacon@....com" <will.deacon@....com>, Hans Liljestrand <ishkamiel@...il.com>,
"aik@...abs.ru" <aik@...abs.ru>, "david@...son.dropbear.id.au" <david@...son.dropbear.id.au>
Subject: Re: Conversion from atomic_t to refcount_t: summary of issues
On Wed, Dec 7, 2016 at 8:24 AM, Peter Zijlstra <peterz@...radead.org> wrote:
> On Fri, Dec 02, 2016 at 03:25:42PM -0500, David Windsor wrote:
>> On Thu, Dec 1, 2016 at 8:17 PM, Boqun Feng <boqun.feng@...il.com> wrote:
>
>> > So we currently don't have a clear semantics for stats_t, do we?
>>
>> We had a discussion about the stats_t API in another thread. We
>> agreed upon add(), sub(), inc(), dec(), read() and set().
>>
>> > What kind of atomic_t should be replaced with stats_t?
>>
>> stats_t is used for those cases in which an atomic variable is
>> required, but the overflow of this variable isn't of much concern.
>> Typically, these types of variables are counters of some kind (rx/tx
>> counts, etc), but not always. Perhaps "stats_t" isn't the best type
>> name. We actually used "atomic_wrap_t" in previous iterations.
>
> And atomic_wrap_t is a horrid trainwreck. Please as to explain the
> semantics of atomic_wrap_cmpxchg(). How does wrapping apply to something
> that doesn't do sign bits.
>
atomic_wrap_t grew out of a desire to fix an already broken system for
doing reference counting. atomic_t is being widely used for both
reference counting (which should not overflow), non-reference
counting, and other operations. atomic_wrap_t provides the semantics
of the "original" atomic_t: atomic operations with no overflow
protection. Thus, atomic_wrap_cmpxchg(): the cmpxchg operation for
atomic_wrap_t types. Abominations like this sometimes exist in RFC
series. In this case, we came up with the atomic_wrap API by mostly
creating an atomic_wrap-ified version of each atomic_t API function.
>> > In the link David pointed out, there are a few cases where a
>> > stats_t is put on a correctness-related variable. I don't think
>> > that's a good place to use stats_t.
>> >
>>
>> Yeah, I just grabbed a few examples I noted during my stats_t
>> conversion work. The drivers/ tree is littered with stats_t
>> instances.
>
> Not sure how to respond to this, if you're converting all that to
> stats_t then you're doing it wrong.
>
> Most of what you showed should very emphatically not be stats_t.
>
Yes, none of those examples were appropriate. My apologies; they were
quickly chosen from a pool of potential stats_t conversions.
Further audit of atomic_wrap_t indicates that much of what we marked
as atomic_wrap_t are actually things like sequence numbers, IDs, etc.
Examples:
http://lxr.free-electrons.com/source/include/linux/padata.h#L132
struct parallel_data.seq_nr
http://lxr.free-electrons.com/source/fs/btrfs/delayed-inode.h#L46
struct btrfs_delayed_root.items_seq
http://lxr.free-electrons.com/source/drivers/ata/libata-core.c#L108
ata_print_id
These "identifier" types make up a good number of atomic_wrap_t cases.
With respect to stats_t variables, here are two more examples.
First, cm_listens_created and cm_listens_destroyed from
drivers/infiniband/hw/nes/nes_cm.c:
http://lxr.free-electrons.com/source/drivers/infiniband/hw/nes/nes_cm.c#L72.
Only atomic_inc() and atomic_read() are used on these variables:
http://lxr.free-electrons.com/source/drivers/infiniband/hw/nes/nes_cm.c#L3499
atomic_inc(&cm_listens_created);
http://lxr.free-electrons.com/source/drivers/infiniband/hw/nes/nes_cm.c#L1336
atomic_inc(&cm_listens_destroyed);
http://lxr.free-electrons.com/source/drivers/infiniband/hw/nes/nes_nic.c#L1284
target_stat_values[++index] = atomic_read(&cm_listens_created);
http://lxr.free-electrons.com/source/drivers/infiniband/hw/nes/nes_nic.c#L1285
target_stat_values[++index] = atomic_read(&cm_listens_destroyed);
Next, struct irq_desc.threads_handled. It is defined in
include/linux/irqdesc.h and, in the struct's comments, is described
as, "[a] stats field for deferred spurious detection of threaded
handlers."
Only atomic_inc() and atomic_read() are called to manage this variable:
atomic_read():
kernel/irq/spurious.c:
handled = atomic_read(&desc->threads_handled);
irq_desc.threads_handled is part of threaded interrupt handlers and is
incremented in irq_thread():.
atomic_inc():
kernel/irq/manage.c:949
static int irq_thread(void *data)
{
....
while (!irq_wait_for_interrupt(action)) {
irqreturn_t action_ret;
irq_thread_check_affinity(desc, action);
action_ret = handler_fn(desc, action);
if (action_ret == IRQ_HANDLED)
atomic_inc(&desc->threads_handled);
...
}
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.