\section{I/O Scheduling}

\begin{frame}
   {Disk Bottlenecks and I/O Scheduling}
   \begin{itemize}
      \item
      I/O scheduler stands between low-level device drivers
      and I/O requests
      \item
      Need to balance:
      \begin{itemize}
         \item
         Hardware Access Time
         \item
         Latency
         \item
         Deadlines
         \item
         Fairness
         \item
         Efficiency
      \end{itemize}
      \begin{important}
         Modern SSDs can change requirements radically
      \end{important}
   \end{itemize}

\end{frame}

\cprotect\note{

   The I/O scheduler provides the interface between the
   generic block layer and low-level physical device
   drivers. Both the VM (Virtual Memory) and VFS (Virtual
   File System) layers submit I/O requests to block devices;
   it is the job of the I/O scheduling layer to prioritize
   and order these requests before they are given to the
   block devices.

   Any I/O scheduling algorithm has to satisfy certain
   (sometimes conflicting) requirements:
   \begin{itemize}
      \item
      Hardware access times should be minimized; i.e.,
      requests should be ordered according to physical
      location on the disk. This leads to an elevator scheme
      where requests are inserted in the pending queue in
      physical order.
      \item
      Requests should be merged to the extent possible to get
      as big a contiguous region as possible, which also
      minimizes disk access time.
      \item
      Requests should be satisfied with as low a latency as is
      feasible; indeed,in some cases, determinism (in the
      sense of deadlines) may be important.
      \item
      Write operations can usually wait to migrate from caches
      to disk without stalling processes. Read operations,
      however, almost always require a process to wait for
      completion before proceeding further. Favoring reads
      over writes leads to better parallelism and system
      responsiveness.
      \item
      Processes should share the I/O bandwidth in a fair, or
      at least consciously prioritized fashion; even it means
      some overall performance slowdown of the I/O layer,
      process throughput should not suffer inordinately.
   \end{itemize}

}

\section{I/O Scheduler Choices}
\begin{frame}
   {I/O Scheduler Choices}

   \begin{itemize}
      \item
      To see which I/O schedulers are available (for disk
      \file{/dev/sda}):

      \begin{cmd}
$ cat /sys/block/sda/queue/scheduler
      \end{cmd}
      \begin{response}
noop [deadline] cfq          # Before kernel version 5.0
none bfq kyber [mq-deadline] # After  kernel version 5.0
      \end{response}

      \item
      To change the value (as superuser):
      \begin{cmd}
# echo bfq > /sys/block/sda/queue/scheduler
$ cat /sys/block/sda/queue/scheduler
      \end{cmd}
      \begin{response}
none [bfq] kyber mq-deadline
      \end{response}
      \item Scheduler-specific tunables can be found in
      \filelink{/sys/block/sda/queue/iosched}
   \end{itemize}

\end{frame}

\cprotect\note{

   Since demands can be conflicting, different I/O
   schedulers may be appropriate for different workloads;
   e.g., a large database server vs. a desktop system. In
   order to provide flexibility, the \textbf{Linux} kernel has
   an object oriented scheme, in which pointers to the
   various needed functions are supplied in a data
   structure, the particular one of which can be selected at
   run time.

   At least one of the I/O scheduling algorithms must be
   compiled into the kernel. Exactly what is available
   has changed with time, with a major overhaul coming
   with the 5.0 \textbf{Linux} kernel version.

   The default choice is a compile configuration option; for
   kernels before 2.6.18 it was was \textbf{AS}, it then became
   \textbf{CFQ} and is now \textbf{deadline-mq},
   but distributions may have a different
   preference.

   It is possible to use different I/O schedulers for
   different devices.

}
