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.
Unified · Split
| @@ -295,7 +295,6 @@ extern bool libceph_compatible(void *data); · 294 unmodified lines | ||
| 295 | 295 | |
| 296 | 296 | extern const char *ceph_msg_type_name(int type); |
| 297 | 297 | extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid); |
| 298 | −extern void *ceph_kvmalloc(size_t size, gfp_t flags); | |
| 299 | 298 | |
| 300 | 299 | struct fs_parameter; |
| 301 | 300 | struct fc_log; |
| @@ -549,13 +549,10 @@ EXPORT_SYMBOL(vm_mmap); · 548 unmodified lines | ||
| 549 | 549 | * Uses kmalloc to get the memory but if the allocation fails then falls back |
| 550 | 550 | * to the vmalloc allocator. Use kvfree for freeing the memory. |
| 551 | 551 | * |
| 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. | |
| 553 | 553 | * __GFP_RETRY_MAYFAIL is supported, and it should be used only if kmalloc is |
| 554 | 554 | * preferable to the vmalloc fallback, due to visible performance drawbacks. |
| 555 | 555 | * |
| 556 | − * Please note that any use of gfp flags outside of GFP_KERNEL is careful to not | |
| 557 | − * fall back to vmalloc. | |
| 558 | − * | |
| 559 | 556 | * Return: pointer to the allocated memory of %NULL in case of failure |
| 560 | 557 | */ |
| 561 | 558 | void *kvmalloc_node(size_t size, gfp_t flags, int node) |
| @@ -563,13 +560,6 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node) · 1 unmodified line | ||
| 563 | 560 | gfp_t kmalloc_flags = flags; |
| 564 | 561 | void *ret; |
| 565 | 562 | |
| 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 | − | |
| 573 | 563 | /* |
| 574 | 564 | * We want to attempt a large physically contiguous block first because |
| 575 | 565 | * 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) · 6 unmodified lines | ||
| 582 | 572 | |
| 583 | 573 | if (!(kmalloc_flags & __GFP_RETRY_MAYFAIL)) |
| 584 | 574 | kmalloc_flags |= __GFP_NORETRY; |
| 575 | + | |
| 576 | + /* nofail semantic is implemented by the vmalloc fallback */ | |
| 577 | + kmalloc_flags &= ~__GFP_NOFAIL; | |
| 585 | 578 | } |
| 586 | 579 | |
| 587 | 580 | ret = kmalloc_node(size, kmalloc_flags, node); |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <linux/ceph/buffer.h> |
| 9 | 9 | #include <linux/ceph/decode.h> |
| 10 | −#include <linux/ceph/libceph.h> /* for ceph_kvmalloc */ | |
| 10 | +#include <linux/ceph/libceph.h> /* for kvmalloc */ | |
| 11 | 11 | |
| 12 | 12 | struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) |
| 13 | 13 | { |
| @@ -17,7 +17,7 @@ struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) · 3 unmodified lines | ||
| 17 | 17 | if (!b) |
| 18 | 18 | return NULL; |
| 19 | 19 | |
| 20 | − b->vec.iov_base = ceph_kvmalloc(len, gfp); | |
| 20 | + b->vec.iov_base = kvmalloc(len, gfp); | |
| 21 | 21 | if (!b->vec.iov_base) { |
| 22 | 22 | kfree(b); |
| 23 | 23 | return NULL; |
| @@ -190,33 +190,6 @@ int ceph_compare_options(struct ceph_options *new_opt, · 189 unmodified lines | ||
| 190 | 190 | } |
| 191 | 191 | EXPORT_SYMBOL(ceph_compare_options); |
| 192 | 192 | |
| 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 | − | |
| 220 | 193 | static int parse_fsid(const char *str, struct ceph_fsid *fsid) |
| 221 | 194 | { |
| 222 | 195 | int i = 0; |
| @@ -147,7 +147,7 @@ void ceph_crypto_key_destroy(struct ceph_crypto_key *key) · 146 unmodified lines | ||
| 147 | 147 | static const u8 *aes_iv = (u8 *)CEPH_AES_IV; |
| 148 | 148 | |
| 149 | 149 | /* |
| 150 | − * Should be used for buffers allocated with ceph_kvmalloc(). | |
| 150 | + * Should be used for buffers allocated with kvmalloc(). | |
| 151 | 151 | * Currently these are encrypt out-buffer (ceph_buffer) and decrypt |
| 152 | 152 | * in-buffer (msg front). |
| 153 | 153 | * |
| @@ -1920,7 +1920,7 @@ struct ceph_msg *ceph_msg_new2(int type, int front_len, int max_data_items, · 1919 unmodified lines | ||
| 1920 | 1920 | |
| 1921 | 1921 | /* front */ |
| 1922 | 1922 | if (front_len) { |
| 1923 | − m->front.iov_base = ceph_kvmalloc(front_len, flags); | |
| 1923 | + m->front.iov_base = kvmalloc(front_len, flags); | |
| 1924 | 1924 | if (m->front.iov_base == NULL) { |
| 1925 | 1925 | dout("ceph_msg_new can't allocate %d bytes\n", |
| 1926 | 1926 | front_len); |
| @@ -308,7 +308,7 @@ static void *alloc_conn_buf(struct ceph_connection *con, int len) · 307 unmodified lines | ||
| 308 | 308 | if (WARN_ON(con->v2.conn_buf_cnt >= ARRAY_SIZE(con->v2.conn_bufs))) |
| 309 | 309 | return NULL; |
| 310 | 310 | |
| 311 | − buf = ceph_kvmalloc(len, GFP_NOIO); | |
| 311 | + buf = kvmalloc(len, GFP_NOIO); | |
| 312 | 312 | if (!buf) |
| 313 | 313 | return NULL; |
| 314 | 314 | |
| @@ -980,7 +980,7 @@ static struct crush_work *alloc_workspace(const struct crush_map *c) · 979 unmodified lines | ||
| 980 | 980 | work_size = crush_work_size(c, CEPH_PG_MAX_SIZE); |
| 981 | 981 | dout("%s work_size %zu bytes\n", __func__, work_size); |
| 982 | 982 | |
| 983 | − work = ceph_kvmalloc(work_size, GFP_NOIO); | |
| 983 | + work = kvmalloc(work_size, GFP_NOIO); | |
| 984 | 984 | if (!work) |
| 985 | 985 | return NULL; |
| 986 | 986 | |
| @@ -1190,9 +1190,9 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, u32 max) · 203 unmodified lines | ||
| 1190 | 1190 | if (max == map->max_osd) |
| 1191 | 1191 | return 0; |
| 1192 | 1192 | |
| 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); | |
| 1196 | 1196 | if (!state || !weight || !addr) { |
| 1197 | 1197 | kvfree(state); |
| 1198 | 1198 | kvfree(weight); |
| @@ -1222,7 +1222,7 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, u32 max) · 23 unmodified lines | ||
| 1222 | 1222 | if (map->osd_primary_affinity) { |
| 1223 | 1223 | u32 *affinity; |
| 1224 | 1224 | |
| 1225 | − affinity = ceph_kvmalloc(array_size(max, sizeof(*affinity)), | |
| 1225 | + affinity = kvmalloc(array_size(max, sizeof(*affinity)), | |
| 1226 | 1226 | GFP_NOFS); |
| 1227 | 1227 | if (!affinity) |
| 1228 | 1228 | return -ENOMEM; |
| @@ -1503,7 +1503,7 @@ static int set_primary_affinity(struct ceph_osdmap *map, int osd, u32 aff) · 274 unmodified lines | ||
| 1503 | 1503 | if (!map->osd_primary_affinity) { |
| 1504 | 1504 | int i; |
| 1505 | 1505 | |
| 1506 | − map->osd_primary_affinity = ceph_kvmalloc( | |
| 1506 | + map->osd_primary_affinity = kvmalloc( | |
| 1507 | 1507 | array_size(map->max_osd, sizeof(*map->osd_primary_affinity)), |
| 1508 | 1508 | GFP_NOFS); |
| 1509 | 1509 | if (!map->osd_primary_affinity) |