Advertisement
Guest User

Untitled

a guest
Jun 27th, 2017
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.55 KB | None | 0 0
  1. /*
  2.  * elevator noop
  3.  */
  4. #include <linux/blkdev.h>
  5. #include <linux/elevator.h>
  6. #include <linux/bio.h>
  7. #include <linux/module.h>
  8. #include <linux/init.h>
  9.  
  10.  
  11. struct noop_data{
  12.     struct list_head queue;
  13.     unsigned long last_request; //last request dispatched
  14. };
  15.  
  16. //elevator_merge_req_fn
  17. static void noop_merged_requests(struct request_queue *q, struct request *rq,
  18.                  struct request *next)
  19. {
  20.     list_del_init(&next->queuelist);
  21. }
  22.  
  23. /*
  24. //elevator_dispatch_fn 
  25. static int noop_dispatch(struct request_queue *q, int force)
  26. {
  27.         printk("*** Begining dispatch_fn ***\n");
  28.         printk("jiffies: %lu\n", jiffies);
  29.  
  30.         return noop_dispatch2(q, force);
  31.  
  32.     struct noop_data *nd = q->elevator->elevator_data;
  33.  
  34.     if (!list_empty(&nd->queue)) {
  35.         struct request *rq;
  36.         rq = list_entry(nd->queue.next, struct request, queuelist);
  37.  
  38.         printk("Request at sector %lu dispatched.\n", rq->sector);
  39.         list_del_init(&rq->queuelist);
  40.         elv_dispatch_sort(q, rq);
  41.  
  42.         printk("*** Ending dispatch_fn ***\n\n");
  43.         return 1;
  44.     }
  45.  
  46.     printk("Request queue empty\n");
  47.     printk("*** Ending dispatch_fn ***\n\n");
  48.     return 0;
  49. }
  50. */
  51.  
  52. /*
  53. //elevator_add_req_fn
  54. static void noop_add_request(struct request_queue *q, struct request *rq)
  55. {
  56.     printk("Add. . .\n-\n-\n-\n-\n-\n-\n-\n-\n-\n");
  57.     struct noop_data *nd = q->elevator->elevator_data;
  58.  
  59.     list_add_tail(&rq->queuelist, &nd->queue);
  60. }*/
  61.  
  62.  
  63. //elevator_queue_empty_fn
  64. static int noop_queue_empty(struct request_queue *q)
  65. {
  66.     struct noop_data *nd = q->elevator->elevator_data;
  67.  
  68.     return list_empty(&nd->queue);
  69. }
  70.  
  71. //elevator_former_req_fn
  72. static struct request *
  73. noop_former_request(struct request_queue *q, struct request *rq)
  74. {
  75.     struct noop_data *nd = q->elevator->elevator_data;
  76.  
  77.     if (rq->queuelist.prev == &nd->queue)
  78.         return NULL;
  79.     return list_entry(rq->queuelist.prev, struct request, queuelist);
  80. }
  81.  
  82. //elevator_latter_req_fn
  83. static struct request *
  84. noop_latter_request(struct request_queue *q, struct request *rq)
  85. {
  86.     struct noop_data *nd = q->elevator->elevator_data;
  87.  
  88.     if (rq->queuelist.next == &nd->queue)
  89.         return NULL;
  90.     return list_entry(rq->queuelist.next, struct request, queuelist);
  91. }
  92.  
  93. static void *noop_init_queue(struct request_queue *q)
  94. {
  95.     printk("Initializing. . .\n-\n-\n-\n-\n-\n-\n-\n-\n-\n");
  96.     struct noop_data *nd;
  97.  
  98.     nd = kmalloc_node(sizeof(*nd), GFP_KERNEL, q->node);
  99.     if (!nd)
  100.         return NULL;
  101.     INIT_LIST_HEAD(&nd->queue);
  102.     nd->last_request = 0;
  103.     return nd;
  104. }
  105.  
  106. static void noop_exit_queue(struct elevator_queue *e)
  107. {
  108.     struct noop_data *nd = e->elevator_data;
  109.  
  110.     BUG_ON(!list_empty(&nd->queue));
  111.     kfree(nd);
  112. }
  113.  
  114. //===================================================================
  115. //===================================================================
  116. //Note: request queue is to be sorted by location of request
  117.  
  118. static int greater2(struct request *x, unsigned long y){
  119.     //unsigned long s1 = (unsigned long) blk_rq_pos(x);
  120.     //unsigned long s2 = (unsigned long) blk_rq_pos(y);
  121.    
  122.     unsigned long s1 = (unsigned long)(x->sector);
  123.     unsigned long s2 = y;
  124.  
  125.     if (s1 > s2)
  126.         return 1;
  127.  
  128.     return 0;
  129. }
  130.  
  131.  
  132. static int greater(struct request *x, struct request *y){
  133.     //unsigned long s1 = (unsigned long) blk_rq_pos(x);
  134.     //unsigned long s2 = (unsigned long) blk_rq_pos(y);
  135.    
  136.     unsigned long s1 = (unsigned long)(x->sector);
  137.     unsigned long s2 = (unsigned long)(y->sector);
  138.  
  139.     if (s1 > s2)
  140.         return 1;
  141.  
  142.     return 0;
  143. }
  144.  
  145. static unsigned long seek_dist(unsigned long x, struct request *y){
  146.     //unsigned long s1 = (unsigned long) blk_rq_pos(x);
  147.     //unsigned long s2 = (unsigned long) blk_rq_pos(y);
  148.  
  149.     if(y == NULL)
  150.         return ULONG_MAX;
  151.  
  152.     unsigned long s1 = x;
  153.     unsigned long s2 = (unsigned long)(y->sector);
  154.  
  155.     if (s1 > s2)
  156.         return s1-s2;
  157.  
  158.     else
  159.         return s2-s1;
  160. }
  161.  
  162.  
  163. //selects request closes to the last dispatched request
  164. static int noop_dispatch(struct request_queue *q, int force){
  165.     printk("*** Begining dispatch_fn *** \n");
  166.     printk("jiffies: %lu\n", jiffies);
  167.  
  168.     struct noop_data *nd = q->elevator->elevator_data;
  169.    unsigned long last_rq = nd->last_request;
  170.  
  171.     if (list_empty(&nd->queue)) {
  172.         printk("Request queue empty.\n");
  173.         printk("*** Ending dispatch_fn *** \n\n");
  174.         return 0;
  175.     }
  176.  
  177.     struct list_head *pos;
  178.     struct request *curr;
  179.     struct request *prev = NULL;
  180.  
  181.     //iterate through request queue
  182.     list_for_each(pos, nd->queue.next) {
  183.         curr = list_entry(pos, struct request, queuelist);
  184.  
  185.         //This if statement comes into effect at the spot in the queue
  186.         //that the most recently dispatched request would be. The closest
  187.         //element is either the current one or the one before it.
  188.  
  189.         //Note: the greater function is a comparison of request locations
  190.         //I'm not sure how to implement this.
  191.         if (greater2(curr, last_rq)) {
  192.             //seek_dist would be a numerical approximation of the
  193.             //distance between two requests.  I still need to implement this.
  194.             unsigned long dist1 = seek_dist(last_rq, curr);
  195.             unsigned long dist2 = seek_dist(last_rq, prev);
  196.  
  197.             if (dist1 < dist2) {
  198.                 printk("Request at sector: %lu dispatched.\n",
  199.                  (unsigned long)(curr->sector));
  200.  
  201.                 nd->last_request = curr->sector;
  202.                 list_del_init(&curr->queuelist);
  203.                 elv_dispatch_sort(q, curr);
  204.             }
  205.             else {
  206.                 printk("Request at sector: %lu dispatched.\n",
  207.                  (unsigned long)(prev->sector));
  208.  
  209.                 nd->last_request = prev->sector;
  210.                 list_del_init(&prev->queuelist);
  211.                 elv_dispatch_sort(q, prev);
  212.             }
  213.             printk("*** Ending dispatch_fn *** \n\n");
  214.             return 1;
  215.         }
  216.         prev = curr;
  217.     }
  218.     printk("Request at sector: %lu dispatched.\n",
  219.         (unsigned long)(prev->sector));
  220.  
  221.     nd->last_request = prev->sector;
  222.     list_del_init(&prev->queuelist);
  223.     elv_dispatch_sort(q, prev);
  224.  
  225.     return 1;
  226. }
  227.  
  228.  
  229. //add the request to the queue in the correct sorted location
  230. static void noop_add_request(struct request_queue *q, struct request *rq) {
  231.     struct noop_data *nd = q->elevator->elevator_data;
  232.     printk("*** Beginning request_add_fn ***\n");
  233.     printk("Request at sector %lu added.\n",
  234.         (unsigned long)(rq->sector));
  235.  
  236.     printk("\tjiffies: %lu\n", jiffies);
  237.  
  238.     if (list_empty(&nd->queue)) {
  239.         list_add_tail(&rq->queuelist, &nd->queue);
  240.         printk("At spot 0\n");
  241.         printk("*** Ending request_add_fn ***\n\n");
  242.         return;
  243.     }
  244.  
  245.     struct list_head *pos;
  246.     struct request *curr;
  247.  
  248.     //same general principle as the list_for_each call in dispatch
  249.     int i = 0;
  250.     list_for_each(pos, nd->queue.next) {
  251.         curr = list_entry(pos, struct request, queuelist);
  252.         if (greater(curr, rq)){
  253.             list_add_tail(&rq->queuelist, &curr->queuelist);
  254.             printk("At spot %d\n", i);
  255.             printk("*** Ending request_add_fn ***\n\n");
  256.             return;
  257.         }
  258.         i++;
  259.     }
  260. }
  261.  
  262.  
  263. //==========================================================================
  264.  
  265. static struct elevator_type elevator_noop = {
  266.     .ops = {
  267.         .elevator_merge_req_fn      = noop_merged_requests,
  268.         .elevator_dispatch_fn       = noop_dispatch,
  269.         .elevator_add_req_fn        = noop_add_request,
  270.         .elevator_queue_empty_fn    = noop_queue_empty,
  271.         .elevator_former_req_fn     = noop_former_request,
  272.         .elevator_latter_req_fn     = noop_latter_request,
  273.         .elevator_init_fn       = noop_init_queue,
  274.         .elevator_exit_fn       = noop_exit_queue,
  275.         //elevator_merge_fn
  276.         //elevator_remove_req_fn
  277.         //elevator_set_req_fn
  278.         //elevator_put_req_fn
  279.     },
  280.     .elevator_name = "anticipatory",
  281.     .elevator_owner = THIS_MODULE,
  282. };
  283.  
  284. static int __init noop_init(void)
  285. {
  286.     elv_register(&elevator_noop);
  287.  
  288.     return 0;
  289. }
  290.  
  291. static void __exit noop_exit(void)
  292. {
  293.     elv_unregister(&elevator_noop);
  294. }
  295.  
  296. module_init(noop_init);
  297. module_exit(noop_exit);
  298.  
  299.  
  300. MODULE_AUTHOR("Jens Axboe");
  301. MODULE_LICENSE("GPL");
  302. MODULE_DESCRIPTION("No-op IO scheduler");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement