🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.unix.programmer
Article #3485

SysV shared memory coherency issues

#3485
From: Ryan Underwood
Date: Mon, 13 Feb 2006 22:30
102 lines
7115 bytes
[This is crossposted to comp.lang.asm.x86 due to the instruction level issue
below]

Hi,
I'm getting really puzzled here.  The basic story is that we have a 4 way Xeon
machine with hyperthreading enabled (8 logical processors).  The application is
a fairly straightforward SysV (not POSIX) shared memory application.  The
shared memory region is declared as a volatile double *.  We are using GCC
4.0.2 with -O0 and a 2.6.6 Linux kernel with RTLinux extensions.

One of the processes sets up essentially a RPC call by placing several double
arguments in the shared memory region along with a function ID, and then
setting a flag to notify the other process that a call is waiting.  The other
process is doing soft-realtime computational work as fast as it can with no
system calls, and occasionally checks the flag mailbox to see if a RPC is
waiting.  If it is, then it reads the function ID and arguments and goes to
work on that task.

This seemed to work fine in my test cases, but eventually broke down for a
different user.  The shared memory is written to and verified by the writer
process, but the computation process _never_ "sees" the flag even if allowed to
run forever.  I can get the computation process to "see" the flag in several
ways:

1) Insert a sleep of between 1 and 10ms before the flag is polled (less than
1ms is not sufficient)

2) Print the contents of the mailbox on the computation process side before
polling the flag

Running under gdb or valgrind does not affect the bug.

Based on the above, my hypothesis is that in the cases where the condition
improves, it is because a system call has been taken, and thus the registers
clobbered.  In the case where the sleep is insufficient, I think it is because
short sleep durations are executed as busy waits instead of forfeiting the
processor.

However, as a matter of experimentation, I changed the memory access in the
computation process from:

	if (m_Mailbox[STALE_MBOX] != 1)
		{ /* these actions are never taken */ }

which generated the following assembly:

	movl    8(%ebp), %eax   # this, this
	movl    32(%eax), %eax  # <variable>.m_Mail
	addl    $288, %eax      #, D.40882
	fldl    (%eax)  #* D.40882
	fld1

to: [with knowledge that sizeof(double)==2*sizeof(uint32_t)]

	if (((uint32_t*)m_Mailbox)[STALE_MBOX*2] != 1)
		{ /* these actions are taken when mbox value is set to 0 */ }

which generated the following assembly:

	movl    8(%ebp), %eax   # this, this
	movl    32(%eax), %eax  # <variable>.m_Mail
	addl    $288, %eax      #, D.40882
	movl    (%eax), %eax    #* D.40882, D.40883
	cmpl    $1, %eax        #, D.40883

As you can see, the load changes from a floating point to an integer load.  To
my utter astonishment, this corrected the symptom that I was observing.
Apparently the memory access semantics of integer and FP loads differ in some
way on these processors.  But is this actually the root of the problem, or is
there a more fundamental issue I am failing to understand?  And is the issue
specific to the SysV shared page implementation (meaning I should look into
POSIX shared memory, pthreads, or mmap instead), or is it a processor-level
issue, perhaps with hyperthreading?

I was advised that I need memory barriers in this application for two reasons:

1) to keep the cache consistent across processors
2) because the mailbox writes may be reordered, meaning that even if the other
process saw the flag, there would be no guarantee that the function argument
writes had been performed yet.

If memory barrier functionality even exists on the IA-32 platform I don't seem
to be finding a way to access it from userspace.  I am under the impression
that all operations on IA-32 are cache-coherent, and did not believe
hyperthreading changed that.  Also, the wmb() macros in the Linux kernel seem
to evaluate to void for IA-32, supporting my position that memory barriers are
unnecessary in this case (that the writes, even if reordered when issued, are
committed in program order):

 * For now, "wmb()" doesn't actually do anything, as all
 * Intel CPU's follow what Intel calls a *Processor Order*,
 * in which all writes are seen in the program order even
 * outside the CPU.
#define wmb()   __asm__ __volatile__ ("": : :"memory")

I'm having a difficult time seeing how this application differs from a typical
pthreads application, except in this case we only share specific preallocated
physical pages, instead of the entire page table of the parent process.

Looking forward to your thoughts,

Ryan Underwood
Technical Details
Message-ID: <-Z-dneLPKKkNlWzeRVn-oQ@fidnet.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!news2.google.com!fu-berlin.de!border2.nntp.ams.giganews.com!border1.nntp.ams.giganews.com!nntp.giganews.com!sn-ams-06!sn-xt-ams-03!sn-post-ams-01!sn-post-01!supernews.com!corp.supernews.com!news.crayne.org!clax86!robomod!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Thread: fc89c,83404d35faeda18b,start
X-Google-Thread: f5392,83404d35faeda18b,start
X-Google-Thread: 11318c,83404d35faeda18b,start
X-Google-Thread: 114917,83404d35faeda18b,start
X-Google-Attributes: gidfc89c,gidf5392,gid11318c,gid114917,public
X-Google-Language: ENGLISH,ASCII-7-bit
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!news2.google.com!fu-berlin.de!border2.nntp.ams.giganews.com!border1.nntp.ams.giganews.com!nntp.giganews.com!sn-ams-06!sn-xt-ams-03!sn-post-ams-01!sn-post-01!supernews.com!corp.supernews.com!news.crayne.org!clax86!robomod!not-for-mail
From: Ryan Underwood  <spamtrap@crayne.org>
Newsgroups: comp.unix.programmer,comp.os.linux.development.system,gnu.gcc.help,comp.lang.asm.x86
Subject: SysV shared memory coherency issues
Approved: CLAX86 Moderators <ccrayne@crayne.org>
Date: Mon, 13 Feb 2006 16:30:40 -0600
Organization: Crayne Consulting
Message-ID: <-Z-dneLPKKkNlWzeRVn-oQ@fidnet.com>
Sender: clax86@wotan.crayne.org
X-CLAX86-Policy: http://www.pacificsites.com/~ccrayne/clax86.html
X-CLAX86-Faq: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.asm.x86.html
X-CLAX86-Info-1: Send submissions to comp-lang-asm-x86@moderators.isc.org
X-CLAX86-Info-2: Send technical complaints to clax86-admin@crayne.org
X-CLAX86-Info-3: Send complaints about policy to clax86-admin@crayne.org
X-Comment: moderators do not necessarily agree or disagree with this article.
X-Authentication-Warning: serv3.gc.dca.giganews.com: news set sender to poster@giganews.com using -f
User-Agent: nn/6.7.2
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.32
X-Greylisting: NO DELAY (Relay+Sender autoqualified);
 processed by UCSD_GL-v2.1 on mailbox7.ucsd.edu;
 Mon, 13 February 2006 14:30:43 -0800 (PST)
X-Spam-Level: Level 
X-Spamscanner: mailbox7.ucsd.edu  (v1.6 Aug  4 2005 15:27:38, 0.0/5.0 3.0.4)
X-MailScanner: PASSED (v1.2.8 51381 k1DMUg0l088744 mailbox7.ucsd.edu)
X-PacificInternet-MailScanner-Information: Please contact the ISP for more information
X-PacificInternet-MailScanner: Found to be clean
X-PacificInternet-MailScanner-SpamCheck: not spam (whitelisted),
 SpamAssassin (score=-0.001, required 5.5, autolearn=disabled,
 SPF_HELO_PASS -0.00)
X-PacificInternet-MailScanner-From: poster@giganews.com
X-Spam-Status: No
X-UIDL: ;C$#!7>^"!YZ1"!d+a"!
X-Complaints-To: abuse@supernews.com
Lines: 103