1 PROJECT 3 GRADING ADVICE
2 ========================
4 This file contains advice for grading project 3. General advice for
5 Pintos grading is in README, which you should read first.
12 This should include a description of the students' supplemental
13 page table. There are two common approaches:
15 - Hash table: a per-process hash table indexed on virtual
16 address. The hash table elements normally include:
20 * Location. At any given time, this is one of:
24 . File and offset (and in many implementations, a byte
25 count between 0 and 4,096 also, with the remaining
32 * Read-only or read/write flag.
34 * Often, a pointer back to the owning thread or page
35 directory, so one of these structures can be used to
36 evict its page (it must be possible to find the page's
37 PTE to mark it not-present before it can be evicted).
39 Students should mention that they added a hash table member
42 Students come up with various ways to break this table into
45 - Modify the page table implementation: 31 bits of each PTE
46 for a page that is not in a frame are available for use.
47 Some groups use these to point to the supplemental page
50 That still leaves us needing a way to find the supplemental
51 page table entry for a page that is in a frame. We can do
52 that with an array that has one entry for each physical
53 page, indexing it based on the frame number for the frame
54 pointed to by the PTE.
56 Some hybrid approaches are also possible.
58 A1 might also describe the frame table, swap table, and file
59 mapping table, but most students leave those for B1. Either way
64 The answer should describe code, not data; the data structures
65 have already been explained in A1.
69 The most common answer is "We always access user data through the
70 user virtual address," which is simple and correct. Another
71 correct answer is "We check accessed and dirty bits for both user
72 and kernel virtual addresses."
74 If sharing is implemented, then the answer must explain how
75 accessed and dirty bits are coordinated. Sharing excludes the
76 possibility of avoiding aliasing.
78 Look for confusion between user and kernel addresses here. Unless
79 sharing is implemented, each user virtual address aliases exactly
80 one kernel virtual address.
82 Watch for the implication that an approximate idea of the dirty
83 status of a page is okay. It's not--if the OS thinks a page is
84 clean, but it's actually dirty, then it could throw away changes
85 without writing them back.
89 A typical answer is along these lines:
91 First we try to get a free frame with palloc_get_page(), which
92 does its own internal synchronization. If it succeeds, we're
95 Otherwise, we grab a lock needed to perform eviction. The
96 lock prevents other threads from trying to evict a page at the
101 If the students used a hash table, they should identify some of
102 the benefits of a hash table relative to alternative data
103 structures: an array would be sparse and thus too big, a list
104 would be slow to search, and so on. Mentioning that a hash table
105 has O(1) average lookup time is also good.
107 If the students modified the existing page tables, then they
108 typically explain that this saves memory because the PTEs are
109 needed anyway, and that lookup through the page table is fast.
111 Students may mention that making their data structure
112 thread-specific reduces the need for locking, or that it makes it
113 easier to find all the pages that belong to a given process (for
114 cleanup when a process dies).
116 Check the submitted code, by hand, for the following:
118 PAGING TO AND FROM DISK
119 =======================
123 Expect to see the following global data:
127 - A lock for the swap bitmap. Sometimes swap synchronization
128 is handled by another lock, but sometimes it's forgotten
133 - A pointer to a frame, used for the clock hand. Not always
136 - A lock on the frame list.
138 There may be some structure definitions to go with the above.
140 Some of the data structures we expect to see here might have
141 already been described in A1.
145 This is normally a description of the second-chance or "clock"
146 algorithm, which sweeps around the list of frames looking for an
147 unset accessed bit, resetting those that are set as it goes.
149 Some students implement a preference to evict clean pages, to
150 reduce the needed I/O. Others use two clock hands, one that
151 checks accessed bits and another ahead of the checking hand that
152 resets bits. Those are nice touches.
154 The dirty bit should *not* be reset as part of the clock
155 algorithm. That will cause data corruption. Take off points if
156 the students say they do so.
158 Some students take the "clock" algorithm name too literally and
159 implement a thread that periodically resets all the accessed bits
160 in the system. That's bad: it's not any more useful to have all
161 the accessed bits unset than it is to have all of them set. It's
162 not a substitute for resetting accessed bits when we need a page,
163 either. If the students do this without providing good rationale,
168 This is a new question for this quarter, so it's hard to say what
169 the answers will look like.
171 I expect that the students will say that they reset the present
172 bit in the PTE for the page that was evicted and that they adjust
173 the supplementary page table for the page to point to its new
178 The heuristic should, roughly, check that the following are true:
182 - PHYS_BASE - STACK_LIMIT <= FA < PHYS_BASE
184 where FA is the faulting address, ESP is the user stack pointer,
185 PHYS_BASE is the macro defined in vaddr.h, and STACK_LIMIT is the
186 maximum size of the stack.
188 The first condition ensures that the fault is actually above the
189 stack pointer, allowing 32 bytes to allow the PUSHA instruction to
190 work. Deduct points if their condition allows more than 32 bytes;
191 the documentation is explicit.
193 The second condition ensures that the fault is in a reasonable
194 place for the stack. It prevents the stack from growing above
195 STACK_LIMIT in size. It also prevents access to kernel virtual
198 STACK_LIMIT should be at least 1 MB. Most students choose 8 MB.
200 Some students think that the "struct intr_frame" that the kernel
201 sees is pushed on the user stack. That's wrong; deduct points.
205 The answer must explain how the submitted code prevents one of the
206 4 conditions for deadlock from occurring. Typically this is by
207 making sure that locks are always acquired in a particular order.
210 - "Terminal" locks, that is, locks under which no further
211 locks are acquired. This is common, for example, for the
212 lock on the swap bitmap.
214 - Ranking locks: students describe the order in which locks
217 Wording that attempts to claim that the conditions for deadlock
218 are "rare" or that the window in which deadlock can occur is
219 "short" are not acceptable. In a proper design, deadlock is
220 impossible, not just rare. Deduct points.
224 This is a two-part question, and students must answer both parts.
226 Usually, a lock protects the page. To evict or to fault in a page
227 requires holding the lock. P holds the lock during the entire
228 eviction process, so Q has to wait for it to be released if it
229 wants to fault it back in.
231 To prevent Q from accessing or modifying its page, P marks its PTE
232 not-present before it starts evicting it, but *after* it acquires
233 the page lock. (If it marked it not-present before acquiring the
234 lock, it would race with Q faulting on the page and trying to
237 Disabling interrupts is not required anywhere. Deduct points from
238 solutions that disable interrupts.
242 Several possible answers:
244 - Same as B6: hold the page's lock while it is being read in,
245 so Q cannot acquire it until it's finished.
247 - Don't add the new page to the list of frames that are
248 candidates for eviction until its page-in is complete.
250 - Mark frames with a "non-evictable" bit while they're being
255 Several possible answers:
257 - Pre-lock all the pages that the system call will access,
258 then unlock them when the system call completes.
260 - Page fault in kernel.
262 - Acquire a global lock needed to evict pages. (But there
263 should be some additional explanation of how the system call
264 makes sure that those pages are in main memory in the first
269 Watch out for claims about deadlock here. Wording that attempts
270 to claim that the conditions for deadlock are "rare" or that the
271 window in which deadlock can occur is "short" are not acceptable.
272 In a proper design, deadlock is impossible, not just rare. Deduct
275 Check the submitted code, by hand, for the following:
282 This usually includes a data structure that represents a mapped
283 file and adds a list of them to "struct thread". Sometimes,
284 students add a new counter for a mapid_t, analogous to the
285 counters added for file descriptors in project 2. The same
286 criteria apply as did in that project.
290 Usually the answer is basically "We reused lots of existing data
291 structures, but we had to deal with a few differences."
293 For some reason, students sometimes talk about permanently
294 assigning or pre-reserving memory mapped files to swap slots or to
295 frames in physical memory here. That's incorrect. The assignment
296 is explicit that mapping should be lazily loaded and written back
297 to their files, not to swap.
301 Basically, *each* page (not just the first) in the new mapping has
302 to be checked as to whether it overlaps any existing segment.
304 There should be some comment about interaction between stack
305 expansion and memory mapped files.
307 Memory mappings are per-process, so mappings in two different
308 processes do not "overlap".
312 Usually, this says how the similar bits of the implementation are
313 shared and the different bits are not. Just make sure it's a
314 reasonable rationale.