On 2020-12-07, Peter Zijlstra <[email protected]> wrote:
>> Yes, and it is read-only access. Perhaps atomic64_t is the wrong thing
>> to use here. We could use a seqcount_latch and a shadow variable so that
>> if a writer has been preempted, we can use the previous value. (Only
>> kmsg_dump would need to use the lockless variant to read the value.)
>> 
>> void clear_seq_set(u64 val)
>> {
>>         spin_lock_irq(&clear_lock);
>>         raw_write_seqcount_latch(&clear_latch);
>>         clear_seq[0] = val;
>>         raw_write_seqcount_latch(&clear_latch);
>>         clear_seq[1] = val;
>>         spin_unlock_irq(&clear_lock);
>> }
>> 
>> u64 clear_seq_get_nolock(void)
>> {
>>         unsigned int seq, idx;
>>         u64 val;
>> 
>>         do {
>>                 seq = raw_read_seqcount_latch(&clear_latch);
>>                 idx = seq & 0x1;
>>                 val = clear_seq[idx];
>>         } while (read_seqcount_latch_retry(&clear_latch, seq));
>> 
>>         return val;
>> }
>
> That's overly complicated.
>
> If you're going to double the storage you can simply do:
>
>
>       seq = val
>       smp_wmb();
>       seq_copy = val;
>
> vs
>
>       do {
>               tmp = seq_copy;
>               smp_rmb();
>               val = seq;
>       } while (val != tmp);

That will not work. We are talking about a situation where the writer is
preempted. So seq will never equal seq_copy in that situation. I expect
that the seqcount_latch is necessary.

John Ogness

Reply via email to