From: Daniel Phillips <phill...@google.com> +static ctl_table dm_root_table[] = {
--- Index: linux-2.6.29-rc2/block/blk-core.c =================================================================== --- linux-2.6.29-rc2.orig/block/blk-core.c +++ linux-2.6.29-rc2/block/blk-core.c @@ -1375,9 +1375,9 @@ static inline int bio_check_eod(struct b */ static inline void __generic_make_request(struct bio *bio) { - struct request_queue *q; + struct request_queue *q = bdev_get_queue(bio->bi_bdev); sector_t old_sector; - int ret, nr_sectors = bio_sectors(bio); + int nr_sectors = bio_sectors(bio); dev_t old_dev; int err = -EIO; @@ -1386,6 +1386,13 @@ static inline void __generic_make_reques if (bio_check_eod(bio, nr_sectors)) goto end_io; + if (q && q->metric && !bio->bi_queue) { + int need = bio->bi_max_vecs; + bio->bi_queue = q; + /* FIXME: potential race if atomic_sub is called in the middle of condition check */ + wait_event(q->throttle_wait, atomic_read(&q->available) >= need); + atomic_sub(need, &q->available); + } /* * Resolve the mapping until finished. (drivers are * still free to implement/resolve their own stacking @@ -1396,10 +1403,10 @@ static inline void __generic_make_reques */ old_sector = -1; old_dev = 0; + while (1) { do { char b[BDEVNAME_SIZE]; - q = bdev_get_queue(bio->bi_bdev); if (unlikely(!q)) { printk(KERN_ERR "generic_make_request: Trying to access " @@ -1449,8 +1456,10 @@ static inline void __generic_make_reques goto end_io; } - ret = q->make_request_fn(q, bio); - } while (ret); + if (!q->make_request_fn(q, bio)) + return; + q = bdev_get_queue(bio->bi_bdev); + } return; Index: linux-2.6.29-rc2/drivers/md/dm.c =================================================================== --- linux-2.6.29-rc2.orig/drivers/md/dm.c +++ linux-2.6.29-rc2/drivers/md/dm.c @@ -22,6 +22,7 @@ #include <linux/hdreg.h> #include <linux/blktrace_api.h> #include <trace/block.h> +#include <linux/sysctl.h> #define DM_MSG_PREFIX "core" @@ -175,6 +176,45 @@ struct mapped_device { #define MIN_IOS 256 static struct kmem_cache *_io_cache; static struct kmem_cache *_tio_cache; + +static int sysctl_bio_throttle = 0; + +static ctl_table dm_table[] = { + { + .ctl_name = DEV_DM_BIO_THROTTLE, + .procname = "bio_throttle", + .data = &sysctl_bio_throttle, + .maxlen = sizeof(int), + .mode = S_IRUGO|S_IWUSR, + .proc_handler = &proc_dointvec, + }, + { .ctl_name = 0 } +}; + +static ctl_table dm_dir_table[] = { + { + .ctl_name = DEV_DM, + .procname = "dm", + .maxlen = 0, + .mode = S_IRUGO|S_IXUGO, + .child = dm_table, + }, + { .ctl_name = 0 } +}; + +static struct ctl_table_header *dm_table_header; + +static ctl_table dm_root_table[] = { + { + .ctl_name = CTL_DEV, + .procname = "dev", + .maxlen = 0, + .mode = 0555, + .child = dm_dir_table, + }, + { .ctl_name = 0 } +}; + static struct kmem_cache *_rq_tio_cache; static struct kmem_cache *_rq_bio_info_cache; @@ -272,6 +312,7 @@ static int __init dm_init(void) goto bad; } + dm_table_header = register_sysctl_table(dm_root_table); return 0; bad: @@ -287,6 +328,7 @@ static void __exit dm_exit(void) while (i--) _exits[i](); + unregister_sysctl_table(dm_table_header); } /* @@ -915,6 +957,11 @@ out: return max_size; } +static unsigned dm_metric(struct bio *bio) +{ + return 1; +} + /* * The request function that just remaps the bio built up by * dm_merge_bvec. @@ -1077,6 +1124,7 @@ out: static struct block_device_operations dm_blk_dops; +#define DEFAULT_THROTTLE_CAPACITY 1000 /* * Allocate and initialise a blank device with a given minor. */ @@ -1118,6 +1166,13 @@ static struct mapped_device *alloc_dev(i goto bad_queue; md->queue->queuedata = md; + if (sysctl_bio_throttle == 1) { + md->queue->metric = dm_metric; + /* A dm device constructor may change the throttle capacity */ + atomic_set(&md->queue->available, md->queue->capacity = DEFAULT_THROTTLE_CAPACITY); + init_waitqueue_head(&md->queue->throttle_wait); + } + md->queue->backing_dev_info.congested_fn = dm_any_congested; md->queue->backing_dev_info.congested_data = md; blk_queue_make_request(md->queue, dm_request); Index: linux-2.6.29-rc2/fs/bio.c =================================================================== --- linux-2.6.29-rc2.orig/fs/bio.c +++ linux-2.6.29-rc2/fs/bio.c @@ -1379,6 +1379,13 @@ void bio_endio(struct bio *bio, int erro else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) error = -EIO; + if (bio->bi_queue) { + struct request_queue *q = bio->bi_queue; + atomic_add(bio->bi_max_vecs, &q->available); + bio->bi_queue = NULL; /* 0xdeadbeef? */ + wake_up(&q->throttle_wait); + } + if (bio->bi_end_io) bio->bi_end_io(bio, error); } Index: linux-2.6.29-rc2/include/linux/bio.h =================================================================== --- linux-2.6.29-rc2.orig/include/linux/bio.h +++ linux-2.6.29-rc2/include/linux/bio.h @@ -96,6 +96,7 @@ struct bio { bio_end_io_t *bi_end_io; + struct request_queue *bi_queue; /* for throttling */ void *bi_private; #if defined(CONFIG_BLK_DEV_INTEGRITY) struct bio_integrity_payload *bi_integrity; /* data integrity */ Index: linux-2.6.29-rc2/include/linux/blkdev.h =================================================================== --- linux-2.6.29-rc2.orig/include/linux/blkdev.h +++ linux-2.6.29-rc2/include/linux/blkdev.h @@ -346,6 +346,10 @@ struct request_queue struct work_struct unplug_work; struct backing_dev_info backing_dev_info; + unsigned (*metric)(struct bio *bio); /* (stub) bio throttle metric */ + wait_queue_head_t throttle_wait; + atomic_t available; + unsigned capacity; /* * The queue owner gets to use this for whatever they like. Index: linux-2.6.29-rc2/include/linux/sysctl.h =================================================================== --- linux-2.6.29-rc2.orig/include/linux/sysctl.h +++ linux-2.6.29-rc2/include/linux/sysctl.h @@ -858,6 +858,7 @@ enum { DEV_MAC_HID=5, DEV_SCSI=6, DEV_IPMI=7, + DEV_DM=8 }; /* /proc/sys/dev/cdrom */ @@ -881,6 +882,11 @@ enum { DEV_RAID_SPEED_LIMIT_MAX=2 }; +/* /proc/sys/dev/dm */ +enum { + DEV_DM_BIO_THROTTLE = 1 +}; + /* /proc/sys/dev/parport/default */ enum { DEV_PARPORT_DEFAULT_TIMESLICE=1, Index: linux-2.6.29-rc2/kernel/sysctl_check.c =================================================================== --- linux-2.6.29-rc2.orig/kernel/sysctl_check.c +++ linux-2.6.29-rc2/kernel/sysctl_check.c @@ -869,6 +869,11 @@ static const struct trans_ctl_table tran {} }; +static struct trans_ctl_table trans_dm_table[] = { + { DEV_DM_BIO_THROTTLE, "bio_throttle" }, + {} +}; + static const struct trans_ctl_table trans_dev_table[] = { { DEV_CDROM, "cdrom", trans_cdrom_table }, /* DEV_HWMON unused */ @@ -877,6 +882,7 @@ static const struct trans_ctl_table tran { DEV_MAC_HID, "mac_hid", trans_mac_hid_files }, { DEV_SCSI, "scsi", trans_scsi_table }, { DEV_IPMI, "ipmi", trans_ipmi_table }, + { DEV_DM, "dm", trans_dm_table }, {} }; --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Zumastor" group. To post to this group, send email to zumastor@googlegroups.com To unsubscribe from this group, send email to zumastor+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/zumastor?hl=en -~----------~----~----~----~------~----~------~--~---