git: DragonFly_RELEASE_5_6 kernel - Fix pmap placemarker timing race

Matthew Dillon dillon at
Sun Jun 23 14:12:58 PDT 2019

commit 41bf5974e227f13e89b3f1be53afcee20644b930
Author: Matthew Dillon <dillon at>
Date:   Sun Jun 23 08:24:24 2019 -0700

    kernel - Fix pmap placemarker timing race
    * Fix a timing race that could cause a thread to get stuck in
      "pvplw" indefinitely.  The timing window is very short and the
      race is fairly difficult to reproduce.
    * For this race to occur, more than one interaction must take
      place on other cpus against the placemarker being waited on
      by pv_placemarker_wait().  It takes multiple interactions for
      the WAKEUP bit to be lost.
      The first interaction can clear the WAKEUP bit and issue a
      wakeup() before we manage to interlock.  The second interaction
      can then reserve the placemarker so our conditional fails and
      we tsleep().  The result is that we block forever.
      pv_placemarker_wait(pmap_t pmap, vm_pindex_t *pmark)
              if (*pmark != PM_NOPLACEMARK) {
                      atomic_set_long(pmark, PM_PLACEMARK_WAKEUP);
                      tsleep_interlock(pmark, 0);
                      if (*pmark != PM_NOPLACEMARK)
                              tsleep(pmark, PINTERLOCKED, "pvplw", 0);
      Just moving the interlock to before setting the flag is not
      sufficient due to cuteness on my part in overloading the WAKEUP
      bit on top of NOPLACEMARK (NOPLACEMARK is '-1').
    * The solution is to both properly order the interlock AND use
      a cmpset loop to prevent accidently setting the WAKEUP bit on
      a marker that has already been released.
    	mark = *pmark;
            while (mark != PM_NOPLACEMARK) {
                    tsleep_interlock(pmark, 0);
                    if (atomic_fcmpset_long(pmark, &mark,
                                           mark | PM_PLACEMARK_WAKEUP)) {
                            tsleep(pmark, PINTERLOCKED, "pvplw", 0);
    Reported-by: tuxillo

Summary of changes:
 sys/platform/pc64/x86_64/pmap.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

DragonFly BSD source repository

More information about the Commits mailing list