140 likes | 293 Views
CS 498 Lecture 5 /Proc File System and Timer Utilities. Jennifer Hou Department of Computer Science University of Illinois at Urbana-Champaign. The Proc File System. Reading: Linux Kernel Procfs Guide http://kernelnewbies.org/documents/kdoc/procfs-guide/lkprocfsguide.html.
E N D
CS 498 Lecture 5/Proc File System and Timer Utilities Jennifer Hou Department of Computer Science University of Illinois at Urbana-Champaign
The Proc File System Reading: Linux Kernel Procfs Guide http://kernelnewbies.org/documents/kdoc/procfs-guide/lkprocfsguide.html
The Proc File System • All files in /proc are virtual files, and are generated to export the kernel information in the user space. • The files and directories are based on proc_dir_entry.
proc_dir_entry Structure struct proc_dir_entry { unsigned short low_ino; /* Inode number; automatically filled by proc_register */ unsigned short namelen; /* length of the file or directory name */ const char *name; /* a pointer to the name of the file */ mode_tmode; /* the file’s mode */ nlink_t nlink; /* the number of links to this file (default = 1) */ uid_t uid; /* user ID of the file */ gid_t gid; /* group id of the file */ unsigned long size; /* length of the file as shown when the directory is displayed. */ struct inode_operations * proc_iops; struct file_operations * proc_fops; get_info_t *get_info(buffer, start, off, count); struct module *owner; struct proc_dir_entry *next, *parent, *subdir; /* pointers to link the proc directory structure. */ void *data; /* a pointer to private data */ read_proc_t *read_proc (buffer, start, off, count, eof, data); write_proc_t *write_proc(file, buffer,count,data); atomic_tcount; /* use count */ int deleted; /* delete flag */ kdev_t rdev; };
Handling of /proc Entries. • create_proc_entry(name,mode,parent): creates a file with name in the proc directory; returns a pointer to the proc_dir_entry structure. • The name is relative to /proc/ test_entry = create_proc_entry(“test”, 0600, proc_net); test_entrynlink = 1; test_entrydata = (void *) &test_data; test_entryread_proc = test_read_proc; test_entrywrite_proc = test_write_proc; • remove_proc_entry(name,parent) removes the proc file specified in name.
Handling of /proc Entries • proc_mkdir(name,parent) creates directories in the proc directory; returns a pointer to the proc_dir_entry structure. • create_proc_read_entry(name,mode,base,get_info) creates the proc file name and uses the function get_info() to initialize read accesses. test_entry=create_proc_read_entry(“test”, 0600, proc_net, test_get_info);
Control of Time Flow Linux Device Drivers, 2nd Edition Chapter 5, pages 141-146 Chapter 6: Flow of Time http://www.xml.com/ldd/chapter/book/ch06.html
Tasklets • A more formal mechanism of scheduling software interrupts (and other tasks). • The macro DECLARE_TASKLET(name, func,data) • name: a name for the tasklet_struct data structure • func: the tasklet’s handling routine. • data: a pointer to private data to be passed to func(). • tasklet_schedule(&tasklet_struct) schedules a tasklet for execution. • tasklet_disable() stops a tasklet from running, even if it has been scheduled for execution. • tasklet_enable() reactivates a deactivated tasklet.
Tasklet Example #include <linux/interrupt.h> /* Handling routine of new tasklet */ void test_func(unsigned long); /* Data of new tasklet */ char test_data[] = “Hello, I am a test tasklet”; DECLARE_TASKLET(test_tasklet, test_func, (unsigned long) &test_data); void test_func(unsigned long data) { printk(KERN_DEBUG, “%s\n”, (char *) data); } …. tasklet_schedule(&test_tasklet);
Kernel Timers • struct timer_list { struct timer_list *next; /* never touch this */ struct timer_list *prev; /* never touch this */ unsigned long expires; /* the timeout, in jiffies */ unsigned long data; /* argument to the handler */ void (*function)(unsigned long); /* handler of the timeout */ volatile int running; /* added in 2.4; don't touch */ };
Timer Operations • (i)void init_timer(struct timer_list *timer): Initializes the timer structure. • (ii)void add_timer(struct timer_list *timer): Inserts a timer into the global list of active timers. • (iii)mod_timer(struct timer_list *timer, unsigned long expires): Changes the time at which a timer expires. • (iv)int del_timer(struct timer_list *timer): Removes a timer from the list before it expires. • (v)int del_timer_sync(struct timer_list *timer): Same as del_timer, and guarantees that when the function returns, the timer function is not running on any CPU.
Use of Wait Queue • wait_queue_head_t my_queue; • init_waitqueue_head(&my_queue); or DECLARE_WAIT_QUEUE_HEAD(my_queue) • Operations on the queue: • sleep_on(wait_queue_head_t *queue): puts the process to sleep on this queue; not interruptible. • interruptible_sleep_on(wait_queue_head_t *queue): Same as sleep_on, but the sleep can be interrupted. • sleep_on_timeout(wait_queue_head_t *queue, long timeout): puts the process into sleep on this queue, but the sleep will not be longer than timeout. • interruptible_sleep_on_timeout(wait_queue_head_t *queue, long timeout)
Use of Wait Queue • Operations on the queue • wake_up(wait_queue_head_t *queue): wakes up all the processes that are waiting on this event queue. • wake_up_interruptible(wait_queue_head_t *queue): wakes up on the processes that are in interruptible sleeps. • wake_up_sync(wait_queue_head_t *queue) • wake_up_interruptible_sync(wait_queue_head_t *queue): The synchronous variants make any awakened processes runnable, but do not reschedule the CPU.