Page 1 of 1

possible to emulate 'xadd' instruction under i386?

Posted: Sun Dec 29, 2013 3:05 pm
by miaowei
Intel cpu older than 486 doesn't support xadd, but this is the core operation to implement atomic functions such as 'atomic_add_return'.the following is how linux emulates 'xadd' for i386. but I doubt it isn't rigorous:
-----------------------------
static inline int atomic_add_return(int i, atomic_t *v)
{
#ifdef CONFIG_M386
int __i;
unsigned long flags;
if (unlikely(boot_cpu_data.x86 <= 3))
goto no_xadd;
#endif
/* Modern 486+ processor */
return i + xadd(&v->counter, i);

#ifdef CONFIG_M386
no_xadd: /* Legacy 386 processor */
raw_local_irq_save(flags);
__i = atomic_read(v);
atomic_set(v, i + __i);
raw_local_irq_restore(flags);
return i + __i;
#endif
}
-----------------------------

the code snippet above use 'atomic_set' immediately following a 'atomic_read' to emulate the 'atomic_add', is it OK? Will two atomic operations make up one atomic operation? Is there a chance that another CPU does a write-operation to 'v' after this 'atomic_read' and before the 'atomic_set'?

Re: possible to emulate 'xadd' instruction under i386?

Posted: Sun Dec 29, 2013 3:13 pm
by rdos
The issue probably is that there is no multiprocessor i386 systems to support, so it will work even if it wouldn't be correct on a multicore CPU.

Re: possible to emulate 'xadd' instruction under i386?

Posted: Sun Dec 29, 2013 3:55 pm
by iansjack
No. There certainly were, and probably still are, multiple processor 386 systems. I'm not sure how Linux guarantees atomic operations on such systems. Perhaps there is something in atomic variables that was implemented to ensure this on a 386. An interesting topic to look into further. (Though totally irrelevant now as the latest Linux kernels do not support anything earlier than an 80486.)

Re: possible to emulate 'xadd' instruction under i386?

Posted: Sun Dec 29, 2013 4:14 pm
by iansjack
After a bit of research I think the answer is that although PCs with multiple 386 processors existed they were asymmetric rather than symmetric. Thus the problem doesn't arise. The code given in the OP is, for a 386, intended to preserve atomicity between tasks rather than processors.

So, apologies to rdos - you were partially correct!

Re: possible to emulate 'xadd' instruction under i386?

Posted: Sun Dec 29, 2013 5:27 pm
by Owen
The earliest x86 CPUs with APIC support are 486s. Nobody still implements support for any of the multiprocessor systems which existed back then - they were rare then and I'd be very interested to see any which still exist and work.

Re: possible to emulate 'xadd' instruction under i386?

Posted: Mon Dec 30, 2013 12:21 am
by miaowei
Maybe this developer is responsible for poiniting out this in the comment.

Re: possible to emulate 'xadd' instruction under i386?

Posted: Mon Dec 30, 2013 1:51 am
by iansjack
Explanation of this sort of detail is, IMO, not suitably dealt with in a comment. [strike]It is explained in the kernel documentation, which seems to be the appropriate place. It's a subtle point which might occur at various places in the source; it would be counterproductive to explain it each time.

If you want to understand the kernel code it pays to study the documentation as well as the source itself.[/strike]

(Sorry. I've just realized that that was addressing a related point, but not the one you made.)

I don't think there would be any point in explaining that this code wouldn't work in an 80386 SMP setup when no such setup exists. It's rather similar to asking that a book on horse-riding explain why a particular technique wouldn't work on a unicorn. Or perhaps it would be closer to say that it is similar to asking for a comment explaining why this code wouldn't work on an SMP Z80 system.

Additionally, as I said previously, the Linux kernel doesn't support the 80386 nowadays anyway.

(In case you think this unreasonable, I would refer you to the Linux SMP HowTo - http://www.tldp.org/HOWTO/pdf/SMP-HOWTO.pdf - which explains which processors support SMP.)

Re: possible to emulate 'xadd' instruction under i386?

Posted: Thu Jan 02, 2014 4:33 pm
by Combuster
miaowei wrote:the code snippet above use 'atomic_set' immediately following a 'atomic_read' to emulate the 'atomic_add', is it OK? Will two atomic operations make up one atomic operation? Is there a chance that another CPU does a write-operation to 'v' after this 'atomic_read' and before the 'atomic_set'?
There are a lot of requirements to make something that's not originally atomic appear that way. On x86 there's memory atomicity if the accessed memory in question is uncacheable, a LOCK prefix is used, or no other execution unit could possibly accesses that memory. On an i386 using any RAM that's not involved in DMA is sufficient to achieve read-write atomicity.

The next problem is that the processor itself is atomic on an per-instruction basis, and interrupts, exceptions and the like can interrupt that operation and perform other things (including possible other emulated xadds), so you'll need to do something like disabling interrupts to eliminate the probable causes as well. The code in question does not explicitly fixes this requirement (unless the naming is just poor), so it might not actually be atomic unless interrupts are disabled beforehand (maybe because it was called from the context of a system call).

That's about what you should be looking out for. doing something like cli; mov; add; mov; sti; is typically sufficient for emulation purposes.

Re: possible to emulate 'xadd' instruction under i386?

Posted: Thu Jan 02, 2014 6:10 pm
by Octocontrabass
Combuster wrote:The code in question does not explicitly fixes this requirement (unless the naming is just poor), so it might not actually be atomic unless interrupts are disabled beforehand (maybe because it was called from the context of a system call).
Poor naming. The function to save flags also disables interrupts.