Title: Hard Disks
1Hard Disks
- Random Access
- A hard disks total storage capacity is divided
into many small chunks called blocks or sectors - Non-Volatile Storage
- Once written, a block continues to hold data even
after the hard disk is powered down - Reliability
- Performance
2Hard Disks
- One sector on the disk is equivalent to one block
of data - Since there is one head per platter, a platter is
also identified by the head associated with it - Heads are numbered from zero onwards
- All the tracks at the radius are collectively
called a cylinder - Cylinders are also numbered sequentially
- CHS(cylinder,head,sector) identifies a particular
sector of the disk, called CHS block addressing
3(No Transcript)
4Disk Parameters
- Total disk capacity
- (Number of heads) X (Number of cylinders) X
(Sectors per track) X (Sector size) - For example, a disk with 5 heads, 15625
cylinders, 250 sectors per track, and 512 bytes
per sector has a capacity of 10,000,000,000 bytes
5Access Latency
- Access time to a particular block depends on how
the head and platter happen to be positioned when
the disk receives an access request - If the head was on a different cylinder, the head
must jump to the required track (seek latency) - For example, it takes about 10 milliseconds to go
from the outermost track to the innermost - Once the head has settled over the track, it must
wait until the required sector passes under it
(rotational latency) - Seek latency and rotational latency are generally
clubbed together in a measure called random
access latency - The inverse of this number is the measure known
as I/Os per second - A disk with 47 sectors per track spinning at
7200RPM has a maximum bandwidth of 47 512
7200/60 2.8MBps
6Disk Partitions
- Solaris has disk partitions called slices
- Information that maps logical blocks of a slice
to physical blocks of the whole hard disk is
stored on the first physical block in a table
called a VTOC(Volumn Table of Contents) - There can be at most eight slices on one hard disk
7(No Transcript)
8Zoned Data Recoding
- The width of a track and length of a sector
determine the data density (bits per square inch
of magnetic surface) - If outer tracks have the same number of sectors
per track, bits stored on the outer tracks are
stretched out compared to the inner tracks.
Thus, the outer tracks have less than optimal
data density - To employ optimum data density on the entire
platter, the platter is subdivided into many
concentric zones. - The zones carry increasing number of sectors per
track moving from the innermost to the outermost
zones
9(No Transcript)
10Storage arrays
- An array controller card contains its own
processor, cache memory, and disk control logic
11Redundant Array of Inexpensive Disks (RAID)
- Uses a simple Error-Correction Code (ECC) to
recover data after a disk failure - RAID0
- Since there is no redundancy, hence no protection
against disk failure at all - Disk striping, in which consecutive blocks in the
virtual disk map to the same block address on
consecutive disks - RAID1
- Mirroring, 11 ECC
- RAID3
- Uses n data disks plus one parity disk (n1 ECC)
- One virtual disk or n blocks of data are
distributed across n disks - RAID4
- Uses the same scheme as RAID3
- The virtual disk has a block size that equals one
physical block and maps wholly to one block of a
physical disk - A write request is quite expensive since the
parity block and target data block must be read,
new parity calculated from old parity, old data,
and new data, and finally new parity and new data
must be written - RAID5
- Parity blocks are distributed across all disks to
avoid a single disk parity disk becoming a hot
spot for write accesses
12RAID-DP (Double-parity RAID)
13RAID-DP
- Keep the size of RAID arrays small
- Additional disks will be lost to parity impacting
usable capacity and total cost of ownership(TCO) - Performance is generally slower
14RAID-DP
- Use RAID1
- Twice the disk capacity to store the same amount
of data - The most expensive type of storage solution with
the highest TCO
15RAID-DP
- RAID-DP adds a second parity disk to each RAID
group in an aggregate or traditional volume - Whereas the parity disk in a RAID4 volume stores
row parity across the disks in a RAID4 group, the
additional RAID-DP parity disk stores diagonal
parity across the disks in a RAID-DP group.
16(No Transcript)
17RAID4 horizontal row parity
18Adding RAID-DP double parity stripes
19(No Transcript)
20(No Transcript)
21(No Transcript)
22(No Transcript)
23(No Transcript)
24(No Transcript)
25(No Transcript)
26(No Transcript)
27(No Transcript)
28(No Transcript)
29Processes
- Defined as an instance of a program in execution.
Processes are often called tasks or threads in
the Linux source code - Linux uses lightweight processes to offer better
support for multithreaded applications that may
share some resources, like the address space, the
open file, and so on - Use process descriptor a task_struct type
structure whose fields contain all the
information related to a single process
30Linux Process Descriptor
state flags need_resched counter nice next_task pr
ev_task run_list p_cptr p_pptr .. tty thread fs
files mm sigmask_lock sig
tty associated with the process
current directory
pointers to file descriptors
pointers to memory area descriptors
signals received
31Process State
- TASK_RUNNING
- The process is either executing on a CPU or
waiting to be executed - TASK_INTERRUPTIBLE
- The process is suspended until some condition
becomes true - TASK_UNTERRUPTIBLE
- Used when a process must wait until a given event
occurs without being interrupted - TASK_STOPPED
- Process execution has been stopped
- TASK_ZOMBIE
- Process execution is terminated, but the parent
process has not yet issued a wait()-like system
call
32Identifying a process
- Each execution context that can be independently
scheduled must have its own process descriptor,
including lightweight processes - The Unix-like operating system allow users to
identify processes by means of the Process ID
(PID), which is stored in the pid field of the
process descriptor - The PID of a newly created process is normally
the PID of the previously created process
incremented by one - The maximum PID number allowed on Linux is 32767.
When the kernel creates the 32768th process in
the system, it must start recycling the lower,
unused PIDs
33Processor Descriptors Handling
- Linux stores two different data structures for
each process in a single 8KB memory area the
process descriptor and the Kernel Mode process
stack - union task_union
- struct task_struct task
- unsigned long stack2048
-
34Process descriptor and kernel stack
STACK
esp
PROCESSDESCRIPTOR
current
35Process list
next_task
prev_task
define for_each_task(p) \ for (pinit_task
(pp-gtnext_task) ! init_task )
36Doubly linked lists
- The Linux kernel defines the list_head data
structure, whose fields next and prev represent
the forward and back pointers of a generic doubly
linked list - A new list is created by using the
LIST_HEAD(list_name) macro
37Doubly linked lists
data structure 1
data structure 2
data structure 3
list_head
next
prev
38Doubly linked lists
- list_add(n, p)
- Inserts an element pointed by n right after the
specified element pointed by p - list_add_tail(n, h)
- Inserts an element pointed by n at the end of the
list specified by the address h - list_del(p)
- Deletes an element pointed by p
- list_empty(p)
- Checks if the list specified by the address of
its conventional first element is empty - list_entry(p, t, f)
- Returns the address of the data structure of type
t in which the list_head field that has the name
f and the address p is included - list_for_each(p, h)
- Scans the elements of the list specified by the
address h of the conventional first element
39Doubly linked list
- struct ptable_t
- list_head_t headPT_HASH
- sema_t lockPT_HASH
-
- typedef struct ptable_t ptable
- struct process_t
- list_head_t list
- pid_t pid
-
- typedef struct process_t process_t
40Doubly linked list
- int i
- pid_t pid
- list_head_t head, tmp
- process_t ptr
- pid current-gtpid
- i (int)(pidPT_HASH)
- head ptable.headi
- sema_lock(ptable.locki)
- tmp head-gtnext
- while (head ! tmp)
- ptr list_entry(tmp, process_t, list)
- if (pid ptr-gtpid)
- sema_unlock(ptable.locki)
- return
-
- tmp tmp-gtnext
- ptr (process_t )kmalloc(sizeof(process_t))
- pid-gtpid pid
- list_add(ptr-gtlist, head)
- sema_unlock(ptable.locki)
41TASK_RUNNING processes
- Runqueue is introduced to store TASK_RUNNING
processes - add_to_runqueue()
- Inserts a process descriptor at the beginning of
the list - del_from_runqueue()
- Removes a process descriptor from the list
- move_first_runqueue() / move_last_runqueue()
- moves a process descriptor to the beginning or
the end of the runqueue to schedule - task_on_runqueue()
- Checks whether a given process is inserted into
the runqueue - wake_up_process
- Used to make a process runnable. It sets the
process state to TASK_RUNNING and invokes
add_to_runqueue() to insert the process in the
runqueue list
42Wait queues
- A process must often wait for some event to
occur, such as for a disk operation to terminate,
a system resource to be released, or a fixed
interval of time to elapse - A wait queue represents a set of sleeping
processes, which are woken up by the kernel when
some condition becomes true - There are two kinds of sleeping processes
exclusive processes are selectively woken up by
the kernel, while nonexclusive processes are
always woken up by the kernel when the event
occurs
43Wait queues
- struct __wait_queue_head
- spinlock_t lock
- struct list_head task_list
-
- typedef struct __wait_queue_head_t
wait_queue_head_t - struct __wait_queue
- unsigned int flags
- struct task_struct task
- struct list_head task_list
-
- typedef struct __wait_queue wait_queue_t
44Wait queues
- void sleep_on(wait_queue_head_t q)
- unsigned long flags
- wait_queue_t wait
- wait.flags 0
- wait.task current
- current-gtstate TASK_UNINTERRUPTIBLE
- add_wait_queue(q, wait)
- schedule()
- remove_wait_queue(q, wait)
45Wait queues
- Wait_event_interruptible(wq, condition)
- if(!(condition))
- wait_queue_t __wait
- init_waitqueue_entry(__wait, current)
- add_wait_queue(wq, __wait)
- for ()
- set_current_state(TASK_INTERRUPTIBLE)
- if (condition) break
- schedule()
-
- current-gtstate TASK_RUNNING
- remove_wait_queue(wq, __wait)
-