104 lines
3.0 KiB
C
104 lines
3.0 KiB
C
#ifndef _LINUX_ELEVATOR_H
|
|
#define _LINUX_ELEVATOR_H
|
|
|
|
typedef void (elevator_fn) (struct request *, elevator_t *,
|
|
struct list_head *,
|
|
struct list_head *, int);
|
|
|
|
typedef int (elevator_merge_fn) (request_queue_t *, struct request **, struct list_head *,
|
|
struct buffer_head *, int, int);
|
|
|
|
typedef void (elevator_merge_cleanup_fn) (request_queue_t *, struct request *, int);
|
|
|
|
typedef void (elevator_merge_req_fn) (struct request *, struct request *);
|
|
|
|
struct elevator_s
|
|
{
|
|
int read_latency;
|
|
int write_latency;
|
|
|
|
elevator_merge_fn *elevator_merge_fn;
|
|
elevator_merge_req_fn *elevator_merge_req_fn;
|
|
|
|
unsigned int queue_ID;
|
|
};
|
|
|
|
int elevator_noop_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int);
|
|
void elevator_noop_merge_cleanup(request_queue_t *, struct request *, int);
|
|
void elevator_noop_merge_req(struct request *, struct request *);
|
|
|
|
int elevator_linus_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int);
|
|
void elevator_linus_merge_cleanup(request_queue_t *, struct request *, int);
|
|
void elevator_linus_merge_req(struct request *, struct request *);
|
|
|
|
typedef struct blkelv_ioctl_arg_s {
|
|
int queue_ID;
|
|
int read_latency;
|
|
int write_latency;
|
|
int max_bomb_segments;
|
|
} blkelv_ioctl_arg_t;
|
|
|
|
#define BLKELVGET _IOR(0x12,106,sizeof(blkelv_ioctl_arg_t))
|
|
#define BLKELVSET _IOW(0x12,107,sizeof(blkelv_ioctl_arg_t))
|
|
|
|
extern int blkelvget_ioctl(elevator_t *, blkelv_ioctl_arg_t *);
|
|
extern int blkelvset_ioctl(elevator_t *, const blkelv_ioctl_arg_t *);
|
|
|
|
extern void elevator_init(elevator_t *, elevator_t);
|
|
|
|
/*
|
|
* Return values from elevator merger
|
|
*/
|
|
#define ELEVATOR_NO_MERGE 0
|
|
#define ELEVATOR_FRONT_MERGE 1
|
|
#define ELEVATOR_BACK_MERGE 2
|
|
|
|
/*
|
|
* This is used in the elevator algorithm. We don't prioritise reads
|
|
* over writes any more --- although reads are more time-critical than
|
|
* writes, by treating them equally we increase filesystem throughput.
|
|
* This turns out to give better overall performance. -- sct
|
|
*/
|
|
#define IN_ORDER(s1,s2) \
|
|
((((s1)->rq_dev == (s2)->rq_dev && \
|
|
(s1)->sector < (s2)->sector)) || \
|
|
(s1)->rq_dev < (s2)->rq_dev)
|
|
|
|
#define BHRQ_IN_ORDER(bh, rq) \
|
|
((((bh)->b_rdev == (rq)->rq_dev && \
|
|
(bh)->b_rsector < (rq)->sector)) || \
|
|
(bh)->b_rdev < (rq)->rq_dev)
|
|
|
|
static inline int elevator_request_latency(elevator_t * elevator, int rw)
|
|
{
|
|
int latency;
|
|
|
|
latency = elevator->read_latency;
|
|
if (rw != READ)
|
|
latency = elevator->write_latency;
|
|
|
|
return latency;
|
|
}
|
|
|
|
#define ELV_LINUS_SEEK_COST 1
|
|
|
|
#define ELEVATOR_NOOP \
|
|
((elevator_t) { \
|
|
0, /* read_latency */ \
|
|
0, /* write_latency */ \
|
|
\
|
|
elevator_noop_merge, /* elevator_merge_fn */ \
|
|
elevator_noop_merge_req, /* elevator_merge_req_fn */ \
|
|
})
|
|
|
|
#define ELEVATOR_LINUS \
|
|
((elevator_t) { \
|
|
128, /* read passovers */ \
|
|
512, /* write passovers */ \
|
|
\
|
|
elevator_linus_merge, /* elevator_merge_fn */ \
|
|
elevator_linus_merge_req, /* elevator_merge_req_fn */ \
|
|
})
|
|
|
|
#endif
|