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
-~----------~----~----~----~------~----~------~--~---

Reply via email to