100 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<title>Homework: Locking</title>
 | 
						|
<html>
 | 
						|
<head>
 | 
						|
</head>
 | 
						|
<body>
 | 
						|
 | 
						|
<h1>Homework: Locking</h1>
 | 
						|
 | 
						|
 | 
						|
<p>
 | 
						|
<b>Read</b>: spinlock.c
 | 
						|
 | 
						|
<p>
 | 
						|
<b>Hand-In Procedure</b>
 | 
						|
<p>
 | 
						|
You are to turn in this homework at the beginning of lecture. Please
 | 
						|
write up your answers to the exercises below and hand them in to a
 | 
						|
6.828 staff member at the beginning of lecture.
 | 
						|
<p>
 | 
						|
 | 
						|
<b>Assignment</b>:
 | 
						|
In this assignment we will explore some of the interaction
 | 
						|
between interrupts and locking.
 | 
						|
<p>
 | 
						|
 | 
						|
Make sure you understand what would happen if the kernel executed
 | 
						|
the following code snippet:
 | 
						|
<pre>
 | 
						|
  struct spinlock lk;
 | 
						|
  initlock(&lk, "test lock");
 | 
						|
  acquire(&lk);
 | 
						|
  acquire(&lk);
 | 
						|
</pre>
 | 
						|
(Feel free to use Bochs to find out.  <code>acquire</code> is in <code>spinlock.c</code>.)
 | 
						|
<p>
 | 
						|
 | 
						|
An <code>acquire</code> ensures interrupts are off
 | 
						|
on the local processor using <code>cli</code>,
 | 
						|
and interrupts remain off until the <code>release</code>
 | 
						|
of the last lock held by that processor
 | 
						|
(at which point they are enabled using <code>sti</code>).
 | 
						|
<p>
 | 
						|
 | 
						|
Let's see what happens if we turn on interrupts while
 | 
						|
holding the <code>ide</code> lock.
 | 
						|
In <code>ide_rw</code> in <code>ide.c</code>, add a call
 | 
						|
to <code>sti()</code> after the <code>acquire()</code>.
 | 
						|
Rebuild the kernel and boot it in Bochs.
 | 
						|
Chances are the kernel will panic soon after boot; try booting Bochs a few times
 | 
						|
if it doesn't.
 | 
						|
<p>
 | 
						|
 | 
						|
<b>Turn in</b>: explain in a few sentences why the kernel panicked.
 | 
						|
You may find it useful to look up the stack trace
 | 
						|
(the sequence of <code>%eip</code> values printed by <code>panic</code>)
 | 
						|
in the <code>kernel.asm</code> listing.
 | 
						|
<p>
 | 
						|
 | 
						|
Remove the <code>sti()</code> you added,
 | 
						|
rebuild the kernel, and make sure it works again.
 | 
						|
<p>
 | 
						|
 | 
						|
Now let's see what happens if we turn on interrupts
 | 
						|
while holding the <code>kalloc_lock</code>.
 | 
						|
In <code>kalloc()</code> in <code>kalloc.c</code>, add
 | 
						|
a call to <code>sti()</code> after the call to <code>acquire()</code>.
 | 
						|
You will also need to add 
 | 
						|
<code>#include "x86.h"</code> at the top of the file after
 | 
						|
the other <code>#include</code> lines.
 | 
						|
Rebuild the kernel and boot it in Bochs.
 | 
						|
It will not panic.
 | 
						|
<p>
 | 
						|
 | 
						|
<b>Turn in</b>: explain in a few sentences why the kernel didn't panic.
 | 
						|
What is different about <code>kalloc_lock</code>
 | 
						|
as compared to <code>ide_lock</code>?
 | 
						|
<p>
 | 
						|
You do not need to understand anything about the details of the IDE hardware
 | 
						|
to answer this question, but you may find it helpful to look 
 | 
						|
at which functions acquire each lock, and then at when those
 | 
						|
functions get called.
 | 
						|
<p>
 | 
						|
 | 
						|
(There is a very small but non-zero chance that the kernel will panic
 | 
						|
with the extra <code>sti()</code> in <code>kalloc</code>.
 | 
						|
If the kernel <i>does</i> panic, make doubly sure that
 | 
						|
you removed the <code>sti()</code> call from 
 | 
						|
<code>ide_rw</code>.  If it continues to panic and the
 | 
						|
only extra <code>sti()</code> is in <code>bio.c</code>,
 | 
						|
then mail <i>6.828-staff@pdos.csail.mit.edu</i>
 | 
						|
and think about buying a lottery ticket.)
 | 
						|
<p>
 | 
						|
 | 
						|
<b>Turn in</b>: Why does <code>release()</code> clear
 | 
						|
<code>lock->pcs[0]</code> and <code>lock->cpu</code>
 | 
						|
<i>before</i> clearing <code>lock->locked</code>?
 | 
						|
Why not wait until after? 
 | 
						|
 | 
						|
</body>
 | 
						|
</html>
 |