Added OS II assignments

This commit is contained in:
2018-06-08 00:50:59 -07:00
parent 43b3555da8
commit 06c37d59e1
76 changed files with 103393 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
\section{Design}
\begin{itemize}
\item Elevator: LOOK
\item Method of sorting items: Insertion Sort
\end{itemize}
The framework for the LOOK elevator was taken from the no-op elevator. To adapt this framework into the LOOK elevator, the "sstf\_add\_request" function was changed so that each item is sorted as it is inserted into the queue rather than simply adding each new request to the end of the queue. The following is pseudocode that describes the "sstf\_add\_request" function.
\begin{lstlisting}[lineskip=3pt,keywords={if,else,while}]
if (list is empty) {
add request to queue
}
else {
if (request > next) {
while (request > next) {
move up the queue
}
add request to queue before this point
}
else {
while (request > prev) {
move down the queue
}
add request to queue after this point
}
}
\end{lstlisting}

View File

@@ -0,0 +1,278 @@
diff -Naur '--exclude=*.o*' '--exclude=*.ko' '--exclude=*.builtin' linux-yocto-3.19.2_untouched/block/Kconfig.iosched linux-yocto-3.19.2/block/Kconfig.iosched
--- linux-yocto-3.19.2_untouched/block/Kconfig.iosched 2018-05-04 15:14:42.027042321 -0700
+++ linux-yocto-3.19.2/block/Kconfig.iosched 2018-05-04 19:08:10.346278748 -0700
@@ -32,6 +32,12 @@
This is the default I/O scheduler.
+config IOSCHED_SSTF
+ tristate "SSTF scheduler"
+ default y
+ ---help---
+ SSTF for class
+
config CFQ_GROUP_IOSCHED
bool "CFQ Group Scheduling support"
depends on IOSCHED_CFQ && BLK_CGROUP
@@ -55,6 +61,9 @@
config DEFAULT_NOOP
bool "No-op"
+ config DEFAULT_SSTF
+ bool "SSTF" if IOSCHED_SSTF=y
+
endchoice
config DEFAULT_IOSCHED
@@ -62,7 +71,7 @@
default "deadline" if DEFAULT_DEADLINE
default "cfq" if DEFAULT_CFQ
default "noop" if DEFAULT_NOOP
-
+ default "sstf" if DEFAULT_SSTF
endmenu
endif
diff -Naur '--exclude=*.o*' '--exclude=*.ko' '--exclude=*.builtin' linux-yocto-3.19.2_untouched/block/Makefile linux-yocto-3.19.2/block/Makefile
--- linux-yocto-3.19.2_untouched/block/Makefile 2018-05-04 15:14:42.055042785 -0700
+++ linux-yocto-3.19.2/block/Makefile 2018-05-04 17:41:20.460575829 -0700
@@ -18,8 +18,7 @@
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
-
+obj-$(CONFIG_IOSCHED_SSTF) += sstf-iosched.o
obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o
obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o t10-pi.o
-
diff -Naur '--exclude=*.o*' '--exclude=*.ko' '--exclude=*.builtin' linux-yocto-3.19.2_untouched/block/sstf-iosched.c linux-yocto-3.19.2/block/sstf-iosched.c
--- linux-yocto-3.19.2_untouched/block/sstf-iosched.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-yocto-3.19.2/block/sstf-iosched.c 2018-05-05 16:33:00.528490307 -0700
@@ -0,0 +1,226 @@
+/* Developed by Corwin Perren and Corinna Brown
+ * Date: May 4, 2018
+ * Name: sstf-iosched.c
+ */
+#include <linux/blkdev.h>
+#include <linux/elevator.h>
+#include <linux/bio.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+//Main data type to store requests
+struct sstf_data{
+ struct list_head queue;
+ int dir;
+ sector_t head;
+};
+
+/* Name: sstf_merge_requests
+ * Description: merges requests
+ * Parameters: request queue, request, next node
+ */
+static void sstf_merge_requests(struct request_queue *queue,
+ struct request *req, struct request *next)
+{
+ list_del_init(&next->queuelist);
+}
+
+/* Name: sstf_dispatch
+ * Description: Main portion of code, runs the actual elevator
+ * Parameters: request queue, force
+ */
+static int sstf_dispatch(struct request_queue *queue, int force)
+{
+ struct sstf_data *nd = queue->elevator->elevator_data;
+
+ if (!list_empty(&nd->queue)){
+ struct request *req;
+ req = list_entry(nd->queue.next, struct request, queuelist);
+ list_del_init(&req->queuelist);
+ elv_dispatch_sort(queue, req);
+ printk(KERN_DEBUG "[SSTF_GROUP4] Dispatching: %s at %lu\n",
+ (rq_data_dir(req)) == READ ? "READ": "WRITE",
+ (long unsigned int) blk_rq_pos(req));
+
+ return 1;
+ }
+ return 0;
+}
+
+/* Name: sstf_add_request
+ * Description: adds a request to the queue
+ * Parameters: Request queue, request
+ */
+static void sstf_add_request(struct request_queue *queue, struct request *req)
+{
+ struct sstf_data *nd = queue->elevator->elevator_data;
+ struct request *next, *prev;
+ struct request *iter;
+
+ // If the list is empty, we simply add it to the queue.
+ if (list_empty(&nd->queue)){
+ printk(KERN_DEBUG "[SSTF_GROUP4] Adding %s at %lu\n",
+ (rq_data_dir(req)) == READ ? "READ": "WRITE",
+ (long unsigned int) blk_rq_pos(req));
+
+ list_add(&req->queuelist, &nd->queue);
+
+ // Otherwise we'll need to find the right place to insert the request
+ } else {
+ // Get the next and previous entries from the queue
+ next = list_entry(nd->queue.next, struct request, queuelist);
+ prev = list_entry(nd->queue.prev, struct request, queuelist);
+
+ // If the request is larger than the "next" item, work UP the queue
+ // until this isn't the case, and insert it directly before this point
+ if (blk_rq_pos(req) > blk_rq_pos(next)){
+ while (blk_rq_pos(req) > blk_rq_pos(next)) {
+ prev = next;
+ next = list_entry(next->queuelist.next, struct request,
+ queuelist);
+ }
+ printk(KERN_DEBUG "[SSTF_GROUP4] Adding %s at %lu\n",
+ (rq_data_dir(req)) == READ ? "READ": "WRITE",
+ (long unsigned int) blk_rq_pos(req));
+
+ list_add(&req->queuelist, &prev->queuelist);
+
+ // Otherise, if the request is smaller than next, work DOWN the queue
+ // unles this isn't the case, and insert direct after this point
+ } else {
+ while (blk_rq_pos(req) > blk_rq_pos(prev)) {
+ next = prev;
+ prev = list_entry(prev->queuelist.prev, struct request,
+ queuelist);
+ }
+ printk(KERN_DEBUG "[SSTF_GROUP4] Adding %s at %lu\n",
+ (rq_data_dir(req)) == READ ? "READ": "WRITE",
+ (long unsigned int) blk_rq_pos(req));
+
+ list_add(&req->queuelist, &next->queuelist);
+ }
+
+ // Prints out entries in queue, for verification
+ printk(KERN_DEBUG "[SSTF_GROUP4] Priting current queue:\n");
+ list_for_each_entry(iter, &nd->queue, queuelist) {
+ printk(KERN_DEBUG "[SSTF_GROUP4] Item: %lu\n",
+ (unsigned long) blk_rq_pos(iter));
+ }
+ }
+}
+
+/* Name: sstf_former_request
+ * Description: stores former request in queue
+ * Parameters: request queue, request
+ */
+static struct request *sstf_former_request(struct request_queue *queue,
+ struct request *req)
+{
+ struct sstf_data *data = queue->elevator->elevator_data;
+
+ if(req->queuelist.prev == &data->queue)
+ return NULL;
+
+ return list_entry(req->queuelist.prev, struct request, queuelist);
+}
+
+/* Name: sstf_latter_request
+ * Description: stores latter request in queue
+ * Parameters: request queue, request
+ */
+static struct request *sstf_latter_request(struct request_queue *queue,
+ struct request *req)
+{
+ struct sstf_data *data = queue->elevator->elevator_data;
+
+ if(req->queuelist.next == &data->queue)
+ return NULL;
+
+ return list_entry(req->queuelist.next, struct request, queuelist);
+}
+
+/* Name: sstf_init_queue
+ * Description: Initializes the queue
+ * Parameters: Request queue, Elevator
+ */
+static int sstf_init_queue(struct request_queue *queue,
+ struct elevator_type *elev)
+{
+ struct sstf_data *data;
+ struct elevator_queue *elevque;
+
+ elevque = elevator_alloc(queue, elev);
+
+ if(!elevque)
+ return -ENOMEM;
+
+ data = kmalloc_node(sizeof(*data), GFP_KERNEL, queue->node);
+
+ if(!data){
+ kobject_put(&elevque->kobj);
+ return -ENOMEM;
+ }
+
+ data->head = 0;
+ elevque->elevator_data = data;
+
+ INIT_LIST_HEAD(&data->queue);
+
+ spin_lock_irq(queue->queue_lock);
+ queue->elevator = elevque;
+ spin_unlock_irq(queue->queue_lock);
+
+ return 0;
+}
+
+/* Name: sstf_exit_queue
+ * Description: exits the queue
+ * Parameters: elevator
+ */
+static void sstf_exit_queue(struct elevator_queue *elev)
+{
+ struct sstf_data *data = elev->elevator_data;
+
+ BUG_ON(!list_empty(&data->queue));
+ kfree(data);
+}
+
+static struct elevator_type elevator_sstf = {
+ .ops = {
+ .elevator_init_fn = sstf_init_queue,
+ .elevator_add_req_fn = sstf_add_request,
+ .elevator_former_req_fn = sstf_former_request,
+ .elevator_latter_req_fn = sstf_latter_request,
+ .elevator_merge_req_fn = sstf_merge_requests,
+ .elevator_dispatch_fn = sstf_dispatch,
+ .elevator_exit_fn = sstf_exit_queue,
+ },
+ .elevator_name = "sstf",
+ .elevator_owner = THIS_MODULE,
+};
+
+/* Name: elev_init
+ * Description: Initializes the elevator
+ * Parameters: N/A
+ */
+static int __init elev_init(void)
+{
+ return elv_register(&elevator_sstf);
+}
+
+/* Name: elev_exit
+ * Description: exits out of the elevator
+ * Parameters: N/A
+ */
+static void __exit elev_exit(void)
+{
+ elv_unregister(&elevator_sstf);
+}
+
+module_init(elev_init);
+module_exit(elev_exit);
+
+MODULE_AUTHOR("Corwin Perren, Corinna Brown");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SSTF IO Scheduler");

View File

@@ -0,0 +1,105 @@
\documentclass[onecolumn, draftclsnofoot, 10pt, compsoc]{IEEEtran}
\usepackage{graphicx}
\graphicspath{{./figures/}}
\usepackage{url}
\usepackage{setspace}
\usepackage{multicol}
\usepackage{pdflscape}
\usepackage{pdfpages}
\usepackage[british]{babel}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{hyperref}
\usepackage{subfig}
\usepackage{geometry}
\geometry{textheight=9.5in, textwidth=7in}
% \overfullrule=2in
%Personal \newcommands
\definecolor{backcolor}{rgb}{0.95,0.95,0.92}
\lstset{basicstyle=\ttfamily,
backgroundcolor=\color{backcolor},
showstringspaces=false,
commentstyle=\color{red},
keywordstyle=\color{blue},
columns=fullflexible,
breaklines=true,
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
}
\newcommand{\NameSigPair}[1]{
\par
\makebox[2.75in][r]{#1}
\hfill
\makebox[3.25in]{
\makebox[2.25in]{\hrulefill}
\hfill
\makebox[.75in]{\hrulefill}
}
\par\vspace{-12pt}
\textit{
\tiny\noindent
\makebox[2.75in]{}
\hfill
\makebox[3.25in]{
\makebox[2.25in][r]{Signature}
\hfill
\makebox[.75in][r]{Date}
}
}
}
% 3. If the document is not to be signed, uncomment the command below
\renewcommand{\NameSigPair}[1]{#1}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{titlepage}
\pagenumbering{gobble}
\begin{singlespace}
\par\vspace{2in}
\centering
\scshape{
\huge Operating Systems II Homework 2 \par
{\large\today}\par
\vspace{.5in}
\vfill
\vspace{5pt}
{\large Prepared by }\par
Group 4 \par
% 5. comment out the line below this one if you do not wish to name your team
\vspace{5pt}
{\Large
\NameSigPair{Corinna Brown}\par
\NameSigPair{Corwin Perren}\par
}
\vspace{20pt}
\begin{abstract}
The document is our groups submission for homework two covering the design of our solution, answers to explicit assignment questions, a version control log, and a work log.
\end{abstract}
}
\end{singlespace}
\end{titlepage}
\newpage
\pagenumbering{arabic}
\tableofcontents
\clearpage
\input{design}
\input{questions}
\input{versioncontrollog}
\input{worklog}
\end{document}

View File

@@ -0,0 +1,41 @@
import random
import os, shutil
NUM_READ_WRITES = 10
NUM_FILES = 100
RANDOM_PATH = "/dev/zero"
dev_random = open(RANDOM_PATH, "r")
FILES_FOLDER = "files"
file_test_structure = {
"file": None,
"size": None
}
ALL_FILES = []
if os.path.isdir(FILES_FOLDER):
shutil.rmtree(FILES_FOLDER)
os.mkdir(FILES_FOLDER)
for i in range(NUM_FILES):
temp = dict(file_test_structure)
temp["file"] = open(FILES_FOLDER + "/" + str(i)+ ".txt", "w+")
temp["size"] = random.randint(1000000, 10000000)
ALL_FILES.append(temp)
for i in range(NUM_READ_WRITES):
for j in range(NUM_FILES):
current_file = ALL_FILES[j]
current_file["file"].seek(0)
current_file["file"].write(dev_random.read(current_file["size"]))
for j in range(NUM_FILES):
current_file = ALL_FILES[j]
current_file["file"].seek(0)
current_file["file"].read(current_file["size"])

View File

@@ -0,0 +1,31 @@
# This config is copied from overleaf so output there will match compiled output here
# support for the glossaries package:
add_cus_dep('glo', 'gls', 0, 'makeglossaries');
add_cus_dep('acn', 'acr', 0, 'makeglossaries');
sub makeglossaries {
system("makeglossaries \"$_[0]\"");
}
# support for the nomencl package:
add_cus_dep('nlo', 'nls', 0, 'makenlo2nls');
sub makenlo2nls {
system("makeindex -s nomencl.ist -o \"$_[0].nls\" \"$_[0].nlo\"");
}
# from the documentation for V. 2.03 of asymptote:
sub asy {return system("asy \"$_[0]\"");}
add_cus_dep("asy","eps",0,"asy");
add_cus_dep("asy","pdf",0,"asy");
add_cus_dep("asy","tex",0,"asy");
# metapost rule from http://tex.stackexchange.com/questions/37134
add_cus_dep('mp', '1', 0, 'mpost');
sub mpost {
my $file = $_[0];
my ($name, $path) = fileparse($file);
pushd($path);
my $return = system "mpost $name";
popd();
return $return;
}

View File

@@ -0,0 +1,19 @@
# Makefile created by Corwin Perren
# Generic makefile for all LaTeX projects downloaded from overleaf
#
# All this makefile does is call perl against latexmkrc, which is
# the latex equivalent of make
LATEXMK_COMPILE_FLAGS = -cd -pdf homework2.tex
LATEXMK_CLEAN_FLAGS = -c
.DEFAULT_GOAL := all
all: latexmk_output clean
latexmk_output:
perl latexmk.pl $(LATEXMK_COMPILE_FLAGS)
mv homework2.pdf CS444_project2_4.pdf
clean:
perl latexmk.pl $(LATEXMK_CLEAN_FLAGS)

View File

@@ -0,0 +1,19 @@
\section{Questions}
\subsection{Point of Assignment}
The point of this assignment was to explore the way that elevator algorithms are implemented as well as getting acquainted with going through all the steps needed to make and apply changes to Linux kernel modules. This required looking through the kernel elevator source files and performing research to determine how to adapt our elevator algorithm. Additionally, this assignment was an initial experience creating a patch for the Linux kernel.
\subsection{Problem Approach}
We approached this problem by first reading through the Homework 2 page on Canvas and reading through the information on the noop and LOOK/CLOOK algorithms on the "I/O and provided functionality" page on Canvas. Next the "noop-iosched.c" file was copied to "sstf-iosched.c" and all references to noop were changed to sstf. Research was then performed to figure out how to get the kernel to compile, recognize, and use this scheduler. The "noop-iosched.c" file and the files it is dependent on were also explored to learn how this scheduling algorithm was implemented.
After this initial set-up and research, it was decided to implement the LOOK algorithm because it is the more efficient algorithm that seemed like a better choice, especially in real world use cases. In order to ensure that the queue is sorted, insertion sort is used for each of the new items added. Printk statements were placed in the queue add function to ensure that printed results of the queue's state matched what was expected from the LOOK algorithm.
\subsection{Correctness}
We know that the end result was correct by using the output of the printk function calls mentioned above to log the blocks for each request as they were added and dispatched. We also added printouts of the whole queue each time an entry was added, to ensure that the entry was placed in the expected location. With these statements on the screen, verifying correctness was as simple as making sure block numbers in the queue were being added in such that if the head were on its way "up" or "down", that the data in the queue matched the current direction.
To ensure that the implementation worked for all reasonable accesses of the drive, a python script was written to generate many randomly sized files, as well as to randomly read this data back. By changing the number of times that the randomly generated files were read/written we were able to test the scheduler until varying scenarios of use.
\subsection{What Was Learned}
We learned that documentation is extremely important to code development as it allows readers to more easily use code that has already been written. There are not many comments in the "noop-iosched.c" or the "elevator.c" file to describe how the various functions work, and this made it difficult to understand exactly how the previously written code functioned. We also learned that it can be challenging to debug while working with the kernel because sometimes the only error that you see is that the kernel does not boot, at which point using the GDB debugger is needed.
\subsection{How to Evaluate}
After applying the patch file, building the kernel, and booting the VM, you should be able to see prints to the screen once the scheduler is loaded and applied to the main boot device /dev/hda. At this point, there were be a few different kinds of statements to look out for. The first will start with "[SSTF\_GROUP4] Adding ...." that will tell you when a new item is being added to the queue, what block number the access is for, and whether this is a read or write. After these add prints there will be a printout of the whole elevator queue that will immediately allow you to see where the new entry was placed in the queue. Once the system is ready for a dispatch, the kernel will also print a statement starting with "[SSTF\_GROUP4] Dispatching:..." telling you what block is being dispatched, and whether it's a read or write. By watching changes to these statements as the kernel is booting, or by using a program to generate IO, correctness of the implementation can easily be verified. We have included the python file io\_test.py in our tarball if you want to use it to generate the IO that we did for testing.

View File

@@ -0,0 +1,15 @@
\section{Version Control Log}
\begin{center}
\begin{tabular}{l l l l} \textbf{Detail} & \textbf{Author} & \textbf{Date} &\textbf{Description}\\\hline
\href{.//commit/9aba09af70810709d27af320d740e677c498b79f}{9aba09a} & Corwin Perren & 2018-05-04 17:33:16 -0700 &Refactored for easier development. Added initial sstf file. Tested kernel change name. Started virtual machine as ide drive.\\\hline
\href{.//commit/07b427a502f82dd300e79f2bce18a2f56a65fc55}{07b427a} & Corwin Perren & 2018-05-04 18:14:07 -0700 &Compiled sstf. Added untouched directory to gitignore so it doesn't have to check it each time\\\hline
\href{.//commit/690e1a6793997bea1e327810eca7dd2838b131a3}{690e1a6} & Corwin Perren & 2018-05-04 20:31:36 -0700 &Works, but is confusing\\\hline
\href{.//commit/9b48e6ccf10fa5b356e2ce6f1ef185c8af0c3e8b}{9b48e6c} & Corwin Perren & 2018-05-05 14:57:26 -0700 &Added new version of sstf. Removed unneeded files.\\\hline
\href{.//commit/ce39f4775a5172d033dcd86a0ac0613af748830b}{ce39f47} & Corwin Perren & 2018-05-05 16:38:26 -0700 &Final version of homework 2\\\hline
\href{.//commit/58376ddc3bb9791d8c277ef5612118bbe6522f55}{58376dd} & Corwin Perren & 2018-05-05 17:39:40 -0700 &Added patch file for homework2\\\hline
\end{tabular}
\end{center}

View File

@@ -0,0 +1,17 @@
\section{Work Log}
\begin{itemize}
\item 2018-05-04
\begin{itemize}
\item Group met in Valley Library
\item Started Latex document for Homework 2
\item Copied noop elevator
\item Figured out how to get the kernel to use the new elevator
\item Started implementing the LOOK algorithm
\end{itemize}
\item 2018-05-05
\begin{itemize}
\item Group met in Valley Library
\item Finished implementing the LOOK algorithm
\item Created patch file
\end{itemize}
\end{itemize}