all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Mark H Weaver <mhw@netris.org>
To: "Ludovic Courtès" <ludo@gnu.org>
Cc: Andy Wingo <wingo@igalia.com>, 28211@debbugs.gnu.org
Subject: bug#28211: Stack marking issue in multi-threaded code
Date: Fri, 29 Jun 2018 12:54:47 -0400	[thread overview]
Message-ID: <87in61y1m0.fsf@netris.org> (raw)
In-Reply-To: <87a7rdvdm9.fsf_-_@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\?\= \=\?utf-8\?Q\?\=22's\?\= message of "Fri, 29 Jun 2018 17:03:42 +0200")

Hi Ludovic,

ludo@gnu.org (Ludovic Courtès) writes:

> I have a fix for some (most?) of the crashes we were seeing while
> running multi-threaded code such as (guix build compile), and,
> presumably, the grafting code mentioned at the beginning of this bug
> report, although I haven’t checked yet.
>
> So, ‘scm_i_vm_mark_stack’ marks the stack precisely, but contrary to
> what I suspected, precise marking is not at fault.
>
> Instead, the problem has to do with the fact that some VM instructions
> change the frame pointer (vp->fp) before they have set up the dynamic
> link for that new frame.
>
> As a consequence, if a stop-the-world GC is triggered after vp->fp has
> been changed and before its dynamic link has been set, the stack-walking
> loop in ‘scm_i_vm_mark_stack’ could stop very early, leaving a lot of
> objects unmarked.
>
> The patch below fixes the problem for me.  \o/

That's great news!  Thanks for investigating.

> I’m thinking we could perhaps add a compiler barrier before ‘vp->fp = new_fp’
> statements, but in practice it’s not necessary here (x86_64, gcc 7).
>
> Thoughts?

Indeed, we need something to ensure that the compiler won't reorder
these writes.  My recommendation would be to use the 'volatile'
qualifier in the declarations of both the 'fp' field of 'struct scm_vm'
and the stack element modified by SCM_FRAME_SET_DYNAMIC_LINK.

Maybe something like this:

--8<---------------cut here---------------start------------->8---
diff --git a/libguile/frames.h b/libguile/frames.h
index ef2db3df5..8554f886b 100644
--- a/libguile/frames.h
+++ b/libguile/frames.h
@@ -89,6 +89,7 @@
 union scm_vm_stack_element
 {
   scm_t_uintptr as_uint;
+  volatile scm_t_uintptr as_volatile_uint;
   scm_t_uint32 *as_ip;
   SCM as_scm;
   double as_f64;
@@ -104,7 +105,7 @@ union scm_vm_stack_element
 #define SCM_FRAME_RETURN_ADDRESS(fp)    ((fp)[0].as_ip)
 #define SCM_FRAME_SET_RETURN_ADDRESS(fp, ra) ((fp)[0].as_ip = (ra))
 #define SCM_FRAME_DYNAMIC_LINK(fp)      ((fp) + (fp)[1].as_uint)
-#define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) ((fp)[1].as_uint = ((dl) - (fp)))
+#define SCM_FRAME_SET_DYNAMIC_LINK(fp, dl) ((fp)[1].as_volatile_uint = ((dl) - (fp)))
 #define SCM_FRAME_SLOT(fp,i)            ((fp) - (i) - 1)
 #define SCM_FRAME_LOCAL(fp,i)           (SCM_FRAME_SLOT (fp, i)->as_scm)
 #define SCM_FRAME_NUM_LOCALS(fp, sp)    ((fp) - (sp))
diff --git a/libguile/vm.h b/libguile/vm.h
index a1cac391f..0a6179c19 100644
--- a/libguile/vm.h
+++ b/libguile/vm.h
@@ -38,7 +38,7 @@ enum {
 struct scm_vm {
   scm_t_uint32 *ip;		/* instruction pointer */
   union scm_vm_stack_element *sp; /* stack pointer */
-  union scm_vm_stack_element *fp; /* frame pointer */
+  union scm_vm_stack_element *volatile fp; /* frame pointer */
   union scm_vm_stack_element *stack_limit; /* stack limit address */
   int trace_level;              /* traces enabled if trace_level > 0 */
   union scm_vm_stack_element *sp_min_since_gc; /* deepest sp since last gc */
--8<---------------cut here---------------end--------------->8---

> I’d like to push this real soon.  I’ll also do more testing on real
> workloads from Guix, and then I’d like to release 2.2.4, hopefully
> within a few days.

Sounds good to me.

     Thanks,
       Mark

  reply	other threads:[~2018-06-29 16:57 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-23 22:20 bug#28211: Grafting code triggers GC/thread-safety issue on Guile 2.2.2 Ludovic Courtès
2017-08-23 22:48 ` Ludovic Courtès
2018-04-24 16:03 ` Ludovic Courtès
2018-05-08 21:55   ` Ludovic Courtès
2018-05-09  0:32     ` Mark H Weaver
2018-05-09  7:17       ` Ludovic Courtès
2018-05-09  9:11       ` Andy Wingo
2018-05-10  6:50         ` Mark H Weaver
2018-05-10  7:53           ` Andy Wingo
2018-06-29 15:03             ` bug#28211: Stack marking issue in multi-threaded code Ludovic Courtès
2018-06-29 16:54               ` Mark H Weaver [this message]
2018-06-29 21:18                 ` Ludovic Courtès
2018-06-29 23:18                   ` Mark H Weaver
2018-06-30 20:53                     ` Ludovic Courtès
2018-06-30 21:49                       ` Mark H Weaver
2018-07-01 10:12                         ` Andy Wingo
2018-07-03 19:01                           ` Mark H Weaver
2020-03-12 21:59               ` bug#28211: Stack marking issue in multi-threaded code, 2020 edition Ludovic Courtès
2020-03-13 22:38                 ` Ludovic Courtès
2020-03-17 21:16                 ` Andy Wingo
2018-05-10 15:48     ` bug#28211: Grafting code triggers GC/thread-safety issue on Guile 2.2.2 Mark H Weaver
2018-05-10 16:01       ` Mark H Weaver
2018-07-02 10:28 ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87in61y1m0.fsf@netris.org \
    --to=mhw@netris.org \
    --cc=28211@debbugs.gnu.org \
    --cc=ludo@gnu.org \
    --cc=wingo@igalia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.