Re: understanding spin_lock()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>>>>> "Michael" == Michael G Janicki <mikejani@colfax.com> writes:

Michael>   Spurred by some recent lkml/kernel-janitor religious wars on
Michael> the use of spin locks, I'm trying to better understand spin locks
Michael> and their application.  I've decided to start at the obvious point
Michael> of what exactly spin_lock() is doing.  Below is how I understand
Michael> spin_lock() to be expanded and what that means in context.  This
Michael> is looking at the x86 spinlock in 2.4.19-rc1.  For those with a
Michael> better understanding of this, I'd like to ask:

Michael> 1 - is this understanding correct?

Yep, as far as I can tell.  

Michael> 2 - why the use of 'rep ; nop' in the spin?

In the dark ages, where there were no caches (worth talking about), it
was considered fair to release the bus before the bus arbiter gives
bus ownership to some other CPU, so other CPUs are given a chance to
run (and release the lock).

Nowdays, I'm wandering too ...

Besides, it is IMHO another fine example of broken code, "rep; nop"
modifies (e)cx, but the insn clobbers do not mention it.  Sigh, guess
it is easier to blame the compiler ...

Michael> 3 - why is it unnecessary to 'lock' in spin_unlock()?
Michael> 	I don't see where the current way hurts
Michael> 	anything, but it seems we might end up
Michael> 	in an unnecessary spin once in a blue moon

The ``decb'' insn is a read-modify-write operation, which on a MP
system is not guaranteed to be atomic without the lock prefix.

Michael> 4 - this seems to indicate that each use of spin_lock()
Michael> 	generates redundant (although very small) code
Michael> 	in .subsection 1 - correct?

Hmm, in my source it is .text.lock, but yes, it does, just like any
other inline functions generates a bunch of insns in .text.  But it is
not completely redundant, the register assignments in each instance
may differ.

Michael> .section	.text

Michael> # spin_lock_string
Michael> 1:
Michael> 	lock			# make next atomic
Michael> 	decb	lock.lock	# --lock->lock
Michael> 	js	2		# if (lock->lock < 0) goto 2;
Michael> 				# meaning someone already has the lock
Michael> 				# so we just get in line
Michael> 				# if it started at 1, they decb to 0
Michael> 				# and we just came by and decb to -1

Michael> # this here deserves a 'coolness' award
Michael> # because we have written this into a separate section
Michael> # the above will simply fall through if we are able to

Way cool, indeed :)

[snip]

Michael> # ----------------
Michael> # spin_unlock_string
Michael> 	# why not 'lock' instruction here?
Michael> 	movb	$1, lock.lock	# lock->lock = 1; release our lock

4-byte writes on 4-byte aligned addresses are atomic.

Regards,
-velco
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux