linux/block/elevator.c

// SPDX-License-Identifier: GPL-2.0
/*
 *  Block device elevator/IO-scheduler.
 *
 *  Copyright (C) 2000 Andrea Arcangeli <[email protected]> SuSE
 *
 * 30042000 Jens Axboe <[email protected]> :
 *
 * Split the elevator a bit so that it is possible to choose a different
 * one or even write a new "plug in". There are three pieces:
 * - elevator_fn, inserts a new request in the queue list
 * - elevator_merge_fn, decides whether a new buffer can be merged with
 *   an existing request
 * - elevator_dequeue_fn, called when a request is taken off the active list
 *
 * 20082000 Dave Jones <[email protected]> :
 * Removed tests for max-bomb-segments, which was breaking elvtune
 *  when run without -bN
 *
 * Jens:
 * - Rework again to work with bio instead of buffer_heads
 * - loose bi_dev comparisons, partition handling is right now
 * - completely modularize elevator setup and teardown
 *
 */
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/compiler.h>
#include <linux/blktrace_api.h>
#include <linux/hash.h>
#include <linux/uaccess.h>
#include <linux/pm_runtime.h>

#include <trace/events/block.h>

#include "elevator.h"
#include "blk.h"
#include "blk-mq-sched.h"
#include "blk-pm.h"
#include "blk-wbt.h"
#include "blk-cgroup.h"

static DEFINE_SPINLOCK(elv_list_lock);
static LIST_HEAD(elv_list);

/*
 * Merge hash stuff.
 */
#define rq_hash_key(rq)

/*
 * Query io scheduler to see if the current process issuing bio may be
 * merged with rq.
 */
static bool elv_iosched_allow_bio_merge(struct request *rq, struct bio *bio)
{}

/*
 * can we safely merge with this request?
 */
bool elv_bio_merge_ok(struct request *rq, struct bio *bio)
{}
EXPORT_SYMBOL();

/**
 * elevator_match - Check whether @e's name or alias matches @name
 * @e: Scheduler to test
 * @name: Elevator name to test
 *
 * Return true if the elevator @e's name or alias matches @name.
 */
static bool elevator_match(const struct elevator_type *e, const char *name)
{}

static struct elevator_type *__elevator_find(const char *name)
{}

static struct elevator_type *elevator_find_get(struct request_queue *q,
		const char *name)
{}

static const struct kobj_type elv_ktype;

struct elevator_queue *elevator_alloc(struct request_queue *q,
				  struct elevator_type *e)
{}
EXPORT_SYMBOL();

static void elevator_release(struct kobject *kobj)
{}

void elevator_exit(struct request_queue *q)
{}

static inline void __elv_rqhash_del(struct request *rq)
{}

void elv_rqhash_del(struct request_queue *q, struct request *rq)
{}
EXPORT_SYMBOL_GPL();

void elv_rqhash_add(struct request_queue *q, struct request *rq)
{}
EXPORT_SYMBOL_GPL();

void elv_rqhash_reposition(struct request_queue *q, struct request *rq)
{}

struct request *elv_rqhash_find(struct request_queue *q, sector_t offset)
{}

/*
 * RB-tree support functions for inserting/lookup/removal of requests
 * in a sorted RB tree.
 */
void elv_rb_add(struct rb_root *root, struct request *rq)
{}
EXPORT_SYMBOL();

void elv_rb_del(struct rb_root *root, struct request *rq)
{}
EXPORT_SYMBOL();

struct request *elv_rb_find(struct rb_root *root, sector_t sector)
{}
EXPORT_SYMBOL();

enum elv_merge elv_merge(struct request_queue *q, struct request **req,
		struct bio *bio)
{}

/*
 * Attempt to do an insertion back merge. Only check for the case where
 * we can append 'rq' to an existing request, so we can throw 'rq' away
 * afterwards.
 *
 * Returns true if we merged, false otherwise. 'free' will contain all
 * requests that need to be freed.
 */
bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq,
			      struct list_head *free)
{}

void elv_merged_request(struct request_queue *q, struct request *rq,
		enum elv_merge type)
{}

void elv_merge_requests(struct request_queue *q, struct request *rq,
			     struct request *next)
{}

struct request *elv_latter_request(struct request_queue *q, struct request *rq)
{}

struct request *elv_former_request(struct request_queue *q, struct request *rq)
{}

#define to_elv(atr)

static ssize_t
elv_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
{}

static ssize_t
elv_attr_store(struct kobject *kobj, struct attribute *attr,
	       const char *page, size_t length)
{}

static const struct sysfs_ops elv_sysfs_ops =;

static const struct kobj_type elv_ktype =;

int elv_register_queue(struct request_queue *q, bool uevent)
{}

void elv_unregister_queue(struct request_queue *q)
{}

int elv_register(struct elevator_type *e)
{}
EXPORT_SYMBOL_GPL();

void elv_unregister(struct elevator_type *e)
{}
EXPORT_SYMBOL_GPL();

static inline bool elv_support_iosched(struct request_queue *q)
{}

/*
 * For single queue devices, default to using mq-deadline. If we have multiple
 * queues or mq-deadline is not available, default to "none".
 */
static struct elevator_type *elevator_get_default(struct request_queue *q)
{}

/*
 * Use the default elevator settings. If the chosen elevator initialization
 * fails, fall back to the "none" elevator (no elevator).
 */
void elevator_init_mq(struct request_queue *q)
{}

/*
 * Switch to new_e io scheduler.
 *
 * If switching fails, we are most likely running out of memory and not able
 * to restore the old io scheduler, so leaving the io scheduler being none.
 */
int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
{}

void elevator_disable(struct request_queue *q)
{}

/*
 * Switch this queue to the given IO scheduler.
 */
static int elevator_change(struct request_queue *q, const char *elevator_name)
{}

ssize_t elv_iosched_store(struct gendisk *disk, const char *buf,
			  size_t count)
{}

ssize_t elv_iosched_show(struct gendisk *disk, char *name)
{}

struct request *elv_rb_former_request(struct request_queue *q,
				      struct request *rq)
{}
EXPORT_SYMBOL();

struct request *elv_rb_latter_request(struct request_queue *q,
				      struct request *rq)
{}
EXPORT_SYMBOL();

static int __init elevator_setup(char *str)
{}

__setup();