diff options
author | David Rientjes <rientjes@google.com> | 2015-04-14 18:48:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-14 19:49:06 -0400 |
commit | 11d83360452ea2a95e699da01f8e1bcc4676a5de (patch) | |
tree | 22d85ebbc47a9152cafc9373a8300d0abf92106b | |
parent | 2415b9f5cb048a803b30b790af994ba71ff0bd4c (diff) |
mm, mempool: do not allow atomic resizing
Allocating a large number of elements in atomic context could quickly
deplete memory reserves, so just disallow atomic resizing entirely.
Nothing currently uses mempool_resize() with anything other than
GFP_KERNEL, so convert existing callers to drop the gfp_mask.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: David Rientjes <rientjes@google.com>
Acked-by: Steffen Maier <maier@linux.vnet.ibm.com> [zfcp]
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Steve French <sfrench@samba.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 4 | ||||
-rw-r--r-- | fs/cifs/connect.c | 6 | ||||
-rw-r--r-- | include/linux/mempool.h | 2 | ||||
-rw-r--r-- | mm/mempool.c | 10 |
4 files changed, 11 insertions, 11 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 2c5d4567d1da..acde3f5d6e9e 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -738,11 +738,11 @@ static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *act) | |||
738 | return ZFCP_ERP_FAILED; | 738 | return ZFCP_ERP_FAILED; |
739 | 739 | ||
740 | if (mempool_resize(act->adapter->pool.sr_data, | 740 | if (mempool_resize(act->adapter->pool.sr_data, |
741 | act->adapter->stat_read_buf_num, GFP_KERNEL)) | 741 | act->adapter->stat_read_buf_num)) |
742 | return ZFCP_ERP_FAILED; | 742 | return ZFCP_ERP_FAILED; |
743 | 743 | ||
744 | if (mempool_resize(act->adapter->pool.status_read_req, | 744 | if (mempool_resize(act->adapter->pool.status_read_req, |
745 | act->adapter->stat_read_buf_num, GFP_KERNEL)) | 745 | act->adapter->stat_read_buf_num)) |
746 | return ZFCP_ERP_FAILED; | 746 | return ZFCP_ERP_FAILED; |
747 | 747 | ||
748 | atomic_set(&act->adapter->stat_miss, act->adapter->stat_read_buf_num); | 748 | atomic_set(&act->adapter->stat_miss, act->adapter->stat_read_buf_num); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 480cf9c81d50..f3bfe08e177b 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -773,8 +773,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) | |||
773 | 773 | ||
774 | length = atomic_dec_return(&tcpSesAllocCount); | 774 | length = atomic_dec_return(&tcpSesAllocCount); |
775 | if (length > 0) | 775 | if (length > 0) |
776 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv, | 776 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv); |
777 | GFP_KERNEL); | ||
778 | } | 777 | } |
779 | 778 | ||
780 | static int | 779 | static int |
@@ -848,8 +847,7 @@ cifs_demultiplex_thread(void *p) | |||
848 | 847 | ||
849 | length = atomic_inc_return(&tcpSesAllocCount); | 848 | length = atomic_inc_return(&tcpSesAllocCount); |
850 | if (length > 1) | 849 | if (length > 1) |
851 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv, | 850 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv); |
852 | GFP_KERNEL); | ||
853 | 851 | ||
854 | set_freezable(); | 852 | set_freezable(); |
855 | while (server->tcpStatus != CifsExiting) { | 853 | while (server->tcpStatus != CifsExiting) { |
diff --git a/include/linux/mempool.h b/include/linux/mempool.h index 39ed62ab5b8a..b19b3023c880 100644 --- a/include/linux/mempool.h +++ b/include/linux/mempool.h | |||
@@ -29,7 +29,7 @@ extern mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn, | |||
29 | mempool_free_t *free_fn, void *pool_data, | 29 | mempool_free_t *free_fn, void *pool_data, |
30 | gfp_t gfp_mask, int nid); | 30 | gfp_t gfp_mask, int nid); |
31 | 31 | ||
32 | extern int mempool_resize(mempool_t *pool, int new_min_nr, gfp_t gfp_mask); | 32 | extern int mempool_resize(mempool_t *pool, int new_min_nr); |
33 | extern void mempool_destroy(mempool_t *pool); | 33 | extern void mempool_destroy(mempool_t *pool); |
34 | extern void * mempool_alloc(mempool_t *pool, gfp_t gfp_mask); | 34 | extern void * mempool_alloc(mempool_t *pool, gfp_t gfp_mask); |
35 | extern void mempool_free(void *element, mempool_t *pool); | 35 | extern void mempool_free(void *element, mempool_t *pool); |
diff --git a/mm/mempool.c b/mm/mempool.c index e209c98c7203..949970db2874 100644 --- a/mm/mempool.c +++ b/mm/mempool.c | |||
@@ -113,23 +113,24 @@ EXPORT_SYMBOL(mempool_create_node); | |||
113 | * mempool_create(). | 113 | * mempool_create(). |
114 | * @new_min_nr: the new minimum number of elements guaranteed to be | 114 | * @new_min_nr: the new minimum number of elements guaranteed to be |
115 | * allocated for this pool. | 115 | * allocated for this pool. |
116 | * @gfp_mask: the usual allocation bitmask. | ||
117 | * | 116 | * |
118 | * This function shrinks/grows the pool. In the case of growing, | 117 | * This function shrinks/grows the pool. In the case of growing, |
119 | * it cannot be guaranteed that the pool will be grown to the new | 118 | * it cannot be guaranteed that the pool will be grown to the new |
120 | * size immediately, but new mempool_free() calls will refill it. | 119 | * size immediately, but new mempool_free() calls will refill it. |
120 | * This function may sleep. | ||
121 | * | 121 | * |
122 | * Note, the caller must guarantee that no mempool_destroy is called | 122 | * Note, the caller must guarantee that no mempool_destroy is called |
123 | * while this function is running. mempool_alloc() & mempool_free() | 123 | * while this function is running. mempool_alloc() & mempool_free() |
124 | * might be called (eg. from IRQ contexts) while this function executes. | 124 | * might be called (eg. from IRQ contexts) while this function executes. |
125 | */ | 125 | */ |
126 | int mempool_resize(mempool_t *pool, int new_min_nr, gfp_t gfp_mask) | 126 | int mempool_resize(mempool_t *pool, int new_min_nr) |
127 | { | 127 | { |
128 | void *element; | 128 | void *element; |
129 | void **new_elements; | 129 | void **new_elements; |
130 | unsigned long flags; | 130 | unsigned long flags; |
131 | 131 | ||
132 | BUG_ON(new_min_nr <= 0); | 132 | BUG_ON(new_min_nr <= 0); |
133 | might_sleep(); | ||
133 | 134 | ||
134 | spin_lock_irqsave(&pool->lock, flags); | 135 | spin_lock_irqsave(&pool->lock, flags); |
135 | if (new_min_nr <= pool->min_nr) { | 136 | if (new_min_nr <= pool->min_nr) { |
@@ -145,7 +146,8 @@ int mempool_resize(mempool_t *pool, int new_min_nr, gfp_t gfp_mask) | |||
145 | spin_unlock_irqrestore(&pool->lock, flags); | 146 | spin_unlock_irqrestore(&pool->lock, flags); |
146 | 147 | ||
147 | /* Grow the pool */ | 148 | /* Grow the pool */ |
148 | new_elements = kmalloc(new_min_nr * sizeof(*new_elements), gfp_mask); | 149 | new_elements = kmalloc_array(new_min_nr, sizeof(*new_elements), |
150 | GFP_KERNEL); | ||
149 | if (!new_elements) | 151 | if (!new_elements) |
150 | return -ENOMEM; | 152 | return -ENOMEM; |
151 | 153 | ||
@@ -164,7 +166,7 @@ int mempool_resize(mempool_t *pool, int new_min_nr, gfp_t gfp_mask) | |||
164 | 166 | ||
165 | while (pool->curr_nr < pool->min_nr) { | 167 | while (pool->curr_nr < pool->min_nr) { |
166 | spin_unlock_irqrestore(&pool->lock, flags); | 168 | spin_unlock_irqrestore(&pool->lock, flags); |
167 | element = pool->alloc(gfp_mask, pool->pool_data); | 169 | element = pool->alloc(GFP_KERNEL, pool->pool_data); |
168 | if (!element) | 170 | if (!element) |
169 | goto out; | 171 | goto out; |
170 | spin_lock_irqsave(&pool->lock, flags); | 172 | spin_lock_irqsave(&pool->lock, flags); |