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 +#include +#include +#include +#include +#include + +//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");