Commit 03497495 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] standalone elevator noop

From: Nick Piggin <piggin@cyberone.com.au>

Following patch seperates elevator noop, and allows it to be treated
like the other schedulers.
parent 9633628e
config IOSCHED_NOOP
bool "No-op I/O scheduler" if EMBEDDED
default y
---help---
The no-op I/O scheduler is a minimal scheduler that does basic merging
and sorting. Its main uses include non-disk based block devices like
memory devices, and specialised software or hardware environments
that do their own scheduling and require only minimal assistance from
the kernel.
config IOSCHED_AS config IOSCHED_AS
bool "Anticipatory I/O scheduler" if EMBEDDED bool "Anticipatory I/O scheduler" if EMBEDDED
default y default y
---help---
The anticipatory I/O scheduler is the default disk scheduler. It is
generally a good choice for most environments, but is quite large and
complex when compared to the deadline I/O scheduler, it can also be
slower in some cases especially some database loads.
config IOSCHED_DEADLINE config IOSCHED_DEADLINE
bool "Deadline I/O scheduler" if EMBEDDED bool "Deadline I/O scheduler" if EMBEDDED
default y default y
---help---
The deadline I/O scheduler is simple and compact, and is often as
good as the anticipatory I/O scheduler, and in some database
workloads, better. In the case of a single process performing I/O to
a disk at any one time, its behaviour is almost identical to the
anticipatory I/O scheduler and so is a good choice.
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
obj-$(CONFIG_IOSCHED_AS) += as-iosched.o obj-$(CONFIG_IOSCHED_AS) += as-iosched.o
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
obj-$(CONFIG_MAC_FLOPPY) += swim3.o obj-$(CONFIG_MAC_FLOPPY) += swim3.o
......
...@@ -86,72 +86,6 @@ inline int elv_try_last_merge(request_queue_t *q, struct bio *bio) ...@@ -86,72 +86,6 @@ inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
return ELEVATOR_NO_MERGE; return ELEVATOR_NO_MERGE;
} }
/*
* elevator noop
*
* See if we can find a request that this buffer can be coalesced with.
*/
int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
struct bio *bio)
{
struct list_head *entry = &q->queue_head;
struct request *__rq;
int ret;
if ((ret = elv_try_last_merge(q, bio))) {
*insert = q->last_merge;
return ret;
}
while ((entry = entry->prev) != &q->queue_head) {
__rq = list_entry_rq(entry);
if (__rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER))
break;
else if (__rq->flags & REQ_STARTED)
break;
if (!blk_fs_request(__rq))
continue;
if ((ret = elv_try_merge(__rq, bio))) {
*insert = &__rq->queuelist;
q->last_merge = &__rq->queuelist;
return ret;
}
}
return ELEVATOR_NO_MERGE;
}
void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
struct request *next)
{
list_del_init(&next->queuelist);
}
void elevator_noop_add_request(request_queue_t *q, struct request *rq,
struct list_head *insert_here)
{
list_add_tail(&rq->queuelist, &q->queue_head);
/*
* new merges must not precede this barrier
*/
if (rq->flags & REQ_HARDBARRIER)
q->last_merge = NULL;
else if (!q->last_merge)
q->last_merge = &rq->queuelist;
}
struct request *elevator_noop_next_request(request_queue_t *q)
{
if (!list_empty(&q->queue_head))
return list_entry_rq(q->queue_head.next);
return NULL;
}
/* /*
* general block -> elevator interface starts here * general block -> elevator interface starts here
*/ */
...@@ -415,18 +349,8 @@ void elv_unregister_queue(struct request_queue *q) ...@@ -415,18 +349,8 @@ void elv_unregister_queue(struct request_queue *q)
} }
} }
elevator_t elevator_noop = {
.elevator_merge_fn = elevator_noop_merge,
.elevator_merge_req_fn = elevator_noop_merge_requests,
.elevator_next_req_fn = elevator_noop_next_request,
.elevator_add_req_fn = elevator_noop_add_request,
.elevator_name = "noop",
};
module_init(elevator_global_init); module_init(elevator_global_init);
EXPORT_SYMBOL(elevator_noop);
EXPORT_SYMBOL(elv_add_request); EXPORT_SYMBOL(elv_add_request);
EXPORT_SYMBOL(__elv_add_request); EXPORT_SYMBOL(__elv_add_request);
EXPORT_SYMBOL(elv_requeue_request); EXPORT_SYMBOL(elv_requeue_request);
......
...@@ -1232,11 +1232,14 @@ static elevator_t *chosen_elevator = ...@@ -1232,11 +1232,14 @@ static elevator_t *chosen_elevator =
&iosched_as; &iosched_as;
#elif defined(CONFIG_IOSCHED_DEADLINE) #elif defined(CONFIG_IOSCHED_DEADLINE)
&iosched_deadline; &iosched_deadline;
#else #elif defined(CONFIG_IOSCHED_NOOP)
&elevator_noop; &elevator_noop;
#else
NULL;
#error "You must have at least 1 I/O scheduler selected"
#endif #endif
#if defined(CONFIG_IOSCHED_AS) || defined(CONFIG_IOSCHED_DEADLINE) #if defined(CONFIG_IOSCHED_AS) || defined(CONFIG_IOSCHED_DEADLINE) || defined (CONFIG_IOSCHED_NOOP)
static int __init elevator_setup(char *str) static int __init elevator_setup(char *str)
{ {
#ifdef CONFIG_IOSCHED_DEADLINE #ifdef CONFIG_IOSCHED_DEADLINE
...@@ -1246,12 +1249,16 @@ static int __init elevator_setup(char *str) ...@@ -1246,12 +1249,16 @@ static int __init elevator_setup(char *str)
#ifdef CONFIG_IOSCHED_AS #ifdef CONFIG_IOSCHED_AS
if (!strcmp(str, "as")) if (!strcmp(str, "as"))
chosen_elevator = &iosched_as; chosen_elevator = &iosched_as;
#endif
#ifdef CONFIG_IOSCHED_NOOP
if (!strcmp(str, "noop"))
chosen_elevator = &elevator_noop;
#endif #endif
return 1; return 1;
} }
__setup("elevator=", elevator_setup); __setup("elevator=", elevator_setup);
#endif /* CONFIG_IOSCHED_AS || CONFIG_IOSCHED_DEADLINE */ #endif /* CONFIG_IOSCHED_AS || CONFIG_IOSCHED_DEADLINE || CONFIG_IOSCHED_NOOP */
request_queue_t *blk_alloc_queue(int gfp_mask) request_queue_t *blk_alloc_queue(int gfp_mask)
{ {
......
/*
* elevator noop
*/
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/elevator.h>
#include <linux/bio.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/compiler.h>
#include <asm/uaccess.h>
/*
* See if we can find a request that this buffer can be coalesced with.
*/
int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
struct bio *bio)
{
struct list_head *entry = &q->queue_head;
struct request *__rq;
int ret;
if ((ret = elv_try_last_merge(q, bio))) {
*insert = q->last_merge;
return ret;
}
while ((entry = entry->prev) != &q->queue_head) {
__rq = list_entry_rq(entry);
if (__rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER))
break;
else if (__rq->flags & REQ_STARTED)
break;
if (!blk_fs_request(__rq))
continue;
if ((ret = elv_try_merge(__rq, bio))) {
*insert = &__rq->queuelist;
q->last_merge = &__rq->queuelist;
return ret;
}
}
return ELEVATOR_NO_MERGE;
}
void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
struct request *next)
{
list_del_init(&next->queuelist);
}
void elevator_noop_add_request(request_queue_t *q, struct request *rq,
struct list_head *insert_here)
{
list_add_tail(&rq->queuelist, &q->queue_head);
/*
* new merges must not precede this barrier
*/
if (rq->flags & REQ_HARDBARRIER)
q->last_merge = NULL;
else if (!q->last_merge)
q->last_merge = &rq->queuelist;
}
struct request *elevator_noop_next_request(request_queue_t *q)
{
if (!list_empty(&q->queue_head))
return list_entry_rq(q->queue_head.next);
return NULL;
}
elevator_t elevator_noop = {
.elevator_merge_fn = elevator_noop_merge,
.elevator_merge_req_fn = elevator_noop_merge_requests,
.elevator_next_req_fn = elevator_noop_next_request,
.elevator_add_req_fn = elevator_noop_add_request,
.elevator_name = "noop",
};
EXPORT_SYMBOL(elevator_noop);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment