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 | extern const char *ceph_msg_type_name(int type); | 296 | extern const char *ceph_msg_type_name(int type); |
| 297 | extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid); | 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 | struct fs_parameter; | 299 | struct fs_parameter; |
| 301 | struct fc_log; | 300 | struct fc_log; |
| @@ -549,13 +549,10 @@ EXPORT_SYMBOL(vm_mmap); · 548 unmodified lines | |||
| 549 | * Uses kmalloc to get the memory but if the allocation fails then falls back | 549 | * Uses kmalloc to get the memory but if the allocation fails then falls back |
| 550 | * to the vmalloc allocator. Use kvfree for freeing the memory. | 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 | * __GFP_RETRY_MAYFAIL is supported, and it should be used only if kmalloc is | 553 | * __GFP_RETRY_MAYFAIL is supported, and it should be used only if kmalloc is |
| 554 | * preferable to the vmalloc fallback, due to visible performance drawbacks. | 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 | * Return: pointer to the allocated memory of %NULL in case of failure | 556 | * Return: pointer to the allocated memory of %NULL in case of failure |
| 560 | */ | 557 | */ |
| 561 | void *kvmalloc_node(size_t size, gfp_t flags, int node) | 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 | gfp_t kmalloc_flags = flags; | 560 | gfp_t kmalloc_flags = flags; |
| 564 | void *ret; | 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 | * We want to attempt a large physically contiguous block first because | 564 | * We want to attempt a large physically contiguous block first because |
| 575 | * it is less likely to fragment multiple larger blocks and therefore | 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 | if (!(kmalloc_flags & __GFP_RETRY_MAYFAIL)) | 573 | if (!(kmalloc_flags & __GFP_RETRY_MAYFAIL)) |
| 584 | kmalloc_flags |= __GFP_NORETRY; | 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 | ret = kmalloc_node(size, kmalloc_flags, node); | 580 | ret = kmalloc_node(size, kmalloc_flags, node); |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #include <linux/ceph/buffer.h> | 8 | #include <linux/ceph/buffer.h> |
| 9 | #include <linux/ceph/decode.h> | 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 | struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) | 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 | if (!b) | 17 | if (!b) |
| 18 | return NULL; | 18 | return NULL; |
| 19 | 19 | ||
| 20 | b->vec.iov_base = ceph_kvmalloc(len, gfp); | 20 | b->vec.iov_base = kvmalloc(len, gfp); |
| 21 | if (!b->vec.iov_base) { | 21 | if (!b->vec.iov_base) { |
| 22 | kfree(b); | 22 | kfree(b); |
| 23 | return NULL; | 23 | return NULL; |
| @@ -190,33 +190,6 @@ int ceph_compare_options(struct ceph_options *new_opt, · 189 unmodified lines | |||
| 190 | } | 190 | } |
| 191 | EXPORT_SYMBOL(ceph_compare_options); | 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 | static int parse_fsid(const char *str, struct ceph_fsid *fsid) | 193 | static int parse_fsid(const char *str, struct ceph_fsid *fsid) |
| 221 | { | 194 | { |
| 222 | int i = 0; | 195 | int i = 0; |
| @@ -147,7 +147,7 @@ void ceph_crypto_key_destroy(struct ceph_crypto_key *key) · 146 unmodified lines | |||
| 147 | static const u8 *aes_iv = (u8 *)CEPH_AES_IV; | 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 | * Currently these are encrypt out-buffer (ceph_buffer) and decrypt | 151 | * Currently these are encrypt out-buffer (ceph_buffer) and decrypt |
| 152 | * in-buffer (msg front). | 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 | /* front */ | 1921 | /* front */ |
| 1922 | if (front_len) { | 1922 | if (front_len) { |
| 1923 | m->front.iov_base = ceph_kvmalloc(front_len, flags); | 1923 | m->front.iov_base = kvmalloc(front_len, flags); |
| 1924 | if (m->front.iov_base == NULL) { | 1924 | if (m->front.iov_base == NULL) { |
| 1925 | dout("ceph_msg_new can't allocate %d bytes\n", | 1925 | dout("ceph_msg_new can't allocate %d bytes\n", |
| 1926 | front_len); | 1926 | front_len); |
| @@ -308,7 +308,7 @@ static void *alloc_conn_buf(struct ceph_connection *con, int len) · 307 unmodified lines | |||
| 308 | if (WARN_ON(con->v2.conn_buf_cnt >= ARRAY_SIZE(con->v2.conn_bufs))) | 308 | if (WARN_ON(con->v2.conn_buf_cnt >= ARRAY_SIZE(con->v2.conn_bufs))) |
| 309 | return NULL; | 309 | return NULL; |
| 310 | 310 | ||
| 311 | buf = ceph_kvmalloc(len, GFP_NOIO); | 311 | buf = kvmalloc(len, GFP_NOIO); |
| 312 | if (!buf) | 312 | if (!buf) |
| 313 | return NULL; | 313 | return NULL; |
| 314 | 314 | ||
| @@ -980,7 +980,7 @@ static struct crush_work *alloc_workspace(const struct crush_map *c) · 979 unmodified lines | |||
| 980 | work_size = crush_work_size(c, CEPH_PG_MAX_SIZE); | 980 | work_size = crush_work_size(c, CEPH_PG_MAX_SIZE); |
| 981 | dout("%s work_size %zu bytes\n", __func__, work_size); | 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 | if (!work) | 984 | if (!work) |
| 985 | return NULL; | 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 | if (max == map->max_osd) | 1190 | if (max == map->max_osd) |
| 1191 | return 0; | 1191 | return 0; |
| 1192 | 1192 | ||
| 1193 | state = ceph_kvmalloc(array_size(max, sizeof(*state)), GFP_NOFS); | 1193 | state = kvmalloc(array_size(max, sizeof(*state)), GFP_NOFS); |
| 1194 | weight = ceph_kvmalloc(array_size(max, sizeof(*weight)), GFP_NOFS); | 1194 | weight = kvmalloc(array_size(max, sizeof(*weight)), GFP_NOFS); |
| 1195 | addr = ceph_kvmalloc(array_size(max, sizeof(*addr)), GFP_NOFS); | 1195 | addr = kvmalloc(array_size(max, sizeof(*addr)), GFP_NOFS); |
| 1196 | if (!state || !weight || !addr) { | 1196 | if (!state || !weight || !addr) { |
| 1197 | kvfree(state); | 1197 | kvfree(state); |
| 1198 | kvfree(weight); | 1198 | kvfree(weight); |
| @@ -1222,7 +1222,7 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, u32 max) · 23 unmodified lines | |||
| 1222 | if (map->osd_primary_affinity) { | 1222 | if (map->osd_primary_affinity) { |
| 1223 | u32 *affinity; | 1223 | u32 *affinity; |
| 1224 | 1224 | ||
| 1225 | affinity = ceph_kvmalloc(array_size(max, sizeof(*affinity)), | 1225 | affinity = kvmalloc(array_size(max, sizeof(*affinity)), |
| 1226 | GFP_NOFS); | 1226 | GFP_NOFS); |
| 1227 | if (!affinity) | 1227 | if (!affinity) |
| 1228 | return -ENOMEM; | 1228 | return -ENOMEM; |
| @@ -1503,7 +1503,7 @@ static int set_primary_affinity(struct ceph_osdmap *map, int osd, u32 aff) · 274 unmodified lines | |||
| 1503 | if (!map->osd_primary_affinity) { | 1503 | if (!map->osd_primary_affinity) { |
| 1504 | int i; | 1504 | int i; |
| 1505 | 1505 | ||
| 1506 | map->osd_primary_affinity = ceph_kvmalloc( | 1506 | map->osd_primary_affinity = kvmalloc( |
| 1507 | array_size(map->max_osd, sizeof(*map->osd_primary_affinity)), | 1507 | array_size(map->max_osd, sizeof(*map->osd_primary_affinity)), |
| 1508 | GFP_NOFS); | 1508 | GFP_NOFS); |
| 1509 | if (!map->osd_primary_affinity) | 1509 | if (!map->osd_primary_affinity) |