i o
play

I/O 1 last time (1) LRU approximations (part 1) second chance - PowerPoint PPT Presentation

I/O 1 last time (1) LRU approximations (part 1) second chance ordered list of pages use page on list the longest if not referenced otherwise clear referenced bit, put back on list SEQ (active + inactive list, references on inactive move to


  1. I/O 1

  2. last time (1) LRU approximations (part 1) second chance ordered list of pages use page on list the longest if not referenced otherwise clear referenced bit, put back on list SEQ (active + inactive list, references on inactive move to active) ordered list of active, inactive pages use page on inactive list longer move pages from inactive to active whenever referenced avoid checking references to common active pages 2

  3. last time (2) LRU approximations (part 2) CLOCK algorithms (scan all pages periodically; keep history of references) scan through all pages over time (when? OS choice) record if referenced; clear referenced bit use history of whether it was referenced to make decisions lots of choices for details 3

  4. last time (3) being proactive readahead — guess future accesses writeback early — keep disk up to date pools of pre-evicted pages can take advantage of idle CPU/IO device time to speed up future accesses non-LRU patterns example: scanning through large fjle example: reading fjle exactly once to load it possible policy: CLOCK-PRO: kepe pages ‘inactive’ until two references idea: detect ‘bad’ (for LRU) access patterns, do non-LRU thing for them only 4

  5. last time (4) Unix: devices represented as fjles extra fjle operations (ioctl, etc.) for ‘weird’ things eject DVD, change whether terminal echos, etc. 5

  6. Linux example: fjle operations (selected subset — table of pointers to functions) }; ... ... unsigned long mmap_supported_flags; ... ... ... struct file_operations { 6 ssize_t (*read) ( struct file *, char __user *, size_t, loff_t *); ssize_t (*write) ( struct file *, const char __user *,x size_t, loff_t *); long (*unlocked_ioctl) ( struct file *, unsigned int , unsigned long ); int (*mmap) ( struct file *, struct vm_area_struct *); int (*open) ( struct inode *, struct file *); int (*release) ( struct inode *, struct file *);

  7. special case: block devices devices like disks often have a difgerent interface block size usually equal to page size read/write page at a time 7 unlike normal fjle interface, works in terms of ‘blocks’ for working with page cache

  8. Linux example: block device operations struct block_device_operations { ... }; read/write a page for a sector number (= block number) 8 int (*open) ( struct block_device *, fmode_t); void (*release) ( struct gendisk *, fmode_t); int (*rw_page)( struct block_device *, sector_t, struct page *, bool ); int (*ioctl) ( struct block_device *, fmode_t, unsigned , unsigned long );

  9. device driver fmow get interrupt from device trap handler “bottom half” device hardware store and return request result send more to device (if needed) wake up thread (if needed) update bufgers put thread to sleep (if needed) thread making read/write/etc. “top half” send or queue I/O operation (e.g. previous keypresses to keyboard) check if satisfjed from bufgers page cache miss/eviction… read/write/… system call or get I/O request 9

  10. device driver fmow get interrupt from device trap handler “bottom half” device hardware store and return request result send more to device (if needed) wake up thread (if needed) update bufgers put thread to sleep (if needed) thread making read/write/etc. “top half” send or queue I/O operation (e.g. previous keypresses to keyboard) check if satisfjed from bufgers page cache miss/eviction… read/write/… system call or get I/O request 9

  11. device driver fmow get interrupt from device trap handler “bottom half” device hardware store and return request result send more to device (if needed) wake up thread (if needed) update bufgers put thread to sleep (if needed) thread making read/write/etc. “top half” send or queue I/O operation (e.g. previous keypresses to keyboard) check if satisfjed from bufgers page cache miss/eviction… read/write/… system call or get I/O request 9

  12. xv6: device fjles (1) struct devsw { }; extern struct devsw devsw[]; inode = represents fjle on disk pointed to by struct fjle referenced by fd 10 int (*read)( struct inode*, char *, int ); int (*write)( struct inode*, char *, int );

  13. xv6: device fjles (2) struct devsw { }; extern struct devsw devsw[]; array of types of devices special type of fjle on disk has index into array “device number” created via mknod() system call similar scheme used on real Unix/Linux two numbers: major + minor device number 11 int (*read)( struct inode*, char *, int ); int (*write)( struct inode*, char *, int );

  14. xv6: console devsw code run at boot: devsw[CONSOLE].write = consolewrite; devsw[CONSOLE].read = consoleread; CONSOLE is the constant 1 consoleread/consolewrite: run when you read/write console 12

  15. xv6: console devsw code run at boot: devsw[CONSOLE].write = consolewrite; devsw[CONSOLE].read = consoleread; CONSOLE is the constant 1 consoleread/consolewrite: run when you read/write console 12

  16. device driver fmow get interrupt from device trap handler “bottom half” device hardware store and return request result send more to device (if needed) wake up thread (if needed) update bufgers put thread to sleep (if needed) thread making read/write/etc. “top half” send or queue I/O operation (e.g. previous keypresses to keyboard) check if satisfjed from bufgers page cache miss/eviction… read/write/… system call or get I/O request 13

  17. xv6: console top half (read) sleep(&input.r, &cons.lock); put thread to sleep r = reading location, w = writing location if at end of bufger } ... release(&cons.lock) } ... } } int ... while (input.r == input.w){ while (n > 0){ acquire(&cons.lock); target = n; ... { 14 consoleread( struct inode *ip, char *dst, int n) if (myproc() − >killed){ return − 1;

  18. device driver fmow get interrupt from device trap handler “bottom half” device hardware store and return request result send more to device (if needed) wake up thread (if needed) update bufgers put thread to sleep (if needed) thread making read/write/etc. “top half” send or queue I/O operation (e.g. previous keypresses to keyboard) check if satisfjed from bufgers page cache miss/eviction… read/write/… system call or get I/O request 15

  19. xv6: console top half (read) int to user bufger (passed to read) copy from kernel bufger } ... release(&cons.lock) } break ; if (c == '\n') *dst++ = c; ... c = input.buf[input.r++ % INPUT_BUF]; ... while (n > 0){ acquire(&cons.lock); target = n; ... { 16 consoleread( struct inode *ip, char *dst, int n) −− n; return target − n;

  20. xv6: console top half (read) int to user bufger (passed to read) copy from kernel bufger } ... release(&cons.lock) } break ; if (c == '\n') *dst++ = c; ... c = input.buf[input.r++ % INPUT_BUF]; ... while (n > 0){ acquire(&cons.lock); target = n; ... { 16 consoleread( struct inode *ip, char *dst, int n) −− n; return target − n;

  21. xv6: console top half wait for bufger to fjll no special work to request data — keyboard input always sent copy from bufger check if done (newline or enough chars), if not repeat 17

  22. device driver fmow get interrupt from device trap handler “bottom half” device hardware store and return request result send more to device (if needed) wake up thread (if needed) update bufgers put thread to sleep (if needed) thread making read/write/etc. “top half” send or queue I/O operation (e.g. previous keypresses to keyboard) check if satisfjed from bufgers page cache miss/eviction… read/write/… system call or get I/O request 18

  23. xv6: console interrupt (one case) break ; lapcieoi: tell CPU “I’m done with this interrupt” kbdintr: atually read from keyboard device } ... } ... lapcieoi(); void kbdintr(); case T_IRQ0 + IRQ_KBD: ... ... 19 trap( struct trapframe *tf) { switch (tf − >trapno) {

  24. xv6: console interrupt (one case) break ; lapcieoi: tell CPU “I’m done with this interrupt” kbdintr: atually read from keyboard device } ... } ... lapcieoi(); void kbdintr(); case T_IRQ0 + IRQ_KBD: ... ... 19 trap( struct trapframe *tf) { switch (tf − >trapno) {

  25. device driver fmow get interrupt from device trap handler “bottom half” device hardware store and return request result send more to device (if needed) wake up thread (if needed) update bufgers put thread to sleep (if needed) thread making read/write/etc. “top half” send or queue I/O operation (e.g. previous keypresses to keyboard) check if satisfjed from bufgers page cache miss/eviction… read/write/… system call or get I/O request 20

  26. xv6: console interrupt reading kbdintr fuction actually reads from device adds data to bufger (if room) wakes up sleeping thread (if any) 21

Recommend


More recommend