diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-01 12:02:41 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-01 12:02:41 -0400 |
| commit | 8cf1a3fce0b95050b63d451c9d561da0da2aa4d6 (patch) | |
| tree | 0dc7f93474c3be601a5893900db1418dfd60ba5d | |
| parent | fcff06c438b60f415af5983efe92811d6aa02ad1 (diff) | |
| parent | 80799fbb7d10c30df78015b3fa21f7ffcfc0eb2c (diff) | |
Merge branch 'for-3.6/core' of git://git.kernel.dk/linux-block
Pull core block IO bits from Jens Axboe:
"The most complicated part if this is the request allocation rework by
Tejun, which has been queued up for a long time and has been in
for-next ditto as well.
There are a few commits from yesterday and today, mostly trivial and
obvious fixes. So I'm pretty confident that it is sound. It's also
smaller than usual."
* 'for-3.6/core' of git://git.kernel.dk/linux-block:
block: remove dead func declaration
block: add partition resize function to blkpg ioctl
block: uninitialized ioc->nr_tasks triggers WARN_ON
block: do not artificially constrain max_sectors for stacking drivers
blkcg: implement per-blkg request allocation
block: prepare for multiple request_lists
block: add q->nr_rqs[] and move q->rq.elvpriv to q->nr_rqs_elvpriv
blkcg: inline bio_blkcg() and friends
block: allocate io_context upfront
block: refactor get_request[_wait]()
block: drop custom queue draining used by scsi_transport_{iscsi|fc}
mempool: add @gfp_mask to mempool_create_node()
blkcg: make root blkcg allocation use %GFP_KERNEL
blkcg: __blkg_lookup_create() doesn't need radix preload
| -rw-r--r-- | Documentation/block/queue-sysfs.txt | 7 | ||||
| -rw-r--r-- | block/blk-cgroup.c | 139 | ||||
| -rw-r--r-- | block/blk-cgroup.h | 128 | ||||
| -rw-r--r-- | block/blk-core.c | 209 | ||||
| -rw-r--r-- | block/blk-ioc.c | 1 | ||||
| -rw-r--r-- | block/blk-settings.c | 3 | ||||
| -rw-r--r-- | block/blk-sysfs.c | 34 | ||||
| -rw-r--r-- | block/blk-throttle.c | 3 | ||||
| -rw-r--r-- | block/blk.h | 4 | ||||
| -rw-r--r-- | block/bsg-lib.c | 53 | ||||
| -rw-r--r-- | block/genhd.c | 20 | ||||
| -rw-r--r-- | block/ioctl.c | 59 | ||||
| -rw-r--r-- | block/partition-generic.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/scsi_transport_fc.c | 38 | ||||
| -rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 2 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 53 | ||||
| -rw-r--r-- | include/linux/blkpg.h | 1 | ||||
| -rw-r--r-- | include/linux/bsg-lib.h | 1 | ||||
| -rw-r--r-- | include/linux/genhd.h | 57 | ||||
| -rw-r--r-- | include/linux/mempool.h | 3 | ||||
| -rw-r--r-- | mm/mempool.c | 12 |
21 files changed, 530 insertions, 301 deletions
diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt index d8147b336c35..6518a55273e7 100644 --- a/Documentation/block/queue-sysfs.txt +++ b/Documentation/block/queue-sysfs.txt | |||
| @@ -38,6 +38,13 @@ read or write requests. Note that the total allocated number may be twice | |||
| 38 | this amount, since it applies only to reads or writes (not the accumulated | 38 | this amount, since it applies only to reads or writes (not the accumulated |
| 39 | sum). | 39 | sum). |
| 40 | 40 | ||
| 41 | To avoid priority inversion through request starvation, a request | ||
| 42 | queue maintains a separate request pool per each cgroup when | ||
| 43 | CONFIG_BLK_CGROUP is enabled, and this parameter applies to each such | ||
| 44 | per-block-cgroup request pool. IOW, if there are N block cgroups, | ||
| 45 | each request queue may have upto N request pools, each independently | ||
| 46 | regulated by nr_requests. | ||
| 47 | |||
| 41 | read_ahead_kb (RW) | 48 | read_ahead_kb (RW) |
| 42 | ------------------ | 49 | ------------------ |
| 43 | Maximum number of kilobytes to read-ahead for filesystems on this block | 50 | Maximum number of kilobytes to read-ahead for filesystems on this block |
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index e7dee617358e..f3b44a65fc7a 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
| @@ -31,27 +31,6 @@ EXPORT_SYMBOL_GPL(blkcg_root); | |||
| 31 | 31 | ||
| 32 | static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS]; | 32 | static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS]; |
| 33 | 33 | ||
| 34 | struct blkcg *cgroup_to_blkcg(struct cgroup *cgroup) | ||
| 35 | { | ||
| 36 | return container_of(cgroup_subsys_state(cgroup, blkio_subsys_id), | ||
| 37 | struct blkcg, css); | ||
| 38 | } | ||
| 39 | EXPORT_SYMBOL_GPL(cgroup_to_blkcg); | ||
| 40 | |||
| 41 | static struct blkcg *task_blkcg(struct task_struct *tsk) | ||
| 42 | { | ||
| 43 | return container_of(task_subsys_state(tsk, blkio_subsys_id), | ||
| 44 | struct blkcg, css); | ||
| 45 | } | ||
| 46 | |||
| 47 | struct blkcg *bio_blkcg(struct bio *bio) | ||
| 48 | { | ||
| 49 | if (bio && bio->bi_css) | ||
| 50 | return container_of(bio->bi_css, struct blkcg, css); | ||
| 51 | return task_blkcg(current); | ||
| 52 | } | ||
| 53 | EXPORT_SYMBOL_GPL(bio_blkcg); | ||
| 54 | |||
| 55 | static bool blkcg_policy_enabled(struct request_queue *q, | 34 | static bool blkcg_policy_enabled(struct request_queue *q, |
| 56 | const struct blkcg_policy *pol) | 35 | const struct blkcg_policy *pol) |
| 57 | { | 36 | { |
| @@ -84,6 +63,7 @@ static void blkg_free(struct blkcg_gq *blkg) | |||
| 84 | kfree(pd); | 63 | kfree(pd); |
| 85 | } | 64 | } |
| 86 | 65 | ||
| 66 | blk_exit_rl(&blkg->rl); | ||
| 87 | kfree(blkg); | 67 | kfree(blkg); |
| 88 | } | 68 | } |
| 89 | 69 | ||
| @@ -91,16 +71,18 @@ static void blkg_free(struct blkcg_gq *blkg) | |||
| 91 | * blkg_alloc - allocate a blkg | 71 | * blkg_alloc - allocate a blkg |
| 92 | * @blkcg: block cgroup the new blkg is associated with | 72 | * @blkcg: block cgroup the new blkg is associated with |
| 93 | * @q: request_queue the new blkg is associated with | 73 | * @q: request_queue the new blkg is associated with |
| 74 | * @gfp_mask: allocation mask to use | ||
| 94 | * | 75 | * |
| 95 | * Allocate a new blkg assocating @blkcg and @q. | 76 | * Allocate a new blkg assocating @blkcg and @q. |
| 96 | */ | 77 | */ |
| 97 | static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q) | 78 | static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q, |
| 79 | gfp_t gfp_mask) | ||
| 98 | { | 80 | { |
| 99 | struct blkcg_gq *blkg; | 81 | struct blkcg_gq *blkg; |
| 100 | int i; | 82 | int i; |
| 101 | 83 | ||
| 102 | /* alloc and init base part */ | 84 | /* alloc and init base part */ |
| 103 | blkg = kzalloc_node(sizeof(*blkg), GFP_ATOMIC, q->node); | 85 | blkg = kzalloc_node(sizeof(*blkg), gfp_mask, q->node); |
| 104 | if (!blkg) | 86 | if (!blkg) |
| 105 | return NULL; | 87 | return NULL; |
| 106 | 88 | ||
| @@ -109,6 +91,13 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q) | |||
| 109 | blkg->blkcg = blkcg; | 91 | blkg->blkcg = blkcg; |
| 110 | blkg->refcnt = 1; | 92 | blkg->refcnt = 1; |
| 111 | 93 | ||
| 94 | /* root blkg uses @q->root_rl, init rl only for !root blkgs */ | ||
| 95 | if (blkcg != &blkcg_root) { | ||
| 96 | if (blk_init_rl(&blkg->rl, q, gfp_mask)) | ||
| 97 | goto err_free; | ||
| 98 | blkg->rl.blkg = blkg; | ||
| 99 | } | ||
| 100 | |||
| 112 | for (i = 0; i < BLKCG_MAX_POLS; i++) { | 101 | for (i = 0; i < BLKCG_MAX_POLS; i++) { |
| 113 | struct blkcg_policy *pol = blkcg_policy[i]; | 102 | struct blkcg_policy *pol = blkcg_policy[i]; |
| 114 | struct blkg_policy_data *pd; | 103 | struct blkg_policy_data *pd; |
| @@ -117,11 +106,9 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q) | |||
| 117 | continue; | 106 | continue; |
| 118 | 107 | ||
| 119 | /* alloc per-policy data and attach it to blkg */ | 108 | /* alloc per-policy data and attach it to blkg */ |
| 120 | pd = kzalloc_node(pol->pd_size, GFP_ATOMIC, q->node); | 109 | pd = kzalloc_node(pol->pd_size, gfp_mask, q->node); |
| 121 | if (!pd) { | 110 | if (!pd) |
| 122 | blkg_free(blkg); | 111 | goto err_free; |
| 123 | return NULL; | ||
| 124 | } | ||
| 125 | 112 | ||
| 126 | blkg->pd[i] = pd; | 113 | blkg->pd[i] = pd; |
| 127 | pd->blkg = blkg; | 114 | pd->blkg = blkg; |
| @@ -132,6 +119,10 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q) | |||
| 132 | } | 119 | } |
| 133 | 120 | ||
| 134 | return blkg; | 121 | return blkg; |
| 122 | |||
| 123 | err_free: | ||
| 124 | blkg_free(blkg); | ||
| 125 | return NULL; | ||
| 135 | } | 126 | } |
| 136 | 127 | ||
| 137 | static struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg, | 128 | static struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg, |
| @@ -175,9 +166,13 @@ struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, struct request_queue *q) | |||
| 175 | } | 166 | } |
| 176 | EXPORT_SYMBOL_GPL(blkg_lookup); | 167 | EXPORT_SYMBOL_GPL(blkg_lookup); |
| 177 | 168 | ||
| 169 | /* | ||
| 170 | * If @new_blkg is %NULL, this function tries to allocate a new one as | ||
| 171 | * necessary using %GFP_ATOMIC. @new_blkg is always consumed on return. | ||
| 172 | */ | ||
| 178 | static struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg, | 173 | static struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg, |
| 179 | struct request_queue *q) | 174 | struct request_queue *q, |
| 180 | __releases(q->queue_lock) __acquires(q->queue_lock) | 175 | struct blkcg_gq *new_blkg) |
| 181 | { | 176 | { |
| 182 | struct blkcg_gq *blkg; | 177 | struct blkcg_gq *blkg; |
| 183 | int ret; | 178 | int ret; |
| @@ -189,24 +184,26 @@ static struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg, | |||
| 189 | blkg = __blkg_lookup(blkcg, q); | 184 | blkg = __blkg_lookup(blkcg, q); |
| 190 | if (blkg) { | 185 | if (blkg) { |
| 191 | rcu_assign_pointer(blkcg->blkg_hint, blkg); | 186 | rcu_assign_pointer(blkcg->blkg_hint, blkg); |
| 192 | return blkg; | 187 | goto out_free; |
| 193 | } | 188 | } |
| 194 | 189 | ||
| 195 | /* blkg holds a refe | ||
