lkml.org 
[lkml]   [2006]   [Sep]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 10/21] block: elevator selection and pinning
    Provide an block queue init function that allows to set an elevator. And a 
    function to pin the current elevator.

    Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Signed-off-by: Daniel Phillips <phillips@google.com>
    CC: Jens Axboe <axboe@suse.de>
    CC: Pavel Machek <pavel@ucw.cz>
    ---
    block/elevator.c | 56 ++++++++++++++++++++++++++++++++++++-----------
    block/ll_rw_blk.c | 12 ++++++++--
    include/linux/blkdev.h | 9 +++++++
    include/linux/elevator.h | 1
    4 files changed, 63 insertions(+), 15 deletions(-)

    Index: linux-2.6/block/ll_rw_blk.c
    ===================================================================
    --- linux-2.6.orig/block/ll_rw_blk.c
    +++ linux-2.6/block/ll_rw_blk.c
    @@ -1899,6 +1899,14 @@ EXPORT_SYMBOL(blk_init_queue);
    request_queue_t *
    blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
    {
    + return blk_init_queue_node_elv(rfn, lock, node_id, NULL);
    +}
    +EXPORT_SYMBOL(blk_init_queue_node);
    +
    +request_queue_t *
    +blk_init_queue_node_elv(request_fn_proc *rfn, spinlock_t *lock, int node_id,
    + char *elv_name)
    +{
    request_queue_t *q = blk_alloc_queue_node(GFP_KERNEL, node_id);

    if (!q)
    @@ -1939,7 +1947,7 @@ blk_init_queue_node(request_fn_proc *rfn
    /*
    * all done
    */
    - if (!elevator_init(q, NULL)) {
    + if (!elevator_init(q, elv_name)) {
    blk_queue_congestion_threshold(q);
    return q;
    }
    @@ -1947,7 +1955,7 @@ blk_init_queue_node(request_fn_proc *rfn
    blk_put_queue(q);
    return NULL;
    }
    -EXPORT_SYMBOL(blk_init_queue_node);
    +EXPORT_SYMBOL(blk_init_queue_node_elv);

    int blk_get_queue(request_queue_t *q)
    {
    Index: linux-2.6/include/linux/blkdev.h
    ===================================================================
    --- linux-2.6.orig/include/linux/blkdev.h
    +++ linux-2.6/include/linux/blkdev.h
    @@ -444,6 +444,12 @@ struct request_queue
    #define QUEUE_FLAG_REENTER 6 /* Re-entrancy avoidance */
    #define QUEUE_FLAG_PLUGGED 7 /* queue is plugged */
    #define QUEUE_FLAG_ELVSWITCH 8 /* don't use elevator, just do FIFO */
    +#define QUEUE_FLAG_ELVPINNED 9 /* pin the current elevator */
    +
    +static inline void blk_queue_pin_elevator(struct request_queue *q)
    +{
    + set_bit(QUEUE_FLAG_ELVPINNED, &q->queue_flags);
    +}

    enum {
    /*
    @@ -696,6 +702,9 @@ static inline void elv_dispatch_add_tail
    /*
    * Access functions for manipulating queue properties
    */
    +extern request_queue_t *blk_init_queue_node_elv(request_fn_proc *rfn,
    + spinlock_t *lock, int node_id,
    + char *elv_name);
    extern request_queue_t *blk_init_queue_node(request_fn_proc *rfn,
    spinlock_t *lock, int node_id);
    extern request_queue_t *blk_init_queue(request_fn_proc *, spinlock_t *);
    Index: linux-2.6/block/elevator.c
    ===================================================================
    --- linux-2.6.orig/block/elevator.c
    +++ linux-2.6/block/elevator.c
    @@ -856,11 +856,33 @@ fail_register:
    return 0;
    }

    +int elv_iosched_switch(request_queue_t *q, const char *elevator_name)
    +{
    + struct elevator_type *e;
    +
    + if (test_bit(QUEUE_FLAG_ELVPINNED, &q->queue_flags))
    + return -EPERM;
    +
    + e = elevator_get(elevator_name);
    + if (!e)
    + return -EINVAL;
    +
    + if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
    + elevator_put(e);
    + return -EEXIST;
    + }
    +
    + if (!elevator_switch(q, e))
    + return -ENOMEM;
    +
    + return 0;
    +}
    +
    ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
    {
    char elevator_name[ELV_NAME_MAX];
    size_t len;
    - struct elevator_type *e;
    + int error;

    elevator_name[sizeof(elevator_name) - 1] = '\0';
    strncpy(elevator_name, name, sizeof(elevator_name) - 1);
    @@ -869,20 +891,27 @@ ssize_t elv_iosched_store(request_queue_
    if (len && elevator_name[len - 1] == '\n')
    elevator_name[len - 1] = '\0';

    - e = elevator_get(elevator_name);
    - if (!e) {
    - printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
    - return -EINVAL;
    - }
    -
    - if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
    - elevator_put(e);
    - return count;
    + error = elv_iosched_switch(q, elevator_name);
    + switch (error) {
    + case -EPERM:
    + printk(KERN_NOTICE
    + "elevator: cannot switch elevator, pinned\n");
    + break;
    +
    + case -EINVAL:
    + printk(KERN_ERR "elevator: type %s not found\n",
    + elevator_name);
    + break;
    +
    + case -ENOMEM:
    + printk(KERN_ERR "elevator: switch to %s failed\n",
    + elevator_name);
    + default:
    + error = 0;
    + break;
    }

    - if (!elevator_switch(q, e))
    - printk(KERN_ERR "elevator: switch to %s failed\n",elevator_name);
    - return count;
    + return error ?: count;
    }

    ssize_t elv_iosched_show(request_queue_t *q, char *name)
    @@ -914,5 +943,6 @@ EXPORT_SYMBOL(__elv_add_request);
    EXPORT_SYMBOL(elv_next_request);
    EXPORT_SYMBOL(elv_dequeue_request);
    EXPORT_SYMBOL(elv_queue_empty);
    +EXPORT_SYMBOL(elv_iosched_switch);
    EXPORT_SYMBOL(elevator_exit);
    EXPORT_SYMBOL(elevator_init);
    Index: linux-2.6/include/linux/elevator.h
    ===================================================================
    --- linux-2.6.orig/include/linux/elevator.h
    +++ linux-2.6/include/linux/elevator.h
    @@ -107,6 +107,7 @@ extern int elv_may_queue(request_queue_t
    extern void elv_completed_request(request_queue_t *, struct request *);
    extern int elv_set_request(request_queue_t *, struct request *, struct bio *, gfp_t);
    extern void elv_put_request(request_queue_t *, struct request *);
    +extern int elv_iosched_switch(request_queue_t *, const char *);

    /*
    * io scheduler registration
    --
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-09-06 15:47    [W:0.034 / U:1.260 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site