Skip to content

Commit a421ef3

Browse files
Michal Hockotorvalds
authored andcommitted
mm: allow !GFP_KERNEL allocations for kvmalloc
Support for GFP_NO{FS,IO} and __GFP_NOFAIL has been implemented by previous patches so we can allow the support for kvmalloc. This will allow some external users to simplify or completely remove their helpers. GFP_NOWAIT semantic hasn't been supported so far but it hasn't been explicitly documented so let's add a note about that. ceph_kvmalloc is the first helper to be dropped and changed to kvmalloc. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Michal Hocko <[email protected]> Reviewed-by: Uladzislau Rezki (Sony) <[email protected]> Acked-by: Vlastimil Babka <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Dave Chinner <[email protected]> Cc: Ilya Dryomov <[email protected]> Cc: Jeff Layton <[email protected]> Cc: Neil Brown <[email protected]> Cc: Sebastian Andrzej Siewior <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 30d3f01 commit a421ef3

File tree

8 files changed

+15
-50
lines changed

8 files changed

+15
-50
lines changed

include/linux/ceph/libceph.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ extern bool libceph_compatible(void *data);
295295

296296
extern const char *ceph_msg_type_name(int type);
297297
extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
298-
extern void *ceph_kvmalloc(size_t size, gfp_t flags);
299298

300299
struct fs_parameter;
301300
struct fc_log;

mm/util.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -549,27 +549,17 @@ EXPORT_SYMBOL(vm_mmap);
549549
* Uses kmalloc to get the memory but if the allocation fails then falls back
550550
* to the vmalloc allocator. Use kvfree for freeing the memory.
551551
*
552-
* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported.
552+
* GFP_NOWAIT and GFP_ATOMIC are not supported, neither is the __GFP_NORETRY modifier.
553553
* __GFP_RETRY_MAYFAIL is supported, and it should be used only if kmalloc is
554554
* preferable to the vmalloc fallback, due to visible performance drawbacks.
555555
*
556-
* Please note that any use of gfp flags outside of GFP_KERNEL is careful to not
557-
* fall back to vmalloc.
558-
*
559556
* Return: pointer to the allocated memory of %NULL in case of failure
560557
*/
561558
void *kvmalloc_node(size_t size, gfp_t flags, int node)
562559
{
563560
gfp_t kmalloc_flags = flags;
564561
void *ret;
565562

566-
/*
567-
* vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables)
568-
* so the given set of flags has to be compatible.
569-
*/
570-
if ((flags & GFP_KERNEL) != GFP_KERNEL)
571-
return kmalloc_node(size, flags, node);
572-
573563
/*
574564
* We want to attempt a large physically contiguous block first because
575565
* it is less likely to fragment multiple larger blocks and therefore
@@ -582,6 +572,9 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
582572

583573
if (!(kmalloc_flags & __GFP_RETRY_MAYFAIL))
584574
kmalloc_flags |= __GFP_NORETRY;
575+
576+
/* nofail semantic is implemented by the vmalloc fallback */
577+
kmalloc_flags &= ~__GFP_NOFAIL;
585578
}
586579

587580
ret = kmalloc_node(size, kmalloc_flags, node);

net/ceph/buffer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include <linux/ceph/buffer.h>
99
#include <linux/ceph/decode.h>
10-
#include <linux/ceph/libceph.h> /* for ceph_kvmalloc */
10+
#include <linux/ceph/libceph.h> /* for kvmalloc */
1111

1212
struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp)
1313
{
@@ -17,7 +17,7 @@ struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp)
1717
if (!b)
1818
return NULL;
1919

20-
b->vec.iov_base = ceph_kvmalloc(len, gfp);
20+
b->vec.iov_base = kvmalloc(len, gfp);
2121
if (!b->vec.iov_base) {
2222
kfree(b);
2323
return NULL;

net/ceph/ceph_common.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -190,33 +190,6 @@ int ceph_compare_options(struct ceph_options *new_opt,
190190
}
191191
EXPORT_SYMBOL(ceph_compare_options);
192192

193-
/*
194-
* kvmalloc() doesn't fall back to the vmalloc allocator unless flags are
195-
* compatible with (a superset of) GFP_KERNEL. This is because while the
196-
* actual pages are allocated with the specified flags, the page table pages
197-
* are always allocated with GFP_KERNEL.
198-
*
199-
* ceph_kvmalloc() may be called with GFP_KERNEL, GFP_NOFS or GFP_NOIO.
200-
*/
201-
void *ceph_kvmalloc(size_t size, gfp_t flags)
202-
{
203-
void *p;
204-
205-
if ((flags & (__GFP_IO | __GFP_FS)) == (__GFP_IO | __GFP_FS)) {
206-
p = kvmalloc(size, flags);
207-
} else if ((flags & (__GFP_IO | __GFP_FS)) == __GFP_IO) {
208-
unsigned int nofs_flag = memalloc_nofs_save();
209-
p = kvmalloc(size, GFP_KERNEL);
210-
memalloc_nofs_restore(nofs_flag);
211-
} else {
212-
unsigned int noio_flag = memalloc_noio_save();
213-
p = kvmalloc(size, GFP_KERNEL);
214-
memalloc_noio_restore(noio_flag);
215-
}
216-
217-
return p;
218-
}
219-
220193
static int parse_fsid(const char *str, struct ceph_fsid *fsid)
221194
{
222195
int i = 0;

net/ceph/crypto.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
147147
static const u8 *aes_iv = (u8 *)CEPH_AES_IV;
148148

149149
/*
150-
* Should be used for buffers allocated with ceph_kvmalloc().
150+
* Should be used for buffers allocated with kvmalloc().
151151
* Currently these are encrypt out-buffer (ceph_buffer) and decrypt
152152
* in-buffer (msg front).
153153
*

net/ceph/messenger.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1920,7 +1920,7 @@ struct ceph_msg *ceph_msg_new2(int type, int front_len, int max_data_items,
19201920

19211921
/* front */
19221922
if (front_len) {
1923-
m->front.iov_base = ceph_kvmalloc(front_len, flags);
1923+
m->front.iov_base = kvmalloc(front_len, flags);
19241924
if (m->front.iov_base == NULL) {
19251925
dout("ceph_msg_new can't allocate %d bytes\n",
19261926
front_len);

net/ceph/messenger_v2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ static void *alloc_conn_buf(struct ceph_connection *con, int len)
308308
if (WARN_ON(con->v2.conn_buf_cnt >= ARRAY_SIZE(con->v2.conn_bufs)))
309309
return NULL;
310310

311-
buf = ceph_kvmalloc(len, GFP_NOIO);
311+
buf = kvmalloc(len, GFP_NOIO);
312312
if (!buf)
313313
return NULL;
314314

net/ceph/osdmap.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ static struct crush_work *alloc_workspace(const struct crush_map *c)
980980
work_size = crush_work_size(c, CEPH_PG_MAX_SIZE);
981981
dout("%s work_size %zu bytes\n", __func__, work_size);
982982

983-
work = ceph_kvmalloc(work_size, GFP_NOIO);
983+
work = kvmalloc(work_size, GFP_NOIO);
984984
if (!work)
985985
return NULL;
986986

@@ -1190,9 +1190,9 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, u32 max)
11901190
if (max == map->max_osd)
11911191
return 0;
11921192

1193-
state = ceph_kvmalloc(array_size(max, sizeof(*state)), GFP_NOFS);
1194-
weight = ceph_kvmalloc(array_size(max, sizeof(*weight)), GFP_NOFS);
1195-
addr = ceph_kvmalloc(array_size(max, sizeof(*addr)), GFP_NOFS);
1193+
state = kvmalloc(array_size(max, sizeof(*state)), GFP_NOFS);
1194+
weight = kvmalloc(array_size(max, sizeof(*weight)), GFP_NOFS);
1195+
addr = kvmalloc(array_size(max, sizeof(*addr)), GFP_NOFS);
11961196
if (!state || !weight || !addr) {
11971197
kvfree(state);
11981198
kvfree(weight);
@@ -1222,7 +1222,7 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, u32 max)
12221222
if (map->osd_primary_affinity) {
12231223
u32 *affinity;
12241224

1225-
affinity = ceph_kvmalloc(array_size(max, sizeof(*affinity)),
1225+
affinity = kvmalloc(array_size(max, sizeof(*affinity)),
12261226
GFP_NOFS);
12271227
if (!affinity)
12281228
return -ENOMEM;
@@ -1503,7 +1503,7 @@ static int set_primary_affinity(struct ceph_osdmap *map, int osd, u32 aff)
15031503
if (!map->osd_primary_affinity) {
15041504
int i;
15051505

1506-
map->osd_primary_affinity = ceph_kvmalloc(
1506+
map->osd_primary_affinity = kvmalloc(
15071507
array_size(map->max_osd, sizeof(*map->osd_primary_affinity)),
15081508
GFP_NOFS);
15091509
if (!map->osd_primary_affinity)

0 commit comments

Comments
 (0)