Do pushcli() and popcli() in the spinlock of XV6 need atomic?

Viewed 63

As learning XV6's spinlock,I thought a problem and don't find answer in google. In spinlock, pushcli() and popcli() used to insure interrupt handler run currently:

void pushcli(void)
{
  int eflags;

  eflags = readeflags();
  cli();
  if (mycpu()->ncli == 0)
    mycpu()->intena = eflags & FL_IF;
  mycpu()->ncli += 1;
}

void popcli(void)
{
  if (readeflags() & FL_IF)
    panic("popcli - interruptible");
  if (--mycpu()->ncli < 0)
    panic("popcli");
  if (mycpu()->ncli == 0 && mycpu()->intena)
    sti();
}

However, the spinlock is used to dure with threads and func in it like xchg() should be atomic,but codes in pushcli() and popcli like mycpu()->ncli += 1; are not atomic , which might cause incorrect result of ncli and intena.So why we can use nonatomic operations in pushcli()?If we shouldn't, what can we do to correct it to safe?

1 Answers

Short answer:

  • mycpu()->ncli is local to each CPU
  • lk->locked is shared between all CPUs

No pushcli and popcli don't need be atomic because they can't be preempted.

We have two different context here:

  1. The access to spinlock->locked (lk->locked) member

    // The xchg is atomic.
    while(xchg(&lk->locked, 1) != 0)
      ;
    
  2. And the enabling/disable of interruption: cli()/sti()

In the first case, the variable is stored in memory, any cpu could want to access the lock at any time, the atomic instruction is need here: only one cpu can have access to it.

In the second case, we are in the kernel code of a cpu: the code executed is local to given processor and once cli is called the cpu can't interrupt (so can't be preempted) until sti is called.

Since the cpu deals with a variable that is private to it mycpu()->ncli;, no atomicity is needed here.


To be exact, mycpu() read a shared array cpus[], and by design return the cpu structure referring to the CPU that executed the function. Note that mycpy() require interrupt to be disabled to execute (if not, you got a kernal panic).

Related