diff options
| -rw-r--r-- | drivers/md/dm-mpath.c | 6 | ||||
| -rw-r--r-- | drivers/md/dm.c | 38 | ||||
| -rw-r--r-- | drivers/md/dm.h | 2 |
3 files changed, 42 insertions, 4 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index e08be94959fd..de570a558764 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include <linux/device-mapper.h> | 8 | #include <linux/device-mapper.h> |
| 9 | 9 | ||
| 10 | #include "dm.h" | ||
| 10 | #include "dm-path-selector.h" | 11 | #include "dm-path-selector.h" |
| 11 | #include "dm-uevent.h" | 12 | #include "dm-uevent.h" |
| 12 | 13 | ||
| @@ -116,8 +117,6 @@ struct dm_mpath_io { | |||
| 116 | 117 | ||
| 117 | typedef int (*action_fn) (struct pgpath *pgpath); | 118 | typedef int (*action_fn) (struct pgpath *pgpath); |
| 118 | 119 | ||
| 119 | #define MIN_IOS 256 /* Mempool size */ | ||
| 120 | |||
| 121 | static struct kmem_cache *_mpio_cache; | 120 | static struct kmem_cache *_mpio_cache; |
| 122 | 121 | ||
| 123 | static struct workqueue_struct *kmultipathd, *kmpath_handlerd; | 122 | static struct workqueue_struct *kmultipathd, *kmpath_handlerd; |
| @@ -190,6 +189,7 @@ static void free_priority_group(struct priority_group *pg, | |||
| 190 | static struct multipath *alloc_multipath(struct dm_target *ti) | 189 | static struct multipath *alloc_multipath(struct dm_target *ti) |
| 191 | { | 190 | { |
| 192 | struct multipath *m; | 191 | struct multipath *m; |
| 192 | unsigned min_ios = dm_get_reserved_rq_based_ios(); | ||
| 193 | 193 | ||
| 194 | m = kzalloc(sizeof(*m), GFP_KERNEL); | 194 | m = kzalloc(sizeof(*m), GFP_KERNEL); |
| 195 | if (m) { | 195 | if (m) { |
| @@ -202,7 +202,7 @@ static struct multipath *alloc_multipath(struct dm_target *ti) | |||
| 202 | INIT_WORK(&m->trigger_event, trigger_event); | 202 | INIT_WORK(&m->trigger_event, trigger_event); |
| 203 | init_waitqueue_head(&m->pg_init_wait); | 203 | init_waitqueue_head(&m->pg_init_wait); |
| 204 | mutex_init(&m->work_mutex); | 204 | mutex_init(&m->work_mutex); |
| 205 | m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); | 205 | m->mpio_pool = mempool_create_slab_pool(min_ios, _mpio_cache); |
| 206 | if (!m->mpio_pool) { | 206 | if (!m->mpio_pool) { |
| 207 | kfree(m); | 207 | kfree(m); |
| 208 | return NULL; | 208 | return NULL; |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index f2e5a50ee84e..1e85f1da1ef3 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
| @@ -213,9 +213,41 @@ struct dm_md_mempools { | |||
| 213 | 213 | ||
| 214 | #define RESERVED_BIO_BASED_IOS 16 | 214 | #define RESERVED_BIO_BASED_IOS 16 |
| 215 | #define RESERVED_REQUEST_BASED_IOS 256 | 215 | #define RESERVED_REQUEST_BASED_IOS 256 |
| 216 | #define RESERVED_MAX_IOS 1024 | ||
| 216 | static struct kmem_cache *_io_cache; | 217 | static struct kmem_cache *_io_cache; |
| 217 | static struct kmem_cache *_rq_tio_cache; | 218 | static struct kmem_cache *_rq_tio_cache; |
| 218 | 219 | ||
| 220 | /* | ||
| 221 | * Request-based DM's mempools' reserved IOs set by the user. | ||
| 222 | */ | ||
| 223 | static unsigned reserved_rq_based_ios = RESERVED_REQUEST_BASED_IOS; | ||
| 224 | |||
| 225 | static unsigned __dm_get_reserved_ios(unsigned *reserved_ios, | ||
| 226 | unsigned def, unsigned max) | ||
| 227 | { | ||
| 228 | unsigned ios = ACCESS_ONCE(*reserved_ios); | ||
| 229 | unsigned modified_ios = 0; | ||
| 230 | |||
| 231 | if (!ios) | ||
| 232 | modified_ios = def; | ||
| 233 | else if (ios > max) | ||
| 234 | modified_ios = max; | ||
| 235 | |||
| 236 | if (modified_ios) { | ||
| 237 | (void)cmpxchg(reserved_ios, ios, modified_ios); | ||
| 238 | ios = modified_ios; | ||
| 239 | } | ||
| 240 | |||
| 241 | return ios; | ||
| 242 | } | ||
| 243 | |||
| 244 | unsigned dm_get_reserved_rq_based_ios(void) | ||
| 245 | { | ||
| 246 | return __dm_get_reserved_ios(&reserved_rq_based_ios, | ||
| 247 | RESERVED_REQUEST_BASED_IOS, RESERVED_MAX_IOS); | ||
| 248 | } | ||
| 249 | EXPORT_SYMBOL_GPL(dm_get_reserved_rq_based_ios); | ||
| 250 | |||
| 219 | static int __init local_init(void) | 251 | static int __init local_init(void) |
| 220 | { | 252 | { |
| 221 | int r = -ENOMEM; | 253 | int r = -ENOMEM; |
| @@ -2878,7 +2910,7 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity, u | |||
| 2878 | front_pad = roundup(per_bio_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone); | 2910 | front_pad = roundup(per_bio_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone); |
| 2879 | } else if (type == DM_TYPE_REQUEST_BASED) { | 2911 | } else if (type == DM_TYPE_REQUEST_BASED) { |
| 2880 | cachep = _rq_tio_cache; | 2912 | cachep = _rq_tio_cache; |
| 2881 | pool_size = RESERVED_REQUEST_BASED_IOS; | 2913 | pool_size = dm_get_reserved_rq_based_ios(); |
| 2882 | front_pad = offsetof(struct dm_rq_clone_bio_info, clone); | 2914 | front_pad = offsetof(struct dm_rq_clone_bio_info, clone); |
| 2883 | /* per_bio_data_size is not used. See __bind_mempools(). */ | 2915 | /* per_bio_data_size is not used. See __bind_mempools(). */ |
| 2884 | WARN_ON(per_bio_data_size != 0); | 2916 | WARN_ON(per_bio_data_size != 0); |
| @@ -2936,6 +2968,10 @@ module_exit(dm_exit); | |||
| 2936 | 2968 | ||
| 2937 | module_param(major, uint, 0); | 2969 | module_param(major, uint, 0); |
| 2938 | MODULE_PARM_DESC(major, "The major number of the device mapper"); | 2970 | MODULE_PARM_DESC(major, "The major number of the device mapper"); |
| 2971 | |||
| 2972 | module_param(reserved_rq_based_ios, uint, S_IRUGO | S_IWUSR); | ||
| 2973 | MODULE_PARM_DESC(reserved_rq_based_ios, "Reserved IOs in request-based mempools"); | ||
| 2974 | |||
| 2939 | MODULE_DESCRIPTION(DM_NAME " driver"); | 2975 | MODULE_DESCRIPTION(DM_NAME " driver"); |
| 2940 | MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); | 2976 | MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); |
| 2941 | MODULE_LICENSE("GPL"); | 2977 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 5e604cc7b4aa..15396501e0b3 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h | |||
| @@ -184,6 +184,8 @@ void dm_free_md_mempools(struct dm_md_mempools *pools); | |||
| 184 | /* | 184 | /* |
| 185 | * Helpers that are used by DM core | 185 | * Helpers that are used by DM core |
| 186 | */ | 186 | */ |
| 187 | unsigned dm_get_reserved_rq_based_ios(void); | ||
| 188 | |||
| 187 | static inline bool dm_message_test_buffer_overflow(char *result, unsigned maxlen) | 189 | static inline bool dm_message_test_buffer_overflow(char *result, unsigned maxlen) |
| 188 | { | 190 | { |
| 189 | return !maxlen || strlen(result) + 1 >= maxlen; | 191 | return !maxlen || strlen(result) + 1 >= maxlen; |
