Re: Fwd: Locking with per-cpu variables

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 16 Oct 2005, Aritz Bastida wrote:

* I asked what would happen if I am resetting a counter (actually the
whole struct with memset) in one CPU while the other one is updating
it. What would be the worst thing it could happen?

That some counters are not reset properly.

For example, if the counter is of type long (64 bytes), could it
happen that one CPU updates upper 32 bytes while the other CPU clears
lower 32 bytes, thus corrupting the counter's value?

(I assume you meant bits not bytes above..)

Yes, that is a possible effect on 32-bit systems. Which part gets corrupted is dependent on endianness.

Any datatype larger than the basic word size of the architecture needs special care. You can only do completely lockless operations on counters up to the word size.

No, without locking or serialization by doing the reset from the
per-cpu thread the reset can be lost.

Why would be lost? In any case, the result would be strange, no?

Example:
CPU0 is incrementing the counter
CPU1 is resetting the counter

reg = some cpu register
counter = the counter memory location

CPU0                    CPU1
reg = counter
reg = reg + 1           counter = 0
counter = reg


In the above the reset is lost as it is overwritten by the store of the incremented counter.

If the counter is of a larger type where the hardware does not do atomic store/write operations then very strange effects can be seen, such as the half cleared counter you mentioned above.



As we both mentioned to avoid this you do not clear the per-cpu counters directly. Instead you just set a flag in the per-cpu data indicating that the counters should be cleared and let the per-cpu thread clear the actual counters and reset the flag the next time it is run. If you need to read the per-cpu counters before them, read them as zero if the flag is still set.



This all mentioned, there is already a percpu_counter primitive in the Linux kernel (2.6) which tries to make a reasonable tradeoff for common use. Today that function is pretty much optimized for read-mostly counters on either UP-systems (then reduces to a plain counter) or large scale SMP systems with very many CPUs. This primitive gives you a jitter exponential to the number of CPUs you have.

The Linux kernel per_cpu_counter implementation is perhaps slightly more complex than it needs to be for the more common small to medium sized SMP systems, and also not optimal for write mostly counters. But quite good balanced for general purpose.

The Linux kernel percpu_counter is defined in include/linux/percpu_counter.h

Regards
Henrik
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux