kvmalloc
Subsystems (49)
v3 cover kvmalloc
Hi,
this has been previously posted as a single patch [1] but later on more built on top. It turned out that there are users who would like to have __GFP_REPEAT semantic. This is currently implemented for costly >64B requests. Doing the same for smaller requests would require to redefine __GFP_REPEAT semantic in the page allocator which is out of scope of this series.
There are many open coded kmalloc with vmalloc fallback instances in the tree. Most of them are not careful enough or simply do not care about the underlying semantic of the kmalloc/page allocator which means that a) some vmalloc fallbacks are basically unreachable because the kmalloc part will keep retrying until it succeeds b) the page allocator can invoke a really disruptive steps like the OOM killer to move forward which doesn't sound appropriate when we consider that the vmalloc fallback is available.
As it can be seen implementing kvmalloc requires quite an intimate knowledge if the page allocator and the memory reclaim internals which strongly suggests that a helper should be implemented in the memory subsystem proper.
Most callers I could find have been converted to use the helper instead. This is patch 5. There are some more relying on __GFP_REPEAT in the networking stack which I have converted as well but considering we do not have a support for __GFP_REPEAT for requests smaller than 64kB I have marked it RFC.
[1] http://lkml.kernel.org/r/[email protected]
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v3 1/6 mm: introduce kv[mz]alloc helpers
From: Michal Hocko <[email protected]>
Using kmalloc with the vmalloc fallback for larger allocations is a common pattern in the kernel code. Yet we do not have any common helper for that and so users have invented their own helpers. Some of them are really creative when doing so. Let's just add kv[mz]alloc and make sure it is implemented properly. This implementation makes sure to not make a large memory pressure for > PAGE_SZE requests (__GFP_NORETRY) and also to not warn about allocation failures. This also rules out the OOM killer as the vmalloc is a more approapriate fallback than a disruptive user visible action.
This patch also changes some existing users and removes helpers which are specific for them. In some cases this is not possible (e.g. ext4_kvmalloc, libcfs_kvzalloc, __aa_kvmalloc) because those seems to be broken and require GFP_NO{FS,IO} context which is not vmalloc compatible in general (note that the page table allocation is GFP_KERNEL). Those need to be fixed separately.
apparmor has already claimed kv[mz]alloc so remove those and use __aa_kvmalloc instead to prevent from the naming clashes.
Changes since v3
- add ipc_alloc
Changes since v2
- s@WARN_ON@WARN_ON_ONCE@ as per Vlastimil
- do not fallback to vmalloc for size = PAGE_SIZE as per Vlastimil
Changes since v1
- define __vmalloc_node_flags for CONFIG_MMU=n
--- arch/x86/kvm/lapic.c | 4 ++-- arch/x86/kvm/page_track.c | 4 ++-- arch/x86/kvm/x86.c | 4 ++-- drivers/md/dm-stats.c | 7 +----- fs/ext4/mballoc.c | 2 +- fs/ext4/super.c | 4 ++-- fs/f2fs/f2fs.h | 20 ----------------- fs/f2fs/file.c | 4 ++-- fs/f2fs/segment.c | 14 ++++++------ fs/seq_file.c | 16 +------------- include/linux/kvm_host.h | 2 -- include/linux/mm.h | 14 ++++++++++++ include/linux/vmalloc.h | 1 + ipc/util.c | 7 +----- mm/nommu.c | 5 +++++ mm/util.c | 42 ++++++++++++++++++++++++++++++++++++ mm/vmalloc.c | 2 +- security/apparmor/apparmorfs.c | 2 +- security/apparmor/include/apparmor.h | 10 --------- security/apparmor/match.c | 2 +- virt/kvm/kvm_main.c | 18 +++------------- 21 files changed, 89 insertions(+), 95 deletions(-)
arch/x86/kvm/lapic.c +2 -2
@@ -167,8 +167,8 @@ static void recalculate_apic_map(struct kvm *kvm)if (kvm_apic_present (vcpu)) max_id =max (max_id,kvm_apic_id (vcpu->arch.apic)); - new =kvm_kvzalloc (sizeof (struct kvm_apic_map ) + -sizeof (struct kvm_lapic *) * ((u64 )max_id +1 )); + new =kvzalloc (sizeof (struct kvm_apic_map ) + +sizeof (struct kvm_lapic *) * ((u64 )max_id +1 ),GFP_KERNEL );if (!new) goto out;
arch/x86/kvm/page_track.c +2 -2
@@ -38,8 +38,8 @@ int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,int i;for (i =0 ; i <KVM_PAGE_TRACK_MAX ; i++) { - slot->arch.gfn_track[i] =kvm_kvzalloc (npages * -sizeof (*slot->arch.gfn_track[i])); + slot->arch.gfn_track[i] =kvzalloc (npages * +sizeof (*slot->arch.gfn_track[i]),GFP_KERNEL );if (!slot->arch.gfn_track[i]) goto track_free; }
arch/x86/kvm/x86.c +2 -2
@@ -8082,13 +8082,13 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, slot->base_gfn, level) + 1; slot->arch.rmap[i] = -kvm_kvzalloc (lpages *sizeof (*slot->arch.rmap[i])); +kvzalloc (lpages *sizeof (*slot->arch.rmap[i]),GFP_KERNEL );if (!slot->arch.rmap[i]) goto out_free;if (i ==0 )continue ; - linfo =kvm_kvzalloc (lpages *sizeof (*linfo)); + linfo =kvzalloc (lpages *sizeof (*linfo),GFP_KERNEL );if (!linfo) goto out_free;
drivers/md/dm-stats.c +1 -6
@@ -146,12 +146,7 @@ static void *dm_kvzalloc(size_t alloc_size, int node)if (!claim_shared_memory (alloc_size))return NULL ; -if (alloc_size <=KMALLOC_MAX_SIZE ) { - p =kzalloc_node (alloc_size,GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN, node); -if (p) -return p; - } - p =vzalloc_node (alloc_size, node); + p =kvzalloc_node (alloc_size,GFP_KERNEL | __GFP_NOMEMALLOC, node);if (p)return p;
fs/ext4/mballoc.c +1 -1
@@ -2381,7 +2381,7 @@ int ext4_mb_alloc_groupinfo(struct super_block *sb, ext4_group_t ngroups)return 0 ; size =roundup_pow_of_two (sizeof (*sbi->s_group_info) * size); - new_groupinfo =ext4_kvzalloc (size,GFP_KERNEL ); + new_groupinfo =kvzalloc (size,GFP_KERNEL );if (!new_groupinfo) {ext4_msg (sb,KERN_ERR ,"can't allocate buddy meta group" );return -ENOMEM ;
fs/ext4/super.c +2 -2
@@ -2116,7 +2116,7 @@ int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup)return 0 ; size =roundup_pow_of_two (size *sizeof (struct flex_groups )); - new_groups =ext4_kvzalloc (size,GFP_KERNEL ); + new_groups =kvzalloc (size,GFP_KERNEL );if (!new_groups) {ext4_msg (sb,KERN_ERR ,"not enough memory for %d flex groups" , size / (int )sizeof (struct flex_groups ));
@@ -3850,7 +3850,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount; } } - sbi->s_group_desc =ext4_kvmalloc (db_count * + sbi->s_group_desc =kvmalloc (db_count *sizeof (struct buffer_head *),GFP_KERNEL );if (sbi->s_group_desc ==NULL ) {
fs/f2fs/f2fs.h +0 -20
@@ -1929,26 +1929,6 @@ static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi,return kmalloc (size, flags); } -static inline void *f2fs_kvmalloc (size_t size,gfp_t flags) -{ -void *ret; - - ret =kmalloc (size, flags | __GFP_NOWARN); -if (!ret) - ret =__vmalloc (size, flags,PAGE_KERNEL ); -return ret; -} - -static inline void *f2fs_kvzalloc (size_t size,gfp_t flags) -{ -void *ret; - - ret =kzalloc (size, flags | __GFP_NOWARN); -if (!ret) - ret =__vmalloc (size, flags | __GFP_ZERO,PAGE_KERNEL ); -return ret; -} -#define get_inode_mode (i) \ ((is_inode_flag_set(i, FI_ACL_MODE)) ? \ (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
fs/f2fs/file.c +2 -2
@@ -1013,11 +1013,11 @@ static int __exchange_data_block(struct inode *src_inode,while (len) { olen =min ((pgoff_t )4 *ADDRS_PER_BLOCK , len); - src_blkaddr =f2fs_kvzalloc (sizeof (block_t) * olen,GFP_KERNEL ); + src_blkaddr =kvzalloc (sizeof (block_t) * olen,GFP_KERNEL );if (!src_blkaddr)return -ENOMEM ; - do_replace =f2fs_kvzalloc (sizeof (int ) * olen,GFP_KERNEL ); + do_replace =kvzalloc (sizeof (int ) * olen,GFP_KERNEL );if (!do_replace) {kvfree (src_blkaddr);return -ENOMEM ;
fs/f2fs/segment.c +7 -7
@@ -2286,13 +2286,13 @@ static int build_sit_info(struct f2fs_sb_info *sbi)SM_I (sbi)->sit_info = sit_i; - sit_i->sentries =f2fs_kvzalloc (MAIN_SEGS (sbi) * + sit_i->sentries =kvzalloc (MAIN_SEGS (sbi) *sizeof (struct seg_entry ),GFP_KERNEL );if (!sit_i->sentries)return -ENOMEM ; bitmap_size =f2fs_bitmap_size (MAIN_SEGS (sbi)); - sit_i->dirty_sentries_bitmap =f2fs_kvzalloc (bitmap_size,GFP_KERNEL ); + sit_i->dirty_sentries_bitmap =kvzalloc (bitmap_size,GFP_KERNEL );if (!sit_i->dirty_sentries_bitmap)return -ENOMEM ;
@@ -2318,7 +2318,7 @@ static int build_sit_info(struct f2fs_sb_info *sbi)return -ENOMEM ;if (sbi->segs_per_sec >1 ) { - sit_i->sec_entries =f2fs_kvzalloc (MAIN_SECS (sbi) * + sit_i->sec_entries =kvzalloc (MAIN_SECS (sbi) *sizeof (struct sec_entry ),GFP_KERNEL );if (!sit_i->sec_entries)return -ENOMEM ;
@@ -2364,12 +2364,12 @@ static int build_free_segmap(struct f2fs_sb_info *sbi)SM_I (sbi)->free_info = free_i; bitmap_size =f2fs_bitmap_size (MAIN_SEGS (sbi)); - free_i->free_segmap =f2fs_kvmalloc (bitmap_size,GFP_KERNEL ); + free_i->free_segmap =kvmalloc (bitmap_size,GFP_KERNEL );if (!free_i->free_segmap)return -ENOMEM ; sec_bitmap_size =f2fs_bitmap_size (MAIN_SECS (sbi)); - free_i->free_secmap =f2fs_kvmalloc (sec_bitmap_size,GFP_KERNEL ); + free_i->free_secmap =kvmalloc (sec_bitmap_size,GFP_KERNEL );if (!free_i->free_secmap)return -ENOMEM ;
@@ -2537,7 +2537,7 @@ static int init_victim_secmap(struct f2fs_sb_info *sbi)struct dirty_seglist_info *dirty_i =DIRTY_I (sbi);unsigned int bitmap_size =f2fs_bitmap_size (MAIN_SECS (sbi)); - dirty_i->victim_secmap =f2fs_kvzalloc (bitmap_size,GFP_KERNEL ); + dirty_i->victim_secmap =kvzalloc (bitmap_size,GFP_KERNEL );if (!dirty_i->victim_secmap)return -ENOMEM ;return 0 ;
@@ -2559,7 +2559,7 @@ static int build_dirty_segmap(struct f2fs_sb_info *sbi) bitmap_size =f2fs_bitmap_size (MAIN_SEGS (sbi));for (i =0 ; i <NR_DIRTY_TYPE ; i++) { - dirty_i->dirty_segmap[i] =f2fs_kvzalloc (bitmap_size,GFP_KERNEL ); + dirty_i->dirty_segmap[i] =kvzalloc (bitmap_size,GFP_KERNEL );if (!dirty_i->dirty_segmap[i])return -ENOMEM ; }
fs/seq_file.c +1 -15
@@ -25,21 +25,7 @@ static void seq_set_overflow(struct seq_file *m)static void *seq_buf_alloc (unsigned long size) { -void *buf; -gfp_t gfp =GFP_KERNEL ; - -/* -* For high order allocations, use __GFP_NORETRY to avoid oom-killing - -* it's better to fall back to vmalloc() than to kill things. For small -* allocations, just use GFP_KERNEL which will oom kill, thus no need -* for vmalloc fallback. -*/ -if (size >PAGE_SIZE ) - gfp |= __GFP_NORETRY | __GFP_NOWARN; - buf =kmalloc (size, gfp); -if (!buf && size >PAGE_SIZE ) - buf =vmalloc (size); -return buf; +return kvmalloc (size,GFP_KERNEL ); }/**
include/linux/kvm_host.h +0 -2
@@ -768,8 +768,6 @@ void kvm_arch_check_processor_compat(void *rtn);int kvm_arch_vcpu_runnable (struct kvm_vcpu *vcpu);int kvm_arch_vcpu_should_kick (struct kvm_vcpu *vcpu); -void *kvm_kvzalloc (unsigned long size); -#ifndef __KVM_HAVE_ARCH_VM_ALLOCstatic inline struct kvm *kvm_arch_alloc_vm (void ) {
include/linux/mm.h +14 -0
@@ -484,6 +484,20 @@ static inline int is_vmalloc_or_module_addr(const void *x) }#endif +extern void *kvmalloc_node (size_t size,gfp_t flags,int node); +static inline void *kvmalloc (size_t size,gfp_t flags) +{ +return kvmalloc_node (size, flags,NUMA_NO_NODE ); +} +static inline void *kvzalloc_node (size_t size,gfp_t flags,int node) +{ +return kvmalloc_node (size, flags | __GFP_ZERO, node); +} +static inline void *kvzalloc (size_t size,gfp_t flags) +{ +return kvmalloc (size, flags | __GFP_ZERO); +} +extern void kvfree (const void *addr);static inline atomic_t *compound_mapcount_ptr (struct page *page)
include/linux/vmalloc.h +1 -0
@@ -80,6 +80,7 @@ extern void *__vmalloc_node_range(unsigned long size, unsigned long align, unsigned long start, unsigned long end, gfp_t gfp_mask, pgprot_t prot, unsigned long vm_flags, int node, const void *caller); +extern void *__vmalloc_node_flags (unsigned long size,int node,gfp_t flags);extern void vfree (const void *addr);extern void vfree_atomic (const void *addr);
ipc/util.c +1 -6
@@ -403,12 +403,7 @@ void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)*/ void *ipc_alloc (int size) { -void *out; -if (size >PAGE_SIZE ) - out =vmalloc (size); -else - out =kmalloc (size,GFP_KERNEL ); -return out; +return kvmalloc (size,GFP_KERNEL ); }/**
mm/nommu.c +5 -0
@@ -236,6 +236,11 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) }EXPORT_SYMBOL (__vmalloc); +void *__vmalloc_node_flags (unsigned long size,int node,gfp_t flags) +{ +return __vmalloc (size, flags,PAGE_KERNEL ); +} +void *vmalloc_user (unsigned long size) {void *ret;
mm/util.c +42 -0
48 lines not on this page · raw message
mm/vmalloc.c +1 -1
@@ -1757,7 +1757,7 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) }EXPORT_SYMBOL (__vmalloc); -static inline void *__vmalloc_node_flags (unsigned long size, +void *__vmalloc_node_flags (unsigned long size,int node,gfp_t flags) { return __vmalloc_node(size, 1, flags, PAGE_KERNEL,
security/apparmor/apparmorfs.c +1 -1
@@ -100,7 +100,7 @@ static char *aa_simple_write_to_buffer(int op, const char __user *userbuf,return ERR_PTR (-EACCES );/* freed by caller to simple_write_to_buffer */ - data =kvmalloc (alloc_size); + data =__aa_kvmalloc (alloc_size,0 );if (data ==NULL )return ERR_PTR (-ENOMEM );
security/apparmor/include/apparmor.h +0 -10
@@ -68,16 +68,6 @@ char *aa_split_fqname(char *args, char **ns_name);void aa_info_message (const char *str);void *__aa_kvmalloc (size_t size,gfp_t flags); -static inline void *kvmalloc (size_t size) -{ -return __aa_kvmalloc (size,0 ); -} - -static inline void *kvzalloc (size_t size) -{ -return __aa_kvmalloc (size, __GFP_ZERO); -} -/* returns 0 if kref not incremented */ static inline int kref_get_not0 (struct kref *kref) {
security/apparmor/match.c +1 -1
@@ -61,7 +61,7 @@ static struct table_header *unpack_table(char *blob, size_t bsize)if (bsize < tsize) goto out; - table =kvzalloc (tsize); + table =__aa_kvmalloc (tsize, __GFP_ZERO);if (table) { table->td_id = th.td_id; table->td_flags = th.td_flags;
virt/kvm/kvm_main.c +3 -15
@@ -502,7 +502,7 @@ static struct kvm_memslots *kvm_alloc_memslots(void)int i;struct kvm_memslots *slots; - slots =kvm_kvzalloc (sizeof (struct kvm_memslots )); + slots =kvzalloc (sizeof (struct kvm_memslots ),GFP_KERNEL );if (!slots)return NULL ;
@@ -685,18 +685,6 @@ static struct kvm *kvm_create_vm(unsigned long type)return ERR_PTR (r); } -/* -* Avoid using vmalloc for a small buffer. -* Should not be used when the size is statically known. -*/ -void *kvm_kvzalloc (unsigned long size) -{ -if (size >PAGE_SIZE ) -return vzalloc (size); -else -return kzalloc (size,GFP_KERNEL ); -} -static void kvm_destroy_devices (struct kvm *kvm) {struct kvm_device *dev, *tmp;
@@ -775,7 +763,7 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) {unsigned long dirty_bytes =2 *kvm_dirty_bitmap_bytes (memslot); - memslot->dirty_bitmap =kvm_kvzalloc (dirty_bytes); + memslot->dirty_bitmap =kvzalloc (dirty_bytes,GFP_KERNEL );if (!memslot->dirty_bitmap)return -ENOMEM ;
@@ -995,7 +983,7 @@ int __kvm_set_memory_region(struct kvm *kvm, goto out_free; } - slots =kvm_kvzalloc (sizeof (struct kvm_memslots )); + slots =kvzalloc (sizeof (struct kvm_memslots ),GFP_KERNEL );if (!slots) goto out_free;memcpy (slots,__kvm_memslots (kvm, as_id),sizeof (struct kvm_memslots ));
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 394 lines · Michal Hocko
From: Michal Hocko <[email protected]>
Using kmalloc with the vmalloc fallback for larger allocations is a common pattern in the kernel code. Yet we do not have any common helper for that and so users have invented their own helpers. Some of them are really creative when doing so. Let's just add kv[mz]alloc and make sure it is implemented properly. This implementation makes sure to not make a large memory pressure for >
PAGE_SZErequests (__GFP_NORETRY) and also to not warn about allocation failures. This also rules out the OOM killer as the vmalloc is a more approapriate fallback than a disruptive user visible action.This patch also changes some existing users and removes helpers which are specific for them. In some cases this is not possible (e.g.
ext4_kvmalloc,libcfs_kvzalloc,__aa_kvmalloc) because those seems to be broken and require GFP_NO{FS,IO} context which is not vmalloc compatible in general (note that the page table allocation isGFP_KERNEL). Those need to be fixed separately.apparmor has already claimed kv[mz]alloc so remove those and use
__aa_kvmallocinstead to prevent from the naming clashes.Changes since v3
- addipc_allocChanges since v2
- s@WARN_ON@WARN_ON_ONCE@ as per Vlastimil
- do not fallback to vmalloc for size =PAGE_SIZEas per VlastimilChanges since v1
- define__vmalloc_node_flagsforCONFIG_MMU=nCc Anatoly Stepanov <[email protected]>Cc Paolo Bonzini <[email protected]>Cc Mike Snitzer <[email protected]>Cc "Michael S. Tsirkin" <[email protected]>Cc "Theodore Ts'o" <[email protected]>Reviewed-by Andreas Dilger <[email protected]> # ext4 partAcked-by Vlastimil Babka <[email protected]>Signed-off-by Michal Hocko <[email protected]>--- arch/x86/kvm/lapic.c | 4 ++-- arch/x86/kvm/page_track.c | 4 ++-- arch/x86/kvm/x86.c | 4 ++-- drivers/md/dm-stats.c | 7 +----- fs/ext4/mballoc.c | 2 +- fs/ext4/super.c | 4 ++-- fs/f2fs/f2fs.h | 20 ----------------- fs/f2fs/file.c | 4 ++-- fs/f2fs/segment.c | 14 ++++++------ fs/seq_file.c | 16 +------------- include/linux/kvm_host.h | 2 -- include/linux/mm.h | 14 ++++++++++++ include/linux/vmalloc.h | 1 + ipc/util.c | 7 +----- mm/nommu.c | 5 +++++ mm/util.c | 42 ++++++++++++++++++++++++++++++++++++ mm/vmalloc.c | 2 +- security/apparmor/apparmorfs.c | 2 +- security/apparmor/include/apparmor.h | 10 --------- security/apparmor/match.c | 2 +- virt/kvm/kvm_main.c | 18 +++------------- 21 files changed, 89 insertions(+), 95 deletions(-)arch/x86/kvm/lapic.c +2
-2@@ -167,8 +167,8 @@ static void recalculate_apic_map(struct kvm *kvm)if (kvm_apic_present (vcpu)) max_id =max (max_id,kvm_apic_id (vcpu->arch.apic)); - new =kvm_kvzalloc (sizeof (struct kvm_apic_map ) + -sizeof (struct kvm_lapic *) * ((u64 )max_id +1 )); + new =kvzalloc (sizeof (struct kvm_apic_map ) + +sizeof (struct kvm_lapic *) * ((u64 )max_id +1 ),GFP_KERNEL );if (!new) goto out;arch/x86/kvm/page_track.c +2
-2@@ -38,8 +38,8 @@ int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,int i;for (i =0 ; i <KVM_PAGE_TRACK_MAX ; i++) { - slot->arch.gfn_track[i] =kvm_kvzalloc (npages * -sizeof (*slot->arch.gfn_track[i])); + slot->arch.gfn_track[i] =kvzalloc (npages * +sizeof (*slot->arch.gfn_track[i]),GFP_KERNEL );if (!slot->arch.gfn_track[i]) goto track_free; }arch/x86/kvm/x86.c +2
-2@@ -8082,13 +8082,13 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot, slot->base_gfn, level) + 1; slot->arch.rmap[i] = -kvm_kvzalloc (lpages *sizeof (*slot->arch.rmap[i])); +kvzalloc (lpages *sizeof (*slot->arch.rmap[i]),GFP_KERNEL );if (!slot->arch.rmap[i]) goto out_free;if (i ==0 )continue ; - linfo =kvm_kvzalloc (lpages *sizeof (*linfo)); + linfo =kvzalloc (lpages *sizeof (*linfo),GFP_KERNEL );if (!linfo) goto out_free;drivers/md/dm-stats.c +1
-6@@ -146,12 +146,7 @@ static void *dm_kvzalloc(size_t alloc_size, int node)if (!claim_shared_memory (alloc_size))return NULL ; -if (alloc_size <=KMALLOC_MAX_SIZE ) { - p =kzalloc_node (alloc_size,GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN, node); -if (p) -return p; - } - p =vzalloc_node (alloc_size, node); + p =kvzalloc_node (alloc_size,GFP_KERNEL | __GFP_NOMEMALLOC, node);if (p)return p;fs/ext4/mballoc.c +1
-1@@ -2381,7 +2381,7 @@ int ext4_mb_alloc_groupinfo(struct super_block *sb, ext4_group_t ngroups)return 0 ; size =roundup_pow_of_two (sizeof (*sbi->s_group_info) * size); - new_groupinfo =ext4_kvzalloc (size,GFP_KERNEL ); + new_groupinfo =kvzalloc (size,GFP_KERNEL );if (!new_groupinfo) {ext4_msg (sb,KERN_ERR ,"can't allocate buddy meta group" );return -ENOMEM ;fs/ext4/super.c +2
-2@@ -2116,7 +2116,7 @@ int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup)return 0 ; size =roundup_pow_of_two (size *sizeof (struct flex_groups )); - new_groups =ext4_kvzalloc (size,GFP_KERNEL ); + new_groups =kvzalloc (size,GFP_KERNEL );if (!new_groups) {ext4_msg (sb,KERN_ERR ,"not enough memory for %d flex groups" , size / (int )sizeof (struct flex_groups ));@@ -3850,7 +3850,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount; } } - sbi->s_group_desc =ext4_kvmalloc (db_count * + sbi->s_group_desc =kvmalloc (db_count *sizeof (struct buffer_head *),GFP_KERNEL );if (sbi->s_group_desc ==NULL ) {fs/f2fs/f2fs.h +0
-20@@ -1929,26 +1929,6 @@ static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi,return kmalloc (size, flags); } -static inline void *f2fs_kvmalloc (size_t size,gfp_t flags) -{ -void *ret; - - ret =kmalloc (size, flags | __GFP_NOWARN); -if (!ret) - ret =__vmalloc (size, flags,PAGE_KERNEL ); -return ret; -} - -static inline void *f2fs_kvzalloc (size_t size,gfp_t flags) -{ -void *ret; - - ret =kzalloc (size, flags | __GFP_NOWARN); -if (!ret) - ret =__vmalloc (size, flags | __GFP_ZERO,PAGE_KERNEL ); -return ret; -} -#define get_inode_mode (i) \ ((is_inode_flag_set(i, FI_ACL_MODE)) ? \ (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))fs/f2fs/file.c +2
-2@@ -1013,11 +1013,11 @@ static int __exchange_data_block(struct inode *src_inode,while (len) { olen =min ((pgoff_t )4 *ADDRS_PER_BLOCK , len); - src_blkaddr =f2fs_kvzalloc (sizeof (block_t) * olen,GFP_KERNEL ); + src_blkaddr =kvzalloc (sizeof (block_t) * olen,GFP_KERNEL );if (!src_blkaddr)return -ENOMEM ; - do_replace =f2fs_kvzalloc (sizeof (int ) * olen,GFP_KERNEL ); + do_replace =kvzalloc (sizeof (int ) * olen,GFP_KERNEL );if (!do_replace) {kvfree (src_blkaddr);return -ENOMEM ;fs/f2fs/segment.c +7
-7@@ -2286,13 +2286,13 @@ static int build_sit_info(struct f2fs_sb_info *sbi)SM_I (sbi)->sit_info = sit_i; - sit_i->sentries =f2fs_kvzalloc (MAIN_SEGS (sbi) * + sit_i->sentries =kvzalloc (MAIN_SEGS (sbi) *sizeof (struct seg_entry ),GFP_KERNEL );if (!sit_i->sentries)return -ENOMEM ; bitmap_size =f2fs_bitmap_size (MAIN_SEGS (sbi)); - sit_i->dirty_sentries_bitmap =f2fs_kvzalloc (bitmap_size,GFP_KERNEL ); + sit_i->dirty_sentries_bitmap =kvzalloc (bitmap_size,GFP_KERNEL );if (!sit_i->dirty_sentries_bitmap)return -ENOMEM ;@@ -2318,7 +2318,7 @@ static int build_sit_info(struct f2fs_sb_info *sbi)return -ENOMEM ;if (sbi->segs_per_sec >1 ) { - sit_i->sec_entries =f2fs_kvzalloc (MAIN_SECS (sbi) * + sit_i->sec_entries =kvzalloc (MAIN_SECS (sbi) *sizeof (struct sec_entry ),GFP_KERNEL );if (!sit_i->sec_entries)return -ENOMEM ;@@ -2364,12 +2364,12 @@ static int build_free_segmap(struct f2fs_sb_info *sbi)SM_I (sbi)->free_info = free_i; bitmap_size =f2fs_bitmap_size (MAIN_SEGS (sbi)); - free_i->free_segmap =f2fs_kvmalloc (bitmap_size,GFP_KERNEL ); + free_i->free_segmap =kvmalloc (bitmap_size,GFP_KERNEL );if (!free_i->free_segmap)return -ENOMEM ; sec_bitmap_size =f2fs_bitmap_size (MAIN_SECS (sbi)); - free_i->free_secmap =f2fs_kvmalloc (sec_bitmap_size,GFP_KERNEL ); + free_i->free_secmap =kvmalloc (sec_bitmap_size,GFP_KERNEL );if (!free_i->free_secmap)return -ENOMEM ;@@ -2537,7 +2537,7 @@ static int init_victim_secmap(struct f2fs_sb_info *sbi)struct dirty_seglist_info *dirty_i =DIRTY_I (sbi);unsigned int bitmap_size =f2fs_bitmap_size (MAIN_SECS (sbi)); - dirty_i->victim_secmap =f2fs_kvzalloc (bitmap_size,GFP_KERNEL ); + dirty_i->victim_secmap =kvzalloc (bitmap_size,GFP_KERNEL );if (!dirty_i->victim_secmap)return -ENOMEM ;return 0 ;@@ -2559,7 +2559,7 @@ static int build_dirty_segmap(struct f2fs_sb_info *sbi) bitmap_size =f2fs_bitmap_size (MAIN_SEGS (sbi));for (i =0 ; i <NR_DIRTY_TYPE ; i++) { - dirty_i->dirty_segmap[i] =f2fs_kvzalloc (bitmap_size,GFP_KERNEL ); + dirty_i->dirty_segmap[i] =kvzalloc (bitmap_size,GFP_KERNEL );if (!dirty_i->dirty_segmap[i])return -ENOMEM ; }fs/seq_file.c +1
-15@@ -25,21 +25,7 @@ static void seq_set_overflow(struct seq_file *m)static void *seq_buf_alloc (unsigned long size) { -void *buf; -gfp_t gfp =GFP_KERNEL ; - -/* -* For high order allocations, use __GFP_NORETRY to avoid oom-killing - -* it's better to fall back to vmalloc() than to kill things. For small -* allocations, just use GFP_KERNEL which will oom kill, thus no need -* for vmalloc fallback. -*/ -if (size >PAGE_SIZE ) - gfp |= __GFP_NORETRY | __GFP_NOWARN; - buf =kmalloc (size, gfp); -if (!buf && size >PAGE_SIZE ) - buf =vmalloc (size); -return buf; +return kvmalloc (size,GFP_KERNEL ); }/** include/linux/kvm_host.h +0
-2@@ -768,8 +768,6 @@ void kvm_arch_check_processor_compat(void *rtn);int kvm_arch_vcpu_runnable (struct kvm_vcpu *vcpu);int kvm_arch_vcpu_should_kick (struct kvm_vcpu *vcpu); -void *kvm_kvzalloc (unsigned long size); -#ifndef __KVM_HAVE_ARCH_VM_ALLOCstatic inline struct kvm *kvm_arch_alloc_vm (void ) {include/linux/mm.h +14
-0@@ -484,6 +484,20 @@ static inline int is_vmalloc_or_module_addr(const void *x) }#endif +extern void *kvmalloc_node (size_t size,gfp_t flags,int node); +static inline void *kvmalloc (size_t size,gfp_t flags) +{ +return kvmalloc_node (size, flags,NUMA_NO_NODE ); +} +static inline void *kvzalloc_node (size_t size,gfp_t flags,int node) +{ +return kvmalloc_node (size, flags | __GFP_ZERO, node); +} +static inline void *kvzalloc (size_t size,gfp_t flags) +{ +return kvmalloc (size, flags | __GFP_ZERO); +} +extern void kvfree (const void *addr);static inline atomic_t *compound_mapcount_ptr (struct page *page)include/linux/vmalloc.h +1
-0@@ -80,6 +80,7 @@ extern void *__vmalloc_node_range(unsigned long size, unsigned long align, unsigned long start, unsigned long end, gfp_t gfp_mask, pgprot_t prot, unsigned long vm_flags, int node, const void *caller); +extern void *__vmalloc_node_flags (unsigned long size,int node,gfp_t flags);extern void vfree (const void *addr);extern void vfree_atomic (const void *addr);ipc/util.c +1
-6@@ -403,12 +403,7 @@ void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)*/ void *ipc_alloc (int size) { -void *out; -if (size >PAGE_SIZE ) - out =vmalloc (size); -else - out =kmalloc (size,GFP_KERNEL ); -return out; +return kvmalloc (size,GFP_KERNEL ); }/** mm/nommu.c +5
-0@@ -236,6 +236,11 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) }EXPORT_SYMBOL (__vmalloc); +void *__vmalloc_node_flags (unsigned long size,int node,gfp_t flags) +{ +return __vmalloc (size, flags,PAGE_KERNEL ); +} +void *vmalloc_user (unsigned long size) {void *ret;mm/util.c +0
-0
mm/util.c unsigned long vm_mmap(struct file *file, unsigned long addr, · line 328
Quoted 5 lines
mm/util.c +2
-0@@ -324,6 +324,48 @@ unsigned long vm_mmap(struct file *file, unsigned long addr, }EXPORT_SYMBOL (vm_mmap); +/** +* kvmalloc_node - allocate contiguous memory from SLAB with vmalloc fallback
Hi Michal,
How about this wording instead:
kvmalloc_node - attempt to allocate physically contiguous memory, but upon failure, fall back to non-contiguous (vmalloc) allocation.
mm/util.c unsigned long vm_mmap(struct file *file, unsigned long addr, · line 336
Quoted 8 lines
mm/util.c +8
-0+* @size: size of the request. +* @flags: gfp mask for the allocation - must be compatible (superset) with GFP_KERNEL. +* @node: numa node to allocate from +* +* Uses kmalloc to get the memory but if the allocation fails then falls back +* to the vmalloc allocator. Use kvfree for freeing the memory. +* +* Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either kmalloc_node (possibly adding, but not removing flags), or to __vmalloc_node_flags.
b) In patch 6/6, you are in fact passing in __GFP_REPEAT to the wrappers (kvzalloc, for example), and again, only adding, not removing flags.
Quoted 10 lines
mm/util.c +10
-0+*/ +void *kvmalloc_node (size_t size,gfp_t flags,int node) +{ +gfp_t kmalloc_flags = flags; +void *ret; + +/* +* vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables) +* so the given set of flags has to be compatible. +*/
mm/util.c unsigned long vm_mmap(struct file *file, unsigned long addr, · line 356
Quoted 10 lines
mm/util.c +10
-0+WARN_ON_ONCE ((flags &GFP_KERNEL ) !=GFP_KERNEL ); + +/* +* Make sure that larger requests are not too disruptive - no OOM +* killer and no allocation failure warnings as we have a fallback +*/ +if (size >PAGE_SIZE ) + kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; + + ret =kmalloc_node (size, kmalloc_flags, node);
Along those lines (dealing with larger requests), is there any value in picking some threshold value, and going straight to vmalloc if size is greater than that threshold? It's less flexible and might even require occasional maintenance over the years, but it would save some time on *some* systems in some cases...OK, I think I just talked myself out of the whole idea. But I still want to put the question out there, because I think others may also ask it, and I'd like to hear a more experienced opinion.
(This patchset caught my eye because we have something just like it in an out-of-tree driver, so this would be nice.)
thanks,
john h
Quoted 128 lines
mm/util.c +12
-0+ +/* +* It doesn't really make sense to fallback to vmalloc for sub page +* requests +*/ +if (ret || size <=PAGE_SIZE ) +return ret; + +return __vmalloc_node_flags (size, node, flags); +} +EXPORT_SYMBOL (kvmalloc_node); +void kvfree (const void *addr) {if (is_vmalloc_addr (addr))mm/vmalloc.c +1
-1@@ -1757,7 +1757,7 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) }EXPORT_SYMBOL (__vmalloc); -static inline void *__vmalloc_node_flags (unsigned long size, +void *__vmalloc_node_flags (unsigned long size,int node,gfp_t flags) { return __vmalloc_node(size, 1, flags, PAGE_KERNEL,security/apparmor/apparmorfs.c +1
-1@@ -100,7 +100,7 @@ static char *aa_simple_write_to_buffer(int op, const char __user *userbuf,return ERR_PTR (-EACCES );/* freed by caller to simple_write_to_buffer */ - data =kvmalloc (alloc_size); + data =__aa_kvmalloc (alloc_size,0 );if (data ==NULL )return ERR_PTR (-ENOMEM );security/apparmor/include/apparmor.h +0
-10@@ -68,16 +68,6 @@ char *aa_split_fqname(char *args, char **ns_name);void aa_info_message (const char *str);void *__aa_kvmalloc (size_t size,gfp_t flags); -static inline void *kvmalloc (size_t size) -{ -return __aa_kvmalloc (size,0 ); -} - -static inline void *kvzalloc (size_t size) -{ -return __aa_kvmalloc (size, __GFP_ZERO); -} -/* returns 0 if kref not incremented */ static inline int kref_get_not0 (struct kref *kref) {security/apparmor/match.c +1
-1@@ -61,7 +61,7 @@ static struct table_header *unpack_table(char *blob, size_t bsize)if (bsize < tsize) goto out; - table =kvzalloc (tsize); + table =__aa_kvmalloc (tsize, __GFP_ZERO);if (table) { table->td_id = th.td_id; table->td_flags = th.td_flags;virt/kvm/kvm_main.c +3
-16@@ -502,7 +502,7 @@ static struct kvm_memslots *kvm_alloc_memslots(void)int i;struct kvm_memslots *slots; - slots =kvm_kvzalloc (sizeof (struct kvm_memslots )); + slots =kvzalloc (sizeof (struct kvm_memslots ),GFP_KERNEL );if (!slots)return NULL ;@@ -685,18 +685,6 @@ static struct kvm *kvm_create_vm(unsigned long type)return ERR_PTR (r); } -/* -* Avoid using vmalloc for a small buffer. -* Should not be used when the size is statically known. -*/ -void *kvm_kvzalloc (unsigned long size) -{ -if (size >PAGE_SIZE ) -return vzalloc (size); -else -return kzalloc (size,GFP_KERNEL ); -} -static void kvm_destroy_devices (struct kvm *kvm) {struct kvm_device *dev, *tmp;@@ -775,7 +763,7 @@ static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot) {unsigned long dirty_bytes =2 *kvm_dirty_bitmap_bytes (memslot); - memslot->dirty_bitmap =kvm_kvzalloc (dirty_bytes); + memslot->dirty_bitmap =kvzalloc (dirty_bytes,GFP_KERNEL );if (!memslot->dirty_bitmap)return -ENOMEM ;@@ -995,7 +983,7 @@ int __kvm_set_memory_region(struct kvm *kvm, goto out_free; } - slots =kvm_kvzalloc (sizeof (struct kvm_memslots )); + slots =kvzalloc (sizeof (struct kvm_memslots ),GFP_KERNEL );if (!slots) goto out_free;memcpy (slots,__kvm_memslots (kvm, as_id),sizeof (struct kvm_memslots )); --2.11.0
Quoted 6 lines
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 3 lines · John Hubbard
On 01/12/2017 07:37 AM, Michal Hocko wrote:
[...]
Quoted 13 lines
mm/util.c unsigned long vm_mmap(struct file *file, unsigned long addr, · line 328
Quoted 10 lines
mm/util.c +2
-0@@ -324,6 +324,48 @@ unsigned long vm_mmap(struct file *file, unsigned long addr, }EXPORT_SYMBOL (vm_mmap); +/** +* kvmalloc_node - allocate contiguous memory from SLAB with vmalloc fallback Hi Michal,
Quoted 4 lines
How about this wording instead:
kvmalloc_node- attempt to allocate physically contiguous memory, but upon failure, fall back to non-contiguous (vmalloc) allocation.
OK, why not.
Quoted 9 lines
mm/util.c unsigned long vm_mmap(struct file *file, unsigned long addr, · line 336
Quoted 8 lines
mm/util.c +8
-0+* @size: size of the request. +* @flags: gfp mask for the allocation - must be compatible (superset) with GFP_KERNEL. +* @node: numa node to allocate from +* +* Uses kmalloc to get the memory but if the allocation fails then falls back +* to the vmalloc allocator. Use kvfree for freeing the memory. +* +* Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported
Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.
The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded GFP_KERNEL allocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.
Quoted 2 lines
b) In patch 6/6, you are in fact passing in
__GFP_REPEATto the wrappers (kvzalloc, for example), and again, only adding, not removing flags.
Patch 2 adds a support for __GFP_REPEAT and updates the above line as well.
Quoted 16 lines
Quoted 16 lines
mm/util.c +16
-0+*/ +void *kvmalloc_node (size_t size,gfp_t flags,int node) +{ +gfp_t kmalloc_flags = flags; +void *ret; + +/* +* vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables) +* so the given set of flags has to be compatible. +*/ +WARN_ON_ONCE ((flags &GFP_KERNEL ) !=GFP_KERNEL ); + +/* +* Make sure that larger requests are not too disruptive - no OOM +* killer and no allocation failure warnings as we have a fallback +*/
Quoted 8 lines
mm/util.c unsigned long vm_mmap(struct file *file, unsigned long addr, · line 356
Quoted 4 lines
mm/util.c +4
-0+if (size >PAGE_SIZE ) + kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; + + ret =kmalloc_node (size, kmalloc_flags, node);Along those lines (dealing with larger requests), is there any value in picking some threshold value, and going straight to vmalloc if size is greater than that threshold?
I am not a fan of thresholds. PAGE_ALLOC_COSTLY_ORDER which is internally used by the page allocator has turned out to be a major pain. I do not want to repeat the same mistake again here. Besides that you could hard find a "one suits all" value so it would have to be a part of the API. If we ever grow users who would really like to do something like that then a specialized API should be added.
Quoted 5 lines
It's less flexible and might even require
occasional maintenance over the years, but it would save some time on *some* systems in some cases...OK, I think I just talked myself out of the whole idea. But I still want to put the question out there, because I think others may also ask it, and I'd like to hear a more experienced opinion.
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 41 lines · Michal Hocko
Quoted 3 lines · John Hubbard
On 01/12/2017 07:37 AM, Michal Hocko wrote:
[...]
Quoted 13 lines
mm/util.c unsigned long vm_mmap(struct file *file, unsigned long addr, · line 328
Quoted 10 lines
mm/util.c +2
-0@@ -324,6 +324,48 @@ unsigned long vm_mmap(struct file *file, unsigned long addr, }EXPORT_SYMBOL (vm_mmap); +/** +* kvmalloc_node - allocate contiguous memory from SLAB with vmalloc fallback Hi Michal,
Quoted 4 lines
How about this wording instead:
kvmalloc_node- attempt to allocate physically contiguous memory, but upon failure, fall back to non-contiguous (vmalloc) allocation.OK, why not.
Quoted 9 lines
mm/util.c unsigned long vm_mmap(struct file *file, unsigned long addr, · line 336
Quoted 8 lines
mm/util.c +8
-0+* @size: size of the request. +* @flags: gfp mask for the allocation - must be compatible (superset) with GFP_KERNEL. +* @node: numa node to allocate from +* +* Uses kmalloc to get the memory but if the allocation fails then falls back +* to the vmalloc allocator. Use kvfree for freeing the memory. +* +* Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.
Quoted 6 lines
The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded
GFP_KERNELallocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.
I do wonder about passing those flags through to kmalloc. Maybe it is worth stripping out __GFP_NORETRY and __GFP_NOFAIL, after all. It provides some insulation from any future changes to the implementation of kmalloc, and it also makes the documentation more believable.
Quoted 6 lines
Quoted 3 lines
b) In patch 6/6, you are in fact passing in
__GFP_REPEATto the wrappers (kvzalloc, for example), and again, only adding, not removing flags.Patch 2 adds a support for
__GFP_REPEATand updates the above line as well.
OK, I see.
Quoted 26 lines
Quoted 17 lines
Quoted 17 lines
mm/util.c +16
-0+*/ +void *kvmalloc_node (size_t size,gfp_t flags,int node) +{ +gfp_t kmalloc_flags = flags; +void *ret; + +/* +* vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables) +* so the given set of flags has to be compatible. +*/ +WARN_ON_ONCE ((flags &GFP_KERNEL ) !=GFP_KERNEL ); + +/* +* Make sure that larger requests are not too disruptive - no OOM +* killer and no allocation failure warnings as we have a fallback +*/ Quoted 8 lines
mm/util.c unsigned long vm_mmap(struct file *file, unsigned long addr, · line 356
Quoted 4 lines
mm/util.c +4
-0+if (size >PAGE_SIZE ) + kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; + + ret =kmalloc_node (size, kmalloc_flags, node);Along those lines (dealing with larger requests), is there any value in picking some threshold value, and going straight to vmalloc if size is greater than that threshold?
Quoted 6 lines
I am not a fan of thresholds.
PAGE_ALLOC_COSTLY_ORDERwhich is internally used by the page allocator has turned out to be a major pain. I do not want to repeat the same mistake again here. Besides that you could hard find a "one suits all" value so it would have to be a part of the API. If we ever grow users who would really like to do something like that then a specialized API should be added.
Thanks for explaining, and the note about the pain of dealing with PAGE_ALLOC_COSTLY_ORDER is especially interesting. Sounds good, then.
thanks
john h
Quoted 8 lines
Quoted 6 lines
It's less flexible and might even require
occasional maintenance over the years, but it would save some time on *some* systems in some cases...OK, I think I just talked myself out of the whole idea. But I still want to put the question out there, because I think others may also ask it, and I'd like to hear a more experienced opinion.
Quoted 4 lines
--
Michal Hocko
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Sun 15-01-17 20:34:13, John Hubbard wrote:
[...]
Quoted 14 lines
Quoted 7 lines
Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.Quoted 6 lines
The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded
GFP_KERNELallocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.
Quoted 4 lines
I do wonder about passing those flags through to kmalloc. Maybe it is worth stripping out
__GFP_NORETRYand__GFP_NOFAIL, after all. It provides some insulation from any future changes to the implementation of kmalloc, and it also makes the documentation more believable.
I am not really convinced that we should take an extra steps for these flags. There are no existing users for those flags and new users should follow the documentation.
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 20 lines · Michal Hocko
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Sun 15-01-17 20:34:13, John Hubbard wrote:
[...]
Quoted 14 lines
Quoted 13 lines
Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded
GFP_KERNELallocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.
Quoted 8 lines
Quoted 4 lines
I do wonder about passing those flags through to kmalloc. Maybe it is worth stripping out
__GFP_NORETRYand__GFP_NOFAIL, after all. It provides some insulation from any future changes to the implementation of kmalloc, and it also makes the documentation more believable.I am not really convinced that we should take an extra steps for these flags. There are no existing users for those flags and new users should follow the documentation.
OK, let's just fortify the documentation ever so slightly, then, so that users are more likely to do the right thing. How's this sound:
* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. (Even
* though the current implementation passes the flags on through to kmalloc and
* vmalloc, that is done for efficiency and to avoid unnecessary code. The caller
* should not pass in these flags.)
*
* __GFP_REPEAT is supported, but only for large (>64kB) allocations.
? Or is that documentation overkill?
thanks
john h
Quoted 5 lines
--
Michal Hocko
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 43 lines · John Hubbard
Quoted 20 lines · Michal Hocko
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Sun 15-01-17 20:34:13, John Hubbard wrote:
[...]
Quoted 14 lines
Quoted 13 lines
Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded
GFP_KERNELallocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.Quoted 8 lines
Quoted 4 lines
I do wonder about passing those flags through to kmalloc. Maybe it is worth stripping out
__GFP_NORETRYand__GFP_NOFAIL, after all. It provides some insulation from any future changes to the implementation of kmalloc, and it also makes the documentation more believable.I am not really convinced that we should take an extra steps for these flags. There are no existing users for those flags and new users should follow the documentation.
OK, let's just fortify the documentation ever so slightly, then, so that users are more likely to do the right thing. How's this sound:
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILare not supported. (Even
* though the current implementation passes the flags on through to kmalloc and
* vmalloc, that is done for efficiency and to avoid unnecessary code. The caller
* should not pass in these flags.)
*
*__GFP_REPEATis supported, but only for large (>64kB) allocations.
Quoted 1 line
? Or is that documentation overkill?
Dunno, it sounds like an overkill to me. It is telling more than necessary. If we want to be so vocal about gfp flags then we would have to say much more I suspect. E.g. what about __GFP_HIGHMEM? This flag is supported for vmalloc while unsupported for kmalloc. I am pretty sure there would be other gfp flags to consider and then this would grow borringly large and uninteresting to the point when people simply stop reading it. Let's just be as simple as possible.
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 46 lines · Michal Hocko
Quoted 43 lines · John Hubbard
Quoted 20 lines · Michal Hocko
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Sun 15-01-17 20:34:13, John Hubbard wrote:
[...]
Quoted 14 lines
Quoted 13 lines
Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded
GFP_KERNELallocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.Quoted 8 lines
Quoted 4 lines
I do wonder about passing those flags through to kmalloc. Maybe it is worth stripping out
__GFP_NORETRYand__GFP_NOFAIL, after all. It provides some insulation from any future changes to the implementation of kmalloc, and it also makes the documentation more believable.I am not really convinced that we should take an extra steps for these flags. There are no existing users for those flags and new users should follow the documentation.
OK, let's just fortify the documentation ever so slightly, then, so that users are more likely to do the right thing. How's this sound:
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILare not supported. (Even
* though the current implementation passes the flags on through to kmalloc and
* vmalloc, that is done for efficiency and to avoid unnecessary code. The caller
* should not pass in these flags.)
*
*__GFP_REPEATis supported, but only for large (>64kB) allocations.Quoted 1 line
? Or is that documentation overkill?
Quoted 7 lines
Dunno, it sounds like an overkill to me. It is telling more than necessary. If we want to be so vocal about gfp flags then we would have to say much more I suspect. E.g. what about
__GFP_HIGHMEM? This flag is supported for vmalloc while unsupported for kmalloc. I am pretty sure there would be other gfp flags to consider and then this would grow borringly large and uninteresting to the point when people simply stop reading it. Let's just be as simple as possible.
Agreed, on the simplicity point: simple and clear is ideal. But here, it's merely short, and not quite simple. :) People will look at that short bit of documentation, and then notice that the flags are, in fact, all passed right on through down to both kmalloc_node and __vmalloc_node_flags.
If you don't want too much documentation, then I'd be inclined to say something higher-level, about the intent, rather than mentioning those two flags directly. Because as it stands, the documentation contradicts what the code does.
Sorry to go on and on about such a minor point. I'll let it go after this last note.
Quoted 4 lines
--
Michal Hocko
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 62 lines · John Hubbard
Quoted 46 lines · Michal Hocko
Quoted 43 lines · John Hubbard
Quoted 20 lines · Michal Hocko
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Sun 15-01-17 20:34:13, John Hubbard wrote:
[...]
Quoted 14 lines
Quoted 13 lines
Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded
GFP_KERNELallocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.Quoted 8 lines
Quoted 4 lines
I do wonder about passing those flags through to kmalloc. Maybe it is worth stripping out
__GFP_NORETRYand__GFP_NOFAIL, after all. It provides some insulation from any future changes to the implementation of kmalloc, and it also makes the documentation more believable.I am not really convinced that we should take an extra steps for these flags. There are no existing users for those flags and new users should follow the documentation.
OK, let's just fortify the documentation ever so slightly, then, so that users are more likely to do the right thing. How's this sound:
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILare not supported. (Even
* though the current implementation passes the flags on through to kmalloc and
* vmalloc, that is done for efficiency and to avoid unnecessary code. The caller
* should not pass in these flags.)
*
*__GFP_REPEATis supported, but only for large (>64kB) allocations.Quoted 1 line
? Or is that documentation overkill?
Quoted 7 lines
Dunno, it sounds like an overkill to me. It is telling more than necessary. If we want to be so vocal about gfp flags then we would have to say much more I suspect. E.g. what about
__GFP_HIGHMEM? This flag is supported for vmalloc while unsupported for kmalloc. I am pretty sure there would be other gfp flags to consider and then this would grow borringly large and uninteresting to the point when people simply stop reading it. Let's just be as simple as possible.Agreed, on the simplicity point: simple and clear is ideal. But here, it's merely short, and not quite simple. :) People will look at that short bit of documentation, and then notice that the flags are, in fact, all passed right on through down to both
kmalloc_nodeand__vmalloc_node_flags.
Quoted 4 lines
If you don't want too much documentation, then I'd be inclined to say something higher-level, about the intent, rather than mentioning those two flags directly. Because as it stands, the documentation contradicts what the code does.
Feel free to suggest a better wording. I am, of course, open to any changes.
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 63 lines · Michal Hocko
Quoted 62 lines · John Hubbard
Quoted 46 lines · Michal Hocko
Quoted 43 lines · John Hubbard
Quoted 20 lines · Michal Hocko
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Sun 15-01-17 20:34:13, John Hubbard wrote:
[...]
Quoted 14 lines
Quoted 13 lines
Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded
GFP_KERNELallocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.Quoted 8 lines
Quoted 4 lines
I do wonder about passing those flags through to kmalloc. Maybe it is worth stripping out
__GFP_NORETRYand__GFP_NOFAIL, after all. It provides some insulation from any future changes to the implementation of kmalloc, and it also makes the documentation more believable.I am not really convinced that we should take an extra steps for these flags. There are no existing users for those flags and new users should follow the documentation.
OK, let's just fortify the documentation ever so slightly, then, so that users are more likely to do the right thing. How's this sound:
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILare not supported. (Even
* though the current implementation passes the flags on through to kmalloc and
* vmalloc, that is done for efficiency and to avoid unnecessary code. The caller
* should not pass in these flags.)
*
*__GFP_REPEATis supported, but only for large (>64kB) allocations.Quoted 1 line
? Or is that documentation overkill?
Quoted 7 lines
Dunno, it sounds like an overkill to me. It is telling more than necessary. If we want to be so vocal about gfp flags then we would have to say much more I suspect. E.g. what about
__GFP_HIGHMEM? This flag is supported for vmalloc while unsupported for kmalloc. I am pretty sure there would be other gfp flags to consider and then this would grow borringly large and uninteresting to the point when people simply stop reading it. Let's just be as simple as possible.Agreed, on the simplicity point: simple and clear is ideal. But here, it's merely short, and not quite simple. :) People will look at that short bit of documentation, and then notice that the flags are, in fact, all passed right on through down to both
kmalloc_nodeand__vmalloc_node_flags.
Quoted 7 lines
Quoted 4 lines
If you don't want too much documentation, then I'd be inclined to say something higher-level, about the intent, rather than mentioning those two flags directly. Because as it stands, the documentation contradicts what the code does.
Feel free to suggest a better wording. I am, of course, open to any changes.
OK, here's the best I've got, I tried to keep it concise, but (as you suspected) I'm not sure it's actually any better than the original:
* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL should not be passed in.
* Passing in __GFP_REPEAT is supported, but note that it is ignored for small
* (<=64KB) allocations, during the kmalloc attempt. __GFP_REPEAT is fully
* honored for all allocation sizes during the second part: the vmalloc attempt.
Quoted 5 lines
--
Michal Hocko
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 76 lines · John Hubbard
Quoted 63 lines · Michal Hocko
Quoted 62 lines · John Hubbard
Quoted 46 lines · Michal Hocko
Quoted 43 lines · John Hubbard
Quoted 20 lines · Michal Hocko
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Sun 15-01-17 20:34:13, John Hubbard wrote:
[...]
Quoted 14 lines
Quoted 13 lines
Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded
GFP_KERNELallocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.Quoted 8 lines
Quoted 4 lines
I do wonder about passing those flags through to kmalloc. Maybe it is worth stripping out
__GFP_NORETRYand__GFP_NOFAIL, after all. It provides some insulation from any future changes to the implementation of kmalloc, and it also makes the documentation more believable.I am not really convinced that we should take an extra steps for these flags. There are no existing users for those flags and new users should follow the documentation.
OK, let's just fortify the documentation ever so slightly, then, so that users are more likely to do the right thing. How's this sound:
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILare not supported. (Even
* though the current implementation passes the flags on through to kmalloc and
* vmalloc, that is done for efficiency and to avoid unnecessary code. The caller
* should not pass in these flags.)
*
*__GFP_REPEATis supported, but only for large (>64kB) allocations.Quoted 1 line
? Or is that documentation overkill?
Quoted 7 lines
Dunno, it sounds like an overkill to me. It is telling more than necessary. If we want to be so vocal about gfp flags then we would have to say much more I suspect. E.g. what about
__GFP_HIGHMEM? This flag is supported for vmalloc while unsupported for kmalloc. I am pretty sure there would be other gfp flags to consider and then this would grow borringly large and uninteresting to the point when people simply stop reading it. Let's just be as simple as possible.Agreed, on the simplicity point: simple and clear is ideal. But here, it's merely short, and not quite simple. :) People will look at that short bit of documentation, and then notice that the flags are, in fact, all passed right on through down to both
kmalloc_nodeand__vmalloc_node_flags.Quoted 7 lines
Quoted 4 lines
If you don't want too much documentation, then I'd be inclined to say something higher-level, about the intent, rather than mentioning those two flags directly. Because as it stands, the documentation contradicts what the code does.
Feel free to suggest a better wording. I am, of course, open to any changes.
OK, here's the best I've got, I tried to keep it concise, but (as you suspected) I'm not sure it's actually any better than the original:
Quoted 6 lines
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILshould not be passed in.
* Passing in__GFP_REPEATis supported, but note that it is ignored for small
* (<=64KB) allocations, during the kmalloc attempt.
__GFP_REPEATis fully
* honored for all allocation sizes during the second part: the vmalloc attempt.
this is not true to be really precise because vmalloc doesn't respect the given gfp mask all the way down (look at the pte initialization).
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 81 lines · Michal Hocko
Quoted 79 lines · John Hubbard
Quoted 63 lines · Michal Hocko
Quoted 62 lines · John Hubbard
Quoted 46 lines · Michal Hocko
Quoted 43 lines · John Hubbard
Quoted 20 lines · Michal Hocko
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Sun 15-01-17 20:34:13, John Hubbard wrote:
[...]
Quoted 14 lines
Quoted 13 lines
Quoted 6 lines
Is that "Reclaim modifiers" line still true, or is it a leftover from an earlier approach? I am having trouble reconciling it with rest of the patchset, because:
a) the flags argument below is effectively passed on to either
kmalloc_node(possibly adding, but not removing flags), or to__vmalloc_node_flags.The above only says thos are _unsupported_ - in other words the behavior is not defined. Even if flags are passed down to kmalloc resp. vmalloc it doesn't mean they are used that way. Remember that vmalloc uses some hardcoded
GFP_KERNELallocations. So while I could be really strict about this and mask away these flags I doubt this is worth the additional code.Quoted 8 lines
Quoted 4 lines
I do wonder about passing those flags through to kmalloc. Maybe it is worth stripping out
__GFP_NORETRYand__GFP_NOFAIL, after all. It provides some insulation from any future changes to the implementation of kmalloc, and it also makes the documentation more believable.I am not really convinced that we should take an extra steps for these flags. There are no existing users for those flags and new users should follow the documentation.
OK, let's just fortify the documentation ever so slightly, then, so that users are more likely to do the right thing. How's this sound:
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILare not supported. (Even
* though the current implementation passes the flags on through to kmalloc and
* vmalloc, that is done for efficiency and to avoid unnecessary code. The caller
* should not pass in these flags.)
*
*__GFP_REPEATis supported, but only for large (>64kB) allocations.Quoted 1 line
? Or is that documentation overkill?
Quoted 7 lines
Dunno, it sounds like an overkill to me. It is telling more than necessary. If we want to be so vocal about gfp flags then we would have to say much more I suspect. E.g. what about
__GFP_HIGHMEM? This flag is supported for vmalloc while unsupported for kmalloc. I am pretty sure there would be other gfp flags to consider and then this would grow borringly large and uninteresting to the point when people simply stop reading it. Let's just be as simple as possible.Agreed, on the simplicity point: simple and clear is ideal. But here, it's merely short, and not quite simple. :) People will look at that short bit of documentation, and then notice that the flags are, in fact, all passed right on through down to both
kmalloc_nodeand__vmalloc_node_flags.Quoted 7 lines
Quoted 4 lines
If you don't want too much documentation, then I'd be inclined to say something higher-level, about the intent, rather than mentioning those two flags directly. Because as it stands, the documentation contradicts what the code does.
Feel free to suggest a better wording. I am, of course, open to any changes.
OK, here's the best I've got, I tried to keep it concise, but (as you suspected) I'm not sure it's actually any better than the original:
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILshould not be passed in.
* Passing in__GFP_REPEATis supported, but note that it is ignored for small
* (<=64KB) allocations, during the kmalloc attempt.
Quoted 6 lines
Quoted 2 lines
__GFP_REPEATis fully
* honored for all allocation sizes during the second part: the vmalloc attempt.this is not true to be really precise because vmalloc doesn't respect the given gfp mask all the way down (look at the pte initialization).
I'm having some difficulty in locating that pte initialization part, am I on the wrong code path? Here's what I checked, before making the claim about __GFP_REPEAT being honored:
kvmalloc_node
__vmalloc_node_flags
__vmalloc_node
__vmalloc_node_range
__vmalloc_area_node
alloc_pages_node
__alloc_pages_node
__alloc_pages
__alloc_pages_nodemask
__alloc_pages_slowpath
...and __alloc_pages_slowpath does the __GFP_REPEAT handling:
/*
* Do not retry costly high order allocations unless they are
* __GFP_REPEAT
*/
if (order > PAGE_ALLOC_COSTLY_ORDER && !(gfp_mask & __GFP_REPEAT))
goto nopage;thanks,
john h
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Tue 17-01-17 21:59:13, John Hubbard wrote:
[...]
Quoted 15 lines
Quoted 10 lines
Quoted 6 lines
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILshould not be passed in.
* Passing in__GFP_REPEATis supported, but note that it is ignored for small
* (<=64KB) allocations, during the kmalloc attempt.
__GFP_REPEATis fully
* honored for all allocation sizes during the second part: the vmalloc attempt.this is not true to be really precise because vmalloc doesn't respect the given gfp mask all the way down (look at the pte initialization).
I'm having some difficulty in locating that pte initialization part, am I on the wrong code path? Here's what I checked, before making the claim about
__GFP_REPEATbeing honored:
Quoted 5 lines
kvmalloc_node
__vmalloc_node_flags
__vmalloc_node
__vmalloc_node_range
__vmalloc_area_node
map_vm_area vmap_page_range vmap_page_range_noflush vmap_pud_range pud_alloc __pud_alloc pud_alloc_one
pud will be allocated but the same pattern repeats on the pmd and pte levels. This is btw. one of the reasons why vmalloc with gfp flags is tricky!
moreover
Quoted 1 line
alloc_pages_node
this is order-0 request so...
Quoted 6 lines
__alloc_pages_node
__alloc_pages
__alloc_pages_nodemask
__alloc_pages_slowpath
Quoted 8 lines
...and
__alloc_pages_slowpathdoes the__GFP_REPEAThandling:/* * Do not retry costly high order allocations unless they are * __GFP_REPEAT */ if (order > PAGE_ALLOC_COSTLY_ORDER && !(gfp_mask & __GFP_REPEAT)) goto nopage;
... this doesn't apply
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 34 lines · Michal Hocko
Quoted 4 lines · John Hubbard
Quoted 1 line · Michal Hocko
On Tue 17-01-17 21:59:13, John Hubbard wrote:
[...]
Quoted 15 lines
Quoted 10 lines
Quoted 6 lines
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILshould not be passed in.
* Passing in__GFP_REPEATis supported, but note that it is ignored for small
* (<=64KB) allocations, during the kmalloc attempt.
__GFP_REPEATis fully
* honored for all allocation sizes during the second part: the vmalloc attempt.this is not true to be really precise because vmalloc doesn't respect the given gfp mask all the way down (look at the pte initialization).
I'm having some difficulty in locating that pte initialization part, am I on the wrong code path? Here's what I checked, before making the claim about
__GFP_REPEATbeing honored:Quoted 5 lines
kvmalloc_node
__vmalloc_node_flags
__vmalloc_node
__vmalloc_node_range
__vmalloc_area_nodemap_vm_area vmap_page_range vmap_page_range_noflush vmap_pud_range pud_alloc __pud_alloc pud_alloc_one
Quoted 3 lines
pud will be allocated but the same pattern repeats on the pmd and pte levels. This is btw. one of the reasons why vmalloc with gfp flags is tricky!
Yes, I see that now, thank you for explaining, much appreciated. The flags are left way behind in the code path.
So that leaves us with maybe this for documentation?
* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL should not be passed in.
* Passing in __GFP_REPEAT is supported, and will cause the following behavior:
* for larger (>64KB) allocations, the first part (kmalloc) will do some
* retrying, before falling back to vmalloc.
Quoted 14 lines
moreover
Quoted 1 line
alloc_pages_nodethis is order-0 request so...
Quoted 8 lines
__alloc_pages_node
__alloc_pages
__alloc_pages_nodemask
__alloc_pages_slowpath...and
__alloc_pages_slowpathdoes the__GFP_REPEAThandling:
Quoted 9 lines
Quoted 6 lines
/* * Do not retry costly high order allocations unless they are * __GFP_REPEAT */ if (order > PAGE_ALLOC_COSTLY_ORDER && !(gfp_mask & __GFP_REPEAT)) goto nopage;... this doesn't apply
yes, true.
thanks
john h
Quoted 1 line
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
On Thu 19-01-17 01:09:35, John Hubbard wrote:
[...]
Quoted 6 lines
So that leaves us with maybe this for documentation?
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILshould not be passed in.
* Passing in__GFP_REPEATis supported, and will cause the following behavior:
* for larger (>64KB) allocations, the first part (kmalloc) will do some
* retrying, before falling back to vmalloc.
I am worried this is just too vague. It doesn't really help user to decide whether "do some retrying" is what he really want's or needs.
So I would rather see the following.
"
* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT
* is supported only for large (>32kB) allocations and it should be used when using
* kmalloc is preferable because vmalloc fallback has visible performance drawbacks.
"
I would also add
"
Any use of gfp flags outside of GFP_KERNEL should be consulted with mm people. "
Does it sound any better?
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 19 lines · Michal Hocko
On Thu 19-01-17 01:09:35, John Hubbard wrote:
[...]Quoted 6 lines
So that leaves us with maybe this for documentation?
* Reclaim modifiers -
__GFP_NORETRYand__GFP_NOFAILshould not be passed in.
* Passing in__GFP_REPEATis supported, and will cause the following behavior:
* for larger (>64KB) allocations, the first part (kmalloc) will do some
* retrying, before falling back to vmalloc.I am worried this is just too vague. It doesn't really help user to decide whether "do some retrying" is what he really want's or needs.
So I would rather see the following.
"
* Reclaim modifiers -__GFP_NORETRYand__GFP_NOFAILare not supported.__GFP_REPEAT
* is supported only for large (>32kB) allocations and it should be used when using
* kmalloc is preferable because vmalloc fallback has visible performance drawbacks.
"
Quoted 6 lines
I would also add
"
Any use of gfp flags outside ofGFP_KERNELshould be consulted with mm people. "Does it sound any better?
Yes, that is good. I like that it helps guide the user. Here's some proposed optional grammar tweaks, but even without these, the above is understandable, so either way, I'm happy now:
* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT
* is supported only for large (>32kB) allocations, and it should be used only if
* kmalloc is preferable to the vmalloc fallback, due to visible performance drawbacks. *
* Please consult with mm people before using any gfp flags other than GFP_KERNEL.
thanks
john h
Quoted 10 lines
--
Michal Hocko
SUSE Labs--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
In reply to Michal HockoOn Thu 12-01-17 16:37:12, Michal Hocko wrote:
[...]
Quoted 20 lines
(quoted diff) +20
-0+void *kvmalloc_node(size_t size, gfp_t flags, int node) +{ + gfp_t kmalloc_flags = flags; + void *ret; + + /* + * vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables) + * so the given set of flags has to be compatible. + */ + WARN_ON_ONCE((flags & GFP_KERNEL) != GFP_KERNEL); + + /* + * Make sure that larger requests are not too disruptive - no OOM + * killer and no allocation failure warnings as we have a fallback + */ + if (size > PAGE_SIZE) + kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; + + ret = kmalloc_node(size, kmalloc_flags, node); +
Review
Quoted 10 lines
(quoted diff) +10
-0+ /* + * It doesn't really make sense to fallback to vmalloc for sub page + * requests + */ + if (ret || size <= PAGE_SIZE) + return ret; + + return __vmalloc_node_flags(size, node, flags); +} +EXPORT_SYMBOL(kvmalloc_node);
While discussing bpf change I've realized that the vmalloc fallback doesn't request __GFP_HIGHMEM. So I've updated the patch to do so. All the current users except for f2fs_kv[zm]alloc which just seemed to forgot or didn't know about the flag. In the next step, I would like to check whether we actually have any __vmalloc* user which would strictly refuse __GFP_HIGHMEM because I do not really see any reason for that and if there is none then I would simply pull __GFP_HIGHMEM handling into the vmalloc.
So before I resend the full series again, can I keep acks with the following?
Re: [PATCH 1/6] mm: introduce kv[mz]alloc helpers
Quoted 42 lines · Michal Hocko
On Thu 12-01-17 16:37:12, Michal Hocko wrote:
[...]Quoted 20 lines
(quoted diff) +20
-0+void *kvmalloc_node(size_t size, gfp_t flags, int node) +{ + gfp_t kmalloc_flags = flags; + void *ret; + + /* + * vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables) + * so the given set of flags has to be compatible. + */ + WARN_ON_ONCE((flags & GFP_KERNEL) != GFP_KERNEL); + + /* + * Make sure that larger requests are not too disruptive - no OOM + * killer and no allocation failure warnings as we have a fallback + */ + if (size > PAGE_SIZE) + kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; + + ret = kmalloc_node(size, kmalloc_flags, node); +Review
Quoted 10 lines
(quoted diff) +10
-0+ /* + * It doesn't really make sense to fallback to vmalloc for sub page + * requests + */ + if (ret || size <= PAGE_SIZE) + return ret; + + return __vmalloc_node_flags(size, node, flags); +} +EXPORT_SYMBOL(kvmalloc_node);While discussing bpf change I've realized that the vmalloc fallback doesn't request
__GFP_HIGHMEM. So I've updated the patch to do so. All the current users except for f2fs_kv[zm]alloc which just seemed to forgot or didn't know about the flag. In the next step, I would like to check whether we actually have any __vmalloc* user which would strictly refuse__GFP_HIGHMEMbecause I do not really see any reason for that and if there is none then I would simply pull__GFP_HIGHMEMhandling into the vmalloc.
Quoted 2 lines
So before I resend the full series again, can I keep acks with the following?
OK!
Thanks,
Vlastimil
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v3 2/6 mm: support __GFP_REPEAT in kvmalloc_node for >=64kB
In reply to Michal HockoFrom: Michal Hocko <[email protected]>
vhost code uses __GFP_REPEAT when allocating vhost_virtqueue resp. vhost_vsock because it would really like to prefer kmalloc to the vmalloc fallback - see 23cc5a991c7a ("vhost-net: extend device allocation to vmalloc") for more context. Michael Tsirkin has also noted:
"__GFP_REPEAT overhead is during allocation time. Using vmalloc means all accesses are slowed down. Allocation is not on data path, accesses are. "
The similar applies to other vhost_kvzalloc users.
Let's teach kvmalloc_node to handle __GFP_REPEAT properly. There are two things to be careful about. First we should prevent from the OOM killer and so have to involve __GFP_NORETRY by default and secondly override __GFP_REPEAT for !costly order requests as the __GFP_REPEAT is ignored for !costly orders.
Supporting __GFP_REPEAT like semantic for !costly request is possible it would require changes in the page allocator. This is out of scope of this patch.
This patch shouldn't introduce any functional change.
--- drivers/vhost/net.c | 9 +++------ drivers/vhost/vhost.c | 15 +++------------ drivers/vhost/vsock.c | 9 +++------ mm/util.c | 17 ++++++++++++++--- 4 files changed, 23 insertions(+), 27 deletions(-)
drivers/vhost/net.c +3 -6
@@ -797,12 +797,9 @@ static int vhost_net_open(struct inode *inode, struct file *f)struct vhost_virtqueue **vqs;int i; - n =kmalloc (sizeof *n,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!n) { - n =vmalloc (sizeof *n); -if (!n) -return -ENOMEM ; - } + n =kvmalloc (sizeof *n,GFP_KERNEL | __GFP_REPEAT); +if (!n) +return -ENOMEM ; vqs =kmalloc (VHOST_NET_VQ_MAX *sizeof (*vqs),GFP_KERNEL );if (!vqs) {kvfree (n);
drivers/vhost/vhost.c +3 -12
@@ -515,18 +515,9 @@ long vhost_dev_set_owner(struct vhost_dev *dev) }EXPORT_SYMBOL_GPL (vhost_dev_set_owner); -static void *vhost_kvzalloc (unsigned long size) -{ -void *n =kzalloc (size,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); - -if (!n) - n =vzalloc (size); -return n; -} -struct vhost_umem *vhost_dev_reset_owner_prepare (void ) { -return vhost_kvzalloc (sizeof (struct vhost_umem )); +return kvzalloc (sizeof (struct vhost_umem ),GFP_KERNEL ); }EXPORT_SYMBOL_GPL (vhost_dev_reset_owner_prepare);
@@ -1190,7 +1181,7 @@ EXPORT_SYMBOL_GPL(vhost_vq_access_ok);static struct vhost_umem *vhost_umem_alloc (void ) { -struct vhost_umem *umem =vhost_kvzalloc (sizeof (*umem)); +struct vhost_umem *umem =kvzalloc (sizeof (*umem),GFP_KERNEL );if (!umem)return NULL ;
@@ -1216,7 +1207,7 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)return -EOPNOTSUPP ;if (mem.nregions > max_mem_regions)return -E2BIG ; - newmem =vhost_kvzalloc (size + mem.nregions *sizeof (*m->regions)); + newmem =kvzalloc (size + mem.nregions *sizeof (*m->regions),GFP_KERNEL );if (!newmem)return -ENOMEM ;
drivers/vhost/vsock.c +3 -6
@@ -455,12 +455,9 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)/* This struct is large and allocation could fail, fall back to vmalloc * if there is no other way. */ - vsock =kzalloc (sizeof (*vsock),GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!vsock) { - vsock =vmalloc (sizeof (*vsock)); -if (!vsock) -return -ENOMEM ; - } + vsock =kvmalloc (sizeof (*vsock),GFP_KERNEL | __GFP_REPEAT); +if (!vsock) +return -ENOMEM ; vqs =kmalloc_array (ARRAY_SIZE (vsock->vqs),sizeof (*vqs),GFP_KERNEL );if (!vqs) {
mm/util.c +14 -3
@@ -333,7 +333,8 @@ EXPORT_SYMBOL(vm_mmap);* Uses kmalloc to get the memory but if the allocation fails then falls back * to the vmalloc allocator. Use kvfree for freeing the memory. * -* Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported +* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT +* is supported only for large (>64kB) allocations */ void *kvmalloc_node (size_t size,gfp_t flags,int node) {
@@ -350,8 +351,18 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)* Make sure that larger requests are not too disruptive - no OOM * killer and no allocation failure warnings as we have a fallback */ -if (size >PAGE_SIZE ) - kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; +if (size >PAGE_SIZE ) { + kmalloc_flags |= __GFP_NOWARN; + +/* +* We have to override __GFP_REPEAT by __GFP_NORETRY for !costly +* requests because there is no other way to tell the allocator +* that we want to fail rather than retry endlessly. +*/ +if (!(kmalloc_flags & __GFP_REPEAT) || + (size <=PAGE_SIZE <<PAGE_ALLOC_COSTLY_ORDER )) + kmalloc_flags |= __GFP_NORETRY; + } ret =kmalloc_node (size, kmalloc_flags, node);
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/6] mm: support __GFP_REPEAT in kvmalloc_node for >=64kB
Quoted 24 lines · Michal Hocko
From: Michal Hocko <[email protected]>
vhost code uses
__GFP_REPEATwhen allocatingvhost_virtqueueresp.vhost_vsockbecause it would really like to prefer kmalloc to the vmalloc fallback - see23cc5a991c7a("vhost-net: extend device allocation to vmalloc") for more context. Michael Tsirkin has also noted:
"__GFP_REPEAToverhead is during allocation time. Using vmalloc means all accesses are slowed down. Allocation is not on data path, accesses are. "The similar applies to other
vhost_kvzallocusers.Let's teach
kvmalloc_nodeto handle__GFP_REPEATproperly. There are two things to be careful about. First we should prevent from the OOM killer and so have to involve__GFP_NORETRYby default and secondly override__GFP_REPEATfor !costly order requests as the__GFP_REPEATis ignored for !costly orders.Supporting
__GFP_REPEATlike semantic for !costly request is possible it would require changes in the page allocator. This is out of scope of this patch.
Quoted 5 lines
This patch shouldn't introduce any functional change.
Cc "Michael S. Tsirkin" <[email protected]>Acked-by Vlastimil Babka <[email protected]>Signed-off-by Michal Hocko <[email protected]>
Quoted 126 lines
--- drivers/vhost/net.c | 9 +++------ drivers/vhost/vhost.c | 15 +++------------ drivers/vhost/vsock.c | 9 +++------ mm/util.c | 17 ++++++++++++++--- 4 files changed, 23 insertions(+), 27 deletions(-)drivers/vhost/net.c +3
-6@@ -797,12 +797,9 @@ static int vhost_net_open(struct inode *inode, struct file *f)struct vhost_virtqueue **vqs;int i; - n =kmalloc (sizeof *n,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!n) { - n =vmalloc (sizeof *n); -if (!n) -return -ENOMEM ; - } + n =kvmalloc (sizeof *n,GFP_KERNEL | __GFP_REPEAT); +if (!n) +return -ENOMEM ; vqs =kmalloc (VHOST_NET_VQ_MAX *sizeof (*vqs),GFP_KERNEL );if (!vqs) {kvfree (n);drivers/vhost/vhost.c +3
-12@@ -515,18 +515,9 @@ long vhost_dev_set_owner(struct vhost_dev *dev) }EXPORT_SYMBOL_GPL (vhost_dev_set_owner); -static void *vhost_kvzalloc (unsigned long size) -{ -void *n =kzalloc (size,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); - -if (!n) - n =vzalloc (size); -return n; -} -struct vhost_umem *vhost_dev_reset_owner_prepare (void ) { -return vhost_kvzalloc (sizeof (struct vhost_umem )); +return kvzalloc (sizeof (struct vhost_umem ),GFP_KERNEL ); }EXPORT_SYMBOL_GPL (vhost_dev_reset_owner_prepare);@@ -1190,7 +1181,7 @@ EXPORT_SYMBOL_GPL(vhost_vq_access_ok);static struct vhost_umem *vhost_umem_alloc (void ) { -struct vhost_umem *umem =vhost_kvzalloc (sizeof (*umem)); +struct vhost_umem *umem =kvzalloc (sizeof (*umem),GFP_KERNEL );if (!umem)return NULL ;@@ -1216,7 +1207,7 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)return -EOPNOTSUPP ;if (mem.nregions > max_mem_regions)return -E2BIG ; - newmem =vhost_kvzalloc (size + mem.nregions *sizeof (*m->regions)); + newmem =kvzalloc (size + mem.nregions *sizeof (*m->regions),GFP_KERNEL );if (!newmem)return -ENOMEM ;drivers/vhost/vsock.c +3
-6@@ -455,12 +455,9 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)/* This struct is large and allocation could fail, fall back to vmalloc * if there is no other way. */ - vsock =kzalloc (sizeof (*vsock),GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!vsock) { - vsock =vmalloc (sizeof (*vsock)); -if (!vsock) -return -ENOMEM ; - } + vsock =kvmalloc (sizeof (*vsock),GFP_KERNEL | __GFP_REPEAT); +if (!vsock) +return -ENOMEM ; vqs =kmalloc_array (ARRAY_SIZE (vsock->vqs),sizeof (*vqs),GFP_KERNEL );if (!vqs) {mm/util.c +14
-3@@ -333,7 +333,8 @@ EXPORT_SYMBOL(vm_mmap);* Uses kmalloc to get the memory but if the allocation fails then falls back * to the vmalloc allocator. Use kvfree for freeing the memory. * -* Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported +* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT +* is supported only for large (>64kB) allocations */ void *kvmalloc_node (size_t size,gfp_t flags,int node) {@@ -350,8 +351,18 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)* Make sure that larger requests are not too disruptive - no OOM * killer and no allocation failure warnings as we have a fallback */ -if (size >PAGE_SIZE ) - kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; +if (size >PAGE_SIZE ) { + kmalloc_flags |= __GFP_NOWARN; + +/* +* We have to override __GFP_REPEAT by __GFP_NORETRY for !costly +* requests because there is no other way to tell the allocator +* that we want to fail rather than retry endlessly. +*/ +if (!(kmalloc_flags & __GFP_REPEAT) || + (size <=PAGE_SIZE <<PAGE_ALLOC_COSTLY_ORDER )) + kmalloc_flags |= __GFP_NORETRY; + } ret =kmalloc_node (size, kmalloc_flags, node);Signature · 1 line
2.11.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/6] mm: support __GFP_REPEAT in kvmalloc_node for >=64kB
In reply to Michal HockoQuoted 5 lines · Michal Hocko
drivers/vhost/net.c +0
-0
drivers/vhost/net.c static int vhost_net_open(struct inode *inode, struct file *f) · line 800
Quoted 10 lines
drivers/vhost/net.c +1
-6@@ -797,12 +797,9 @@ static int vhost_net_open(struct inode *inode, struct file *f)struct vhost_virtqueue **vqs;int i; - n =kmalloc (sizeof *n,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!n) { - n =vmalloc (sizeof *n); -if (!n) -return -ENOMEM ; - } + n =kvmalloc (sizeof *n,GFP_KERNEL | __GFP_REPEAT);
An opportunity to standardize as sizeof(*n) like other allocations.
mm/util.c EXPORT_SYMBOL(vm_mmap); · line 337
Quoted 11 lines
mm/util.c +2
-1@@ -333,7 +333,8 @@ EXPORT_SYMBOL(vm_mmap);* Uses kmalloc to get the memory but if the allocation fails then falls back * to the vmalloc allocator. Use kvfree for freeing the memory. * -* Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported +* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT +* is supported only for large (>64kB) allocations
Isn't this ">32kB" (i.e. __GFP_REPEAT is supported for 64kB allocation) ?
Quoted 15 lines
mm/util.c +5
-2*/ void *kvmalloc_node (size_t size,gfp_t flags,int node) {@@ -350,8 +351,18 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)* Make sure that larger requests are not too disruptive - no OOM * killer and no allocation failure warnings as we have a fallback */ -if (size >PAGE_SIZE ) - kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; +if (size >PAGE_SIZE ) { + kmalloc_flags |= __GFP_NOWARN; + +/* +* We have to override __GFP_REPEAT by __GFP_NORETRY for !costly
mm/util.c void *kvmalloc_node(size_t size, gfp_t flags, int node) · line 368
Quoted 10 lines
mm/util.c +7
-0+* requests because there is no other way to tell the allocator +* that we want to fail rather than retry endlessly. +*/ +if (!(kmalloc_flags & __GFP_REPEAT) || + (size <=PAGE_SIZE <<PAGE_ALLOC_COSTLY_ORDER )) + kmalloc_flags |= __GFP_NORETRY; + } ret =kmalloc_node (size, kmalloc_flags, node);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/6] mm: support __GFP_REPEAT in kvmalloc_node for >=64kB
Quoted 1 line · Tetsuo Handa
On 2017/01/13 0:37, Michal Hocko wrote:
[...]
Quoted 5 lines
Quoted 5 lines
mm/util.c +0
-0@@ -333,7 +333,8 @@ EXPORT_SYMBOL(vm_mmap);
Quoted 8 lines
mm/util.c EXPORT_SYMBOL(vm_mmap); · line 337
Quoted 6 lines
mm/util.c +2
-1* Uses kmalloc to get the memory but if the allocation fails then falls back * to the vmalloc allocator. Use kvfree for freeing the memory. * -* Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported +* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT +* is supported only for large (>64kB) allocations Isn't this ">32kB" (i.e.
__GFP_REPEATis supported for 64kB allocation) ?
True, I will update the patch to use >32kB
Thanks!
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/6] mm: support __GFP_REPEAT in kvmalloc_node for >=64kB
In reply to Michal HockoQuoted 24 lines · Michal Hocko
From: Michal Hocko <[email protected]>
vhost code uses
__GFP_REPEATwhen allocatingvhost_virtqueueresp.vhost_vsockbecause it would really like to prefer kmalloc to the vmalloc fallback - see23cc5a991c7a("vhost-net: extend device allocation to vmalloc") for more context. Michael Tsirkin has also noted:
"__GFP_REPEAToverhead is during allocation time. Using vmalloc means all accesses are slowed down. Allocation is not on data path, accesses are. "The similar applies to other
vhost_kvzallocusers.Let's teach
kvmalloc_nodeto handle__GFP_REPEATproperly. There are two things to be careful about. First we should prevent from the OOM killer and so have to involve__GFP_NORETRYby default and secondly override__GFP_REPEATfor !costly order requests as the__GFP_REPEATis ignored for !costly orders.Supporting
__GFP_REPEATlike semantic for !costly request is possible it would require changes in the page allocator. This is out of scope of this patch.
Quoted 5 lines
This patch shouldn't introduce any functional change.
Cc "Michael S. Tsirkin" <[email protected]>Acked-by Vlastimil Babka <[email protected]>Signed-off-by Michal Hocko <[email protected]>
Assuming the new APIs are upstream I see no reason not to use them in vhost. For vhost bits:
Quoted 126 lines
--- drivers/vhost/net.c | 9 +++------ drivers/vhost/vhost.c | 15 +++------------ drivers/vhost/vsock.c | 9 +++------ mm/util.c | 17 ++++++++++++++--- 4 files changed, 23 insertions(+), 27 deletions(-)drivers/vhost/net.c +3
-6@@ -797,12 +797,9 @@ static int vhost_net_open(struct inode *inode, struct file *f)struct vhost_virtqueue **vqs;int i; - n =kmalloc (sizeof *n,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!n) { - n =vmalloc (sizeof *n); -if (!n) -return -ENOMEM ; - } + n =kvmalloc (sizeof *n,GFP_KERNEL | __GFP_REPEAT); +if (!n) +return -ENOMEM ; vqs =kmalloc (VHOST_NET_VQ_MAX *sizeof (*vqs),GFP_KERNEL );if (!vqs) {kvfree (n);drivers/vhost/vhost.c +3
-12@@ -515,18 +515,9 @@ long vhost_dev_set_owner(struct vhost_dev *dev) }EXPORT_SYMBOL_GPL (vhost_dev_set_owner); -static void *vhost_kvzalloc (unsigned long size) -{ -void *n =kzalloc (size,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); - -if (!n) - n =vzalloc (size); -return n; -} -struct vhost_umem *vhost_dev_reset_owner_prepare (void ) { -return vhost_kvzalloc (sizeof (struct vhost_umem )); +return kvzalloc (sizeof (struct vhost_umem ),GFP_KERNEL ); }EXPORT_SYMBOL_GPL (vhost_dev_reset_owner_prepare);@@ -1190,7 +1181,7 @@ EXPORT_SYMBOL_GPL(vhost_vq_access_ok);static struct vhost_umem *vhost_umem_alloc (void ) { -struct vhost_umem *umem =vhost_kvzalloc (sizeof (*umem)); +struct vhost_umem *umem =kvzalloc (sizeof (*umem),GFP_KERNEL );if (!umem)return NULL ;@@ -1216,7 +1207,7 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)return -EOPNOTSUPP ;if (mem.nregions > max_mem_regions)return -E2BIG ; - newmem =vhost_kvzalloc (size + mem.nregions *sizeof (*m->regions)); + newmem =kvzalloc (size + mem.nregions *sizeof (*m->regions),GFP_KERNEL );if (!newmem)return -ENOMEM ;drivers/vhost/vsock.c +3
-6@@ -455,12 +455,9 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)/* This struct is large and allocation could fail, fall back to vmalloc * if there is no other way. */ - vsock =kzalloc (sizeof (*vsock),GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!vsock) { - vsock =vmalloc (sizeof (*vsock)); -if (!vsock) -return -ENOMEM ; - } + vsock =kvmalloc (sizeof (*vsock),GFP_KERNEL | __GFP_REPEAT); +if (!vsock) +return -ENOMEM ; vqs =kmalloc_array (ARRAY_SIZE (vsock->vqs),sizeof (*vqs),GFP_KERNEL );if (!vqs) {mm/util.c +14
-3@@ -333,7 +333,8 @@ EXPORT_SYMBOL(vm_mmap);* Uses kmalloc to get the memory but if the allocation fails then falls back * to the vmalloc allocator. Use kvfree for freeing the memory. * -* Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported +* Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT +* is supported only for large (>64kB) allocations */ void *kvmalloc_node (size_t size,gfp_t flags,int node) {@@ -350,8 +351,18 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)* Make sure that larger requests are not too disruptive - no OOM * killer and no allocation failure warnings as we have a fallback */ -if (size >PAGE_SIZE ) - kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; +if (size >PAGE_SIZE ) { + kmalloc_flags |= __GFP_NOWARN; + +/* +* We have to override __GFP_REPEAT by __GFP_NORETRY for !costly +* requests because there is no other way to tell the allocator +* that we want to fail rather than retry endlessly. +*/ +if (!(kmalloc_flags & __GFP_REPEAT) || + (size <=PAGE_SIZE <<PAGE_ALLOC_COSTLY_ORDER )) + kmalloc_flags |= __GFP_NORETRY; + } ret =kmalloc_node (size, kmalloc_flags, node);Signature · 1 line
2.11.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v3 3/6 rhashtable: simplify a strange allocation pattern
In reply to Michal HockoFrom: Michal Hocko <[email protected]>
alloc_bucket_locks allocation pattern is quite unusual. We are preferring vmalloc when CONFIG_NUMA is enabled. The rationale is that vmalloc will respect the memory policy of the current process and so the backing memory will get distributed over multiple nodes if the requester is configured properly. At least that is the intention, in reality rhastable is shrunk and expanded from a kernel worker so no mempolicy can be assumed.
Let's just simplify the code and use kvmalloc helper, which is a transparent way to use kmalloc with vmalloc fallback, if the caller is allowed to block and use the flag otherwise.
--- lib/rhashtable.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
lib/rhashtable.c +3 -10
@@ -77,16 +77,9 @@ static int alloc_bucket_locks(struct rhashtable *ht, struct bucket_table *tbl, size = min_t(unsigned int, size, tbl->size >> 1);if (sizeof (spinlock_t) !=0 ) { - tbl->locks =NULL ; -#ifdef CONFIG_NUMA -if (size *sizeof (spinlock_t) >PAGE_SIZE && - gfp ==GFP_KERNEL ) - tbl->locks =vmalloc (size *sizeof (spinlock_t)); -#endif -if (gfp !=GFP_KERNEL ) - gfp |= __GFP_NOWARN | __GFP_NORETRY; - -if (!tbl->locks) +if (gfpflags_allow_blocking (gfp)) + tbl->locks =kvmalloc (size *sizeof (spinlock_t), gfp); +else tbl->locks =kmalloc_array (size,sizeof (spinlock_t), gfp);if (!tbl->locks)
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v3 4/6 ila: simplify a strange allocation pattern
In reply to Michal HockoFrom: Michal Hocko <[email protected]>
alloc_ila_locks seemed to c&p from alloc_bucket_locks allocation pattern which is quite unusual. The default allocation size is 320 * sizeof(spinlock_t) which is sub page unless lockdep is enabled when the performance benefit is really questionable and not worth the subtle code IMHO. Also note that the context when we call ila_init_net (modprobe or a task creating a net namespace) has to be properly configured.
Let's just simplify the code and use kvmalloc helper which is a transparent way to use kmalloc with vmalloc fallback.
--- net/ipv6/ila/ila_xlat.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
net/ipv6/ila/ila_xlat.c +1 -7
@@ -41,13 +41,7 @@ static int alloc_ila_locks(struct ila_net *ilan) size =roundup_pow_of_two (nr_pcpus *LOCKS_PER_CPU );if (sizeof (spinlock_t) !=0 ) { -#ifdef CONFIG_NUMA -if (size *sizeof (spinlock_t) >PAGE_SIZE ) - ilan->locks =vmalloc (size *sizeof (spinlock_t)); - else -#endif - ilan->locks =kmalloc_array (size,sizeof (spinlock_t), -GFP_KERNEL ); + ilan->locks =kvmalloc (size *sizeof (spinlock_t),GFP_KERNEL );if (!ilan->locks)return -ENOMEM ;for (i =0 ; i < size; i++)
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v3 5/6 treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoFrom: Michal Hocko <[email protected]>
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
--- arch/s390/kvm/kvm-s390.c | 10 ++----- crypto/lzo.c | 4 +-- drivers/acpi/apei/erst.c | 8 ++--- drivers/char/agp/generic.c | 8 +---- drivers/gpu/drm/nouveau/nouveau_gem.c | 4 +-- drivers/md/bcache/util.h | 12 ++------ drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h | 3 -- drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 25 ++-------------- drivers/net/ethernet/chelsio/cxgb3/l2t.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 31 ++++---------------- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 9 ++---- drivers/net/ethernet/mellanox/mlx4/mr.c | 9 ++---- drivers/nvdimm/dimm_devs.c | 5 +--- .../staging/lustre/lnet/libcfs/linux/linux-mem.c | 11 +------ drivers/xen/evtchn.c | 14 +-------- fs/btrfs/ctree.c | 9 ++---- fs/btrfs/ioctl.c | 9 ++---- fs/btrfs/send.c | 27 ++++++----------- fs/ceph/file.c | 9 ++---- fs/select.c | 5 +--- fs/xattr.c | 27 ++++++----------- kernel/bpf/hashtab.c | 11 ++----- lib/iov_iter.c | 5 +--- mm/frame_vector.c | 5 +--- net/ipv4/inet_hashtables.c | 6 +--- net/ipv4/tcp_metrics.c | 5 +--- net/mpls/af_mpls.c | 5 +--- net/netfilter/x_tables.c | 34 ++++++---------------- net/netfilter/xt_recent.c | 5 +--- net/sched/sch_choke.c | 5 +--- net/sched/sch_fq_codel.c | 26 ++++------------- net/sched/sch_hhf.c | 33 ++++++--------------- net/sched/sch_netem.c | 6 +--- net/sched/sch_sfq.c | 6 +--- security/keys/keyctl.c | 22 ++++---------- 35 files changed, 96 insertions(+), 319 deletions(-)
arch/s390/kvm/kvm-s390.c +2 -8
@@ -1126,10 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL );if (!keys)return -ENOMEM ;
@@ -1171,10 +1168,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (sizeof (uint8_t ) * args->count,GFP_KERNEL );if (!keys)return -ENOMEM ;
crypto/lzo.c +1 -3
@@ -32,9 +32,7 @@ static void *lzo_alloc_ctx(struct crypto_scomp *tfm) {void *ctx; - ctx =kmalloc (LZO1X_MEM_COMPRESS ,GFP_KERNEL | __GFP_NOWARN); -if (!ctx) - ctx =vmalloc (LZO1X_MEM_COMPRESS ); + ctx =kvmalloc (LZO1X_MEM_COMPRESS ,GFP_KERNEL );if (!ctx)return ERR_PTR (-ENOMEM );
drivers/acpi/apei/erst.c +2 -6
@@ -513,7 +513,7 @@ static int __erst_record_id_cache_add_one(void)if (i < erst_record_id_cache.len) goto retry;if (erst_record_id_cache.len >= erst_record_id_cache.size) { -int new_size, alloc_size; +int new_size;u64 *new_entries; new_size = erst_record_id_cache.size *2 ;
@@ -524,11 +524,7 @@ static int __erst_record_id_cache_add_one(void)pr_warn (FW_WARN "too many record IDs!\n" );return 0 ; } - alloc_size = new_size *sizeof (entries[0 ]); -if (alloc_size <PAGE_SIZE ) - new_entries =kmalloc (alloc_size,GFP_KERNEL ); -else - new_entries =vmalloc (alloc_size); + new_entries =kvmalloc (new_size *sizeof (entries[0 ]),GFP_KERNEL );if (!new_entries)return -ENOMEM ; memcpy(new_entries, entries,
drivers/char/agp/generic.c +1 -7
@@ -88,13 +88,7 @@ static int agp_get_key(void)void agp_alloc_page_array (size_t size,struct agp_memory *mem) { - mem->pages =NULL ; - -if (size <=2 *PAGE_SIZE ) - mem->pages =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (mem->pages ==NULL ) { - mem->pages =vmalloc (size); - } + mem->pages =kvmalloc (size,GFP_KERNEL ); }EXPORT_SYMBOL (agp_alloc_page_array);
drivers/gpu/drm/nouveau/nouveau_gem.c +1 -3
@@ -568,9 +568,7 @@ u_memcpya(uint64_t user, unsigned nmemb, unsigned size) size *= nmemb; - mem =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!mem) - mem =vmalloc (size); + mem =kvmalloc (size,GFP_KERNEL );if (!mem)return ERR_PTR (-ENOMEM );
drivers/md/bcache/util.h +2 -10
@@ -43,11 +43,7 @@ struct closure; (heap)->used =0 ; \ (heap)->size = (_size); \ _bytes = (heap)->size *sizeof (*(heap)->data); \ - (heap)->data =NULL ; \ -if (_bytes <KMALLOC_MAX_SIZE ) \ - (heap)->data =kmalloc (_bytes, (gfp)); \ -if ((!(heap)->data) && ((gfp) &GFP_KERNEL )) \ - (heap)->data =vmalloc (_bytes); \ + (heap)->data =kvmalloc (_bytes, (gfp) &GFP_KERNEL ); \ (heap)->data; \ })
@@ -136,12 +132,8 @@ do { \ \ (fifo)->mask = _allocated_size -1 ; \ (fifo)->front = (fifo)->back =0 ; \ - (fifo)->data =NULL ; \ \ -if (_bytes <KMALLOC_MAX_SIZE ) \ - (fifo)->data =kmalloc (_bytes, (gfp)); \ -if ((!(fifo)->data) && ((gfp) &GFP_KERNEL )) \ - (fifo)->data =vmalloc (_bytes); \ + (fifo)->data =kvmalloc (_bytes, (gfp) &GFP_KERNEL ); \ (fifo)->data; \ })
drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h +0 -3
@@ -41,9 +41,6 @@#define VALIDATE_TID 1 -void *cxgb_alloc_mem (unsigned long size); -void cxgb_free_mem (void *addr); -/* * Map an ATID or STID to their entries in the corresponding TID tables. */
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c +2 -23
@@ -1152,27 +1152,6 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new, }/* -* Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. -* The allocated memory is cleared. -*/ -void *cxgb_alloc_mem (unsigned long size) -{ -void *p =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); - -if (!p) - p =vzalloc (size); -return p; -} - -/* -* Free memory allocated through t3_alloc_mem(). -*/ -void cxgb_free_mem (void *addr) -{ -kvfree (addr); -} - -/* * Allocate and initialize the TID tables. Returns 0 on success. */ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,
@@ -1182,7 +1161,7 @@ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,unsigned long size = ntids *sizeof (*t->tid_tab) + natids *sizeof (*t->atid_tab) + nstids *sizeof (*t->stid_tab); - t->tid_tab =cxgb_alloc_mem (size); + t->tid_tab =kvmalloc (size,GFP_KERNEL );if (!t->tid_tab)return -ENOMEM ;
@@ -1218,7 +1197,7 @@ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,static void free_tid_maps (struct tid_info *t) { -cxgb_free_mem (t->tid_tab); +kvfree (t->tid_tab); }static inline void add_adapter (struct adapter *adap)
drivers/net/ethernet/chelsio/cxgb3/l2t.c +1 -1
@@ -444,7 +444,7 @@ struct l2t_data *t3_init_l2t(unsigned int l2t_capacity)struct l2t_data *d;int i, size =sizeof (*d) + l2t_capacity *sizeof (struct l2t_entry ); - d =cxgb_alloc_mem (size); + d =kvmalloc (size,GFP_KERNEL );if (!d)return NULL ;
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +5 -26
@@ -881,27 +881,6 @@ static int setup_sge_queues(struct adapter *adap)return err; } -/* -* Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. -* The allocated memory is cleared. -*/ -void *t4_alloc_mem (size_t size) -{ -void *p =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); - -if (!p) - p =vzalloc (size); -return p; -} - -/* -* Free memory allocated through alloc_mem(). -*/ -void t4_free_mem (void *addr) -{ -kvfree (addr); -} -static u16 cxgb_select_queue (struct net_device *dev,struct sk_buff *skb,void *accel_priv,select_queue_fallback_t fallback) {
@@ -1300,7 +1279,7 @@ static int tid_init(struct tid_info *t) max_ftids *sizeof (*t->ftid_tab) + ftid_bmap_size *sizeof (long ); - t->tid_tab =t4_alloc_mem (size); + t->tid_tab =kvmalloc (size,GFP_KERNEL );if (!t->tid_tab)return -ENOMEM ;
@@ -3416,7 +3395,7 @@ static int adap_init0(struct adapter *adap)/* allocate memory to read the header of the firmware on the * card */ - card_fw =t4_alloc_mem (sizeof (*card_fw)); + card_fw =kvmalloc (sizeof (*card_fw),GFP_KERNEL );/* Get FW from from /lib/firmware/ */ ret = request_firmware(&fw, fw_info->fw_mod_name,
@@ -3436,7 +3415,7 @@ static int adap_init0(struct adapter *adap)/* Cleaning up */ release_firmware (fw); -t4_free_mem (card_fw); +kvfree (card_fw);if (ret <0 ) goto bye;
@@ -4432,9 +4411,9 @@ static void free_some_resources(struct adapter *adapter) {unsigned int i; -t4_free_mem (adapter->l2t); +kvfree (adapter->l2t);t4_cleanup_sched (adapter); -t4_free_mem (adapter->tids.tid_tab); +kvfree (adapter->tids.tid_tab);cxgb4_cleanup_tc_u32 (adapter);kfree (adapter->sge.egr_map);kfree (adapter->sge.ingr_map);
drivers/net/ethernet/mellanox/mlx4/en_tx.c +3 -6
@@ -70,13 +70,10 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, ring->full_size = ring->size -HEADROOM -MAX_DESC_TXBBS ; tmp = size *sizeof (struct mlx4_en_tx_info ); - ring->tx_info =kmalloc_node (tmp,GFP_KERNEL | __GFP_NOWARN, node); + ring->tx_info =kvmalloc_node (tmp,GFP_KERNEL , node);if (!ring->tx_info) { - ring->tx_info =vmalloc (tmp); -if (!ring->tx_info) { - err = -ENOMEM ; - goto err_ring; - } + err = -ENOMEM ; + goto err_ring; } en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",
drivers/net/ethernet/mellanox/mlx4/mr.c +3 -6
@@ -115,12 +115,9 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)for (i =0 ; i <= buddy->max_order; ++i) { s =BITS_TO_LONGS (1 << (buddy->max_order - i)); - buddy->bits[i] =kcalloc (s,sizeof (long ),GFP_KERNEL | __GFP_NOWARN); -if (!buddy->bits[i]) { - buddy->bits[i] =vzalloc (s *sizeof (long )); -if (!buddy->bits[i]) - goto err_out_free; - } + buddy->bits[i] =kvzalloc (s *sizeof (long ),GFP_KERNEL ); +if (!buddy->bits[i]) + goto err_out_free; }set_bit (0 , buddy->bits[buddy->max_order]);
drivers/nvdimm/dimm_devs.c +1 -4
@@ -102,10 +102,7 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)return -ENXIO ; } - ndd->data =kmalloc (ndd->nsarea.config_size,GFP_KERNEL ); -if (!ndd->data) - ndd->data =vmalloc (ndd->nsarea.config_size); - + ndd->data =kvmalloc (ndd->nsarea.config_size,GFP_KERNEL );if (!ndd->data)return -ENOMEM ;
drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c +1 -10
@@ -45,15 +45,6 @@ EXPORT_SYMBOL(libcfs_kvzalloc);void *libcfs_kvzalloc_cpt (struct cfs_cpt_table *cptab,int cpt,size_t size,gfp_t flags) { -void *ret; - - ret =kzalloc_node (size, flags | __GFP_NOWARN, -cfs_cpt_spread_node (cptab, cpt)); -if (!ret) { -WARN_ON (!(flags & (__GFP_FS | __GFP_HIGH))); - ret =vmalloc_node (size,cfs_cpt_spread_node (cptab, cpt)); - } - -return ret; +return kvzalloc_node (size, flags,cfs_cpt_spread_node (cptab, cpt)); }EXPORT_SYMBOL (libcfs_kvzalloc_cpt);
drivers/xen/evtchn.c +1 -13
@@ -87,18 +87,6 @@ struct user_evtchn {bool enabled; }; -static evtchn_port_t *evtchn_alloc_ring (unsigned int size) -{ -evtchn_port_t *ring; -size_t s = size *sizeof (*ring); - - ring =kmalloc (s,GFP_KERNEL ); -if (!ring) - ring =vmalloc (s); - -return ring; -} -static void evtchn_free_ring (evtchn_port_t *ring) {kvfree (ring);
@@ -334,7 +322,7 @@ static int evtchn_resize_ring(struct per_user_data *u)else new_size =2 * u->ring_size; - new_ring =evtchn_alloc_ring (new_size); + new_ring =kvmalloc (new_size *sizeof (*new_ring),GFP_KERNEL );if (!new_ring)return -ENOMEM ;
fs/btrfs/ctree.c +3 -6
@@ -5391,13 +5391,10 @@ int btrfs_compare_trees(struct btrfs_root *left_root, goto out; } - tmp_buf =kmalloc (fs_info->nodesize,GFP_KERNEL | __GFP_NOWARN); + tmp_buf =kvmalloc (fs_info->nodesize,GFP_KERNEL );if (!tmp_buf) { - tmp_buf =vmalloc (fs_info->nodesize); -if (!tmp_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } left_path->search_commit_root =1 ;
fs/btrfs/ioctl.c +3 -6
@@ -3547,12 +3547,9 @@ static int btrfs_clone(struct inode *src, struct inode *inode,u64 last_dest_end = destoff; ret = -ENOMEM ; - buf =kmalloc (fs_info->nodesize,GFP_KERNEL | __GFP_NOWARN); -if (!buf) { - buf =vmalloc (fs_info->nodesize); -if (!buf) -return ret; - } + buf =kvmalloc (fs_info->nodesize,GFP_KERNEL ); +if (!buf) +return ret; path =btrfs_alloc_path ();if (!path) {
fs/btrfs/send.c +9 -18
@@ -6242,22 +6242,16 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) sctx->clone_roots_cnt = arg->clone_sources_count; sctx->send_max_size =BTRFS_SEND_BUF_SIZE ; - sctx->send_buf =kmalloc (sctx->send_max_size,GFP_KERNEL | __GFP_NOWARN); + sctx->send_buf =kvmalloc (sctx->send_max_size,GFP_KERNEL );if (!sctx->send_buf) { - sctx->send_buf =vmalloc (sctx->send_max_size); -if (!sctx->send_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } - sctx->read_buf =kmalloc (BTRFS_SEND_READ_SIZE ,GFP_KERNEL | __GFP_NOWARN); + sctx->read_buf =kvmalloc (BTRFS_SEND_READ_SIZE ,GFP_KERNEL );if (!sctx->read_buf) { - sctx->read_buf =vmalloc (BTRFS_SEND_READ_SIZE ); -if (!sctx->read_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } sctx->pending_dir_moves =RB_ROOT ;
@@ -6278,13 +6272,10 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) alloc_size = arg->clone_sources_count *sizeof (*arg->clone_sources);if (arg->clone_sources_count) { - clone_sources_tmp =kmalloc (alloc_size,GFP_KERNEL | __GFP_NOWARN); + clone_sources_tmp =kvmalloc (alloc_size,GFP_KERNEL );if (!clone_sources_tmp) { - clone_sources_tmp =vmalloc (alloc_size); -if (!clone_sources_tmp) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } ret = copy_from_user(clone_sources_tmp, arg->clone_sources,
fs/ceph/file.c +3 -6
@@ -74,12 +74,9 @@ dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes, align = (unsigned long )(it->iov->iov_base + it->iov_offset) & (PAGE_SIZE -1 ); npages =calc_pages_for (align, nbytes); - pages =kmalloc (sizeof (*pages) * npages,GFP_KERNEL ); -if (!pages) { - pages =vmalloc (sizeof (*pages) * npages); -if (!pages) -return ERR_PTR (-ENOMEM ); - } + pages =kvmalloc (sizeof (*pages) * npages,GFP_KERNEL ); +if (!pages) +return ERR_PTR (-ENOMEM );for (idx =0 ; idx < npages; ) {size_t start;
fs/select.c +1 -4
@@ -586,10 +586,7 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, goto out_nofds; alloc_size =6 * size; - bits =kmalloc (alloc_size,GFP_KERNEL |__GFP_NOWARN); -if (!bits && alloc_size >PAGE_SIZE ) - bits =vmalloc (alloc_size); - + bits =kvmalloc (alloc_size,GFP_KERNEL );if (!bits) goto out_nofds; }
fs/xattr.c +9 -18
@@ -431,12 +431,9 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,if (size) {if (size >XATTR_SIZE_MAX )return -E2BIG ; - kvalue =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!kvalue) { - kvalue =vmalloc (size); -if (!kvalue) -return -ENOMEM ; - } + kvalue =kvmalloc (size,GFP_KERNEL ); +if (!kvalue) +return -ENOMEM ;if (copy_from_user (kvalue, value, size)) { error = -EFAULT ; goto out;
@@ -528,12 +525,9 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,if (size) {if (size >XATTR_SIZE_MAX ) size =XATTR_SIZE_MAX ; - kvalue =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!kvalue) { - kvalue =vmalloc (size); -if (!kvalue) -return -ENOMEM ; - } + kvalue =kvmalloc (size,GFP_KERNEL ); +if (!kvalue) +return -ENOMEM ; } error =vfs_getxattr (d, kname, kvalue, size);
@@ -611,12 +605,9 @@ listxattr(struct dentry *d, char __user *list, size_t size)if (size) {if (size >XATTR_LIST_MAX ) size =XATTR_LIST_MAX ; - klist =kmalloc (size, __GFP_NOWARN |GFP_KERNEL ); -if (!klist) { - klist =vmalloc (size); -if (!klist) -return -ENOMEM ; - } + klist =kvmalloc (size,GFP_KERNEL ); +if (!klist) +return -ENOMEM ; } error =vfs_listxattr (d, klist, size);
kernel/bpf/hashtab.c +3 -8
@@ -320,14 +320,9 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) goto free_htab; err = -ENOMEM ; - htab->buckets =kmalloc_array (htab->n_buckets,sizeof (struct bucket ), -GFP_USER | __GFP_NOWARN); - -if (!htab->buckets) { - htab->buckets =vmalloc (htab->n_buckets *sizeof (struct bucket )); -if (!htab->buckets) - goto free_htab; - } + htab->buckets =kvmalloc (htab->n_buckets *sizeof (struct bucket ),GFP_USER ); +if (!htab->buckets) + goto free_htab;for (i =0 ; i < htab->n_buckets; i++) {INIT_HLIST_HEAD (&htab->buckets[i].head);
lib/iov_iter.c +1 -4
@@ -957,10 +957,7 @@ EXPORT_SYMBOL(iov_iter_get_pages);static struct page **get_pages_array (size_t n) { -struct page **p =kmalloc (n *sizeof (struct page *),GFP_KERNEL ); -if (!p) - p =vmalloc (n *sizeof (struct page *)); -return p; +return kvmalloc (n *sizeof (struct page *),GFP_KERNEL ); } static ssize_t pipe_get_pages_alloc(struct iov_iter *i,
mm/frame_vector.c +1 -4
@@ -200,10 +200,7 @@ struct frame_vector *frame_vector_create(unsigned int nr_frames)* Avoid higher order allocations, use vmalloc instead. It should * be rare anyway. */ -if (size <=PAGE_SIZE ) - vec =kmalloc (size,GFP_KERNEL ); -else - vec =vmalloc (size); + vec =kvmalloc (size,GFP_KERNEL );if (!vec)return NULL ; vec->nr_allocated = nr_frames;
net/ipv4/inet_hashtables.c +1 -5
@@ -687,11 +687,7 @@ int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo)/* no more locks than number of hash buckets */ nblocks =min (nblocks, hashinfo->ehash_mask +1 ); - hashinfo->ehash_locks =kmalloc_array (nblocks, locksz, -GFP_KERNEL | __GFP_NOWARN); -if (!hashinfo->ehash_locks) - hashinfo->ehash_locks =vmalloc (nblocks * locksz); - + hashinfo->ehash_locks =kvmalloc (nblocks * locksz,GFP_KERNEL );if (!hashinfo->ehash_locks)return -ENOMEM ;
net/ipv4/tcp_metrics.c +1 -4
@@ -1155,10 +1155,7 @@ static int __net_init tcp_net_metrics_init(struct net *net) tcp_metrics_hash_log =order_base_2 (slots); size =sizeof (struct tcpm_hash_bucket ) << tcp_metrics_hash_log; - tcp_metrics_hash =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!tcp_metrics_hash) - tcp_metrics_hash =vzalloc (size); - + tcp_metrics_hash =kvzalloc (size,GFP_KERNEL );if (!tcp_metrics_hash)return -ENOMEM ;
net/mpls/af_mpls.c +1 -4
@@ -1525,10 +1525,7 @@ static int resize_platform_label_table(struct net *net, size_t limit)unsigned index;if (size) { - labels =kzalloc (size,GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); -if (!labels) - labels =vzalloc (size); - + labels =kvzalloc (size,GFP_KERNEL );if (!labels) goto nolabels; }
net/netfilter/x_tables.c +9 -25
@@ -712,17 +712,11 @@ EXPORT_SYMBOL(xt_check_entry_offsets);*/ unsigned int *xt_alloc_entry_offsets (unsigned int size) { -unsigned int *off; - - off =kcalloc (size,sizeof (unsigned int ),GFP_KERNEL | __GFP_NOWARN); - -if (off) -return off; -if (size < (SIZE_MAX /sizeof (unsigned int ))) - off =vmalloc (size *sizeof (unsigned int )); +return kvmalloc (size *sizeof (unsigned int ),GFP_KERNEL ); + +return NULL ; -return off; }EXPORT_SYMBOL (xt_alloc_entry_offsets);
@@ -956,15 +950,9 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size)if ((SMP_ALIGN (size) >>PAGE_SHIFT ) +2 > totalram_pages)return NULL ; -if (sz <= (PAGE_SIZE <<PAGE_ALLOC_COSTLY_ORDER )) - info =kmalloc (sz,GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); -if (!info) { - info =__vmalloc (sz,GFP_KERNEL | __GFP_NOWARN | - __GFP_NORETRY | __GFP_HIGHMEM, -PAGE_KERNEL ); -if (!info) -return NULL ; - } + info =kvmalloc (sz,GFP_KERNEL ); +if (!info) +return NULL ;memset (info,0 ,sizeof (*info)); info->size = size;return info;
@@ -1066,7 +1054,7 @@ static int xt_jumpstack_alloc(struct xt_table_info *i) size =sizeof (void **) * nr_cpu_ids;if (size >PAGE_SIZE ) - i->jumpstack =vzalloc (size); + i->jumpstack =kvzalloc (size,GFP_KERNEL );else i->jumpstack =kzalloc (size,GFP_KERNEL );if (i->jumpstack ==NULL )
@@ -1088,12 +1076,8 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)*/ size =sizeof (void *) * i->stacksize *2u ;for_each_possible_cpu (cpu) { -if (size >PAGE_SIZE ) - i->jumpstack[cpu] =vmalloc_node (size, -cpu_to_node (cpu)); -else - i->jumpstack[cpu] =kmalloc_node (size, -GFP_KERNEL ,cpu_to_node (cpu)); + i->jumpstack[cpu] =kvmalloc_node (size,GFP_KERNEL , +cpu_to_node (cpu));if (i->jumpstack[cpu] ==NULL )/* * Freeing will be done later on by the callers. The
net/netfilter/xt_recent.c +1 -4
@@ -388,10 +388,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par, } sz =sizeof (*t) +sizeof (t->iphash[0 ]) * ip_list_hash_size; -if (sz <=PAGE_SIZE ) - t =kzalloc (sz,GFP_KERNEL ); -else - t =vzalloc (sz); + t =kvzalloc (sz,GFP_KERNEL );if (t ==NULL ) { ret = -ENOMEM ; goto out;
net/sched/sch_choke.c +1 -4
@@ -431,10 +431,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)if (mask != q->tab_mask) {struct sk_buff **ntab; - ntab =kcalloc (mask +1 ,sizeof (struct sk_buff *), -GFP_KERNEL | __GFP_NOWARN); -if (!ntab) - ntab =vzalloc ((mask +1 ) *sizeof (struct sk_buff *)); + ntab =kvzalloc ((mask +1 ) *sizeof (struct sk_buff *),GFP_KERNEL );if (!ntab)return -ENOMEM ;
net/sched/sch_fq_codel.c +6 -20
@@ -449,27 +449,13 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt)return 0 ; } -static void *fq_codel_zalloc (size_t sz) -{ -void *ptr =kzalloc (sz,GFP_KERNEL | __GFP_NOWARN); - -if (!ptr) - ptr =vzalloc (sz); -return ptr; -} - -static void fq_codel_free (void *addr) -{ -kvfree (addr); -} -static void fq_codel_destroy (struct Qdisc *sch) {struct fq_codel_sched_data *q =qdisc_priv (sch);tcf_destroy_chain (&q->filter_list); -fq_codel_free (q->backlogs); -fq_codel_free (q->flows); +kvfree (q->backlogs); +kvfree (q->flows); }static int fq_codel_init (struct Qdisc *sch,struct nlattr *opt)
@@ -497,13 +483,13 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) }if (!q->flows) { - q->flows =fq_codel_zalloc (q->flows_cnt * -sizeof (struct fq_codel_flow )); + q->flows =kvmalloc (q->flows_cnt * +sizeof (struct fq_codel_flow ),GFP_KERNEL );if (!q->flows)return -ENOMEM ; - q->backlogs =fq_codel_zalloc (q->flows_cnt *sizeof (u32)); + q->backlogs =kvmalloc (q->flows_cnt *sizeof (u32),GFP_KERNEL );if (!q->backlogs) { -fq_codel_free (q->flows); +kvfree (q->flows);return -ENOMEM ; }for (i =0 ; i < q->flows_cnt; i++) {
net/sched/sch_hhf.c +9 -24
@@ -467,29 +467,14 @@ static void hhf_reset(struct Qdisc *sch)rtnl_kfree_skbs (skb, skb); } -static void *hhf_zalloc (size_t sz) -{ -void *ptr =kzalloc (sz,GFP_KERNEL | __GFP_NOWARN); - -if (!ptr) - ptr =vzalloc (sz); - -return ptr; -} - -static void hhf_free (void *addr) -{ -kvfree (addr); -} -static void hhf_destroy (struct Qdisc *sch) {int i;struct hhf_sched_data *q =qdisc_priv (sch);for (i =0 ; i <HHF_ARRAYS_CNT ; i++) { -hhf_free (q->hhf_arrays[i]); -hhf_free (q->hhf_valid_bits[i]); +kvfree (q->hhf_arrays[i]); +kvfree (q->hhf_valid_bits[i]); }for (i =0 ; i <HH_FLOWS_CNT ; i++) {
@@ -503,7 +488,7 @@ static void hhf_destroy(struct Qdisc *sch)kfree (flow); } } -hhf_free (q->hh_flows); +kvfree (q->hh_flows); }static const struct nla_policy hhf_policy[TCA_HHF_MAX +1 ] = {
@@ -609,8 +594,8 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt)if (!q->hh_flows) {/* Initialize heavy-hitter flow table. */ - q->hh_flows =hhf_zalloc (HH_FLOWS_CNT * -sizeof (struct list_head )); + q->hh_flows =kvmalloc (HH_FLOWS_CNT * +sizeof (struct list_head ),GFP_KERNEL );if (!q->hh_flows)return -ENOMEM ;for (i =0 ; i <HH_FLOWS_CNT ; i++)
@@ -624,8 +609,8 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt)/* Initialize heavy-hitter filter arrays. */ for (i =0 ; i <HHF_ARRAYS_CNT ; i++) { - q->hhf_arrays[i] =hhf_zalloc (HHF_ARRAYS_LEN * -sizeof (u32)); + q->hhf_arrays[i] =kvmalloc (HHF_ARRAYS_LEN * +sizeof (u32),GFP_KERNEL );if (!q->hhf_arrays[i]) {hhf_destroy (sch);return -ENOMEM ;
@@ -635,8 +620,8 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt)/* Initialize valid bits of heavy-hitter filter arrays. */ for (i =0 ; i <HHF_ARRAYS_CNT ; i++) { - q->hhf_valid_bits[i] =hhf_zalloc (HHF_ARRAYS_LEN / -BITS_PER_BYTE ); + q->hhf_valid_bits[i] =kvmalloc (HHF_ARRAYS_LEN / +BITS_PER_BYTE ,GFP_KERNEL );if (!q->hhf_valid_bits[i]) {hhf_destroy (sch);return -ENOMEM ;
net/sched/sch_netem.c +1 -5
@@ -692,15 +692,11 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)spinlock_t *root_lock;struct disttable *d;int i; -size_t s;if (n >NETEM_DIST_MAX )return -EINVAL ; - s =sizeof (struct disttable ) + n *sizeof (s16); - d =kmalloc (s,GFP_KERNEL | __GFP_NOWARN); -if (!d) - d =vmalloc (s); + d =kvmalloc (sizeof (struct disttable ) + n *sizeof (s16),GFP_KERNEL );if (!d)return -ENOMEM ;
net/sched/sch_sfq.c +1 -5
@@ -684,11 +684,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)static void *sfq_alloc (size_t sz) { -void *ptr =kmalloc (sz,GFP_KERNEL | __GFP_NOWARN); - -if (!ptr) - ptr =vmalloc (sz); -return ptr; +return kvmalloc (sz,GFP_KERNEL ); }static void sfq_free (void *addr)
security/keys/keyctl.c +6 -16
@@ -99,14 +99,9 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,if (_payload) { ret = -ENOMEM ; - payload =kmalloc (plen,GFP_KERNEL | __GFP_NOWARN); -if (!payload) { -if (plen <=PAGE_SIZE ) - goto error2; - payload =vmalloc (plen); -if (!payload) - goto error2; - } + payload =kvmalloc (plen,GFP_KERNEL ); +if (!payload) + goto error2; ret = -EFAULT ;if (copy_from_user (payload, _payload, plen) !=0 )
@@ -1064,14 +1059,9 @@ long keyctl_instantiate_key_common(key_serial_t id,if (from) { ret = -ENOMEM ; - payload =kmalloc (plen,GFP_KERNEL ); -if (!payload) { -if (plen <=PAGE_SIZE ) - goto error; - payload =vmalloc (plen); -if (!payload) - goto error; - } + payload =kvmalloc (plen,GFP_KERNEL ); +if (!payload) + goto error; ret = -EFAULT ;if (!copy_from_iter_full (payload, plen, from))
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 12 lines · Michal Hocko
From: Michal Hocko <[email protected]>
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
Quoted 2 lines
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
For the btrfs bits,
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoQuoted 17 lines · Michal Hocko
arch/s390/kvm/kvm-s390.c +1
-4@@ -1126,10 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL );if (!keys)return -ENOMEM ;
arch/s390/kvm/kvm-s390.c static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args) · line 1173
Quoted 10 lines
arch/s390/kvm/kvm-s390.c +1
-4@@ -1171,10 +1168,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (sizeof (uint8_t ) * args->count,GFP_KERNEL );if (!keys)return -ENOMEM ;
KVM/s390 parts
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoQuoted 569 lines · Michal Hocko
From: Michal Hocko <[email protected]>
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
Cc Martin Schwidefsky <[email protected]>Cc Heiko Carstens <[email protected]>Cc Herbert Xu <[email protected]>Cc Anton Vorontsov <[email protected]>Cc Colin Cross <[email protected]>Cc Kees Cook <[email protected]>Cc Tony Luck <[email protected]>Cc "Rafael J. Wysocki" <[email protected]>Cc Ben Skeggs <[email protected]>Cc Kent Overstreet <[email protected]>Cc Santosh Raspatur <[email protected]>Cc Hariprasad S <[email protected]>Cc Tariq Toukan <[email protected]>Cc Yishai Hadas <[email protected]>Cc Dan Williams <[email protected]>Cc Oleg Drokin <[email protected]>Cc Andreas Dilger <[email protected]>Cc Boris Ostrovsky <[email protected]>Cc David Sterba <[email protected]>Cc "Yan, Zheng" <[email protected]>Cc Ilya Dryomov <[email protected]>Cc Alexander Viro <[email protected]>Cc Alexei Starovoitov <[email protected]>Cc Eric Dumazet <[email protected]>Signed-off-by Michal Hocko <[email protected]>--- arch/s390/kvm/kvm-s390.c | 10 ++----- crypto/lzo.c | 4 +-- drivers/acpi/apei/erst.c | 8 ++--- drivers/char/agp/generic.c | 8 +---- drivers/gpu/drm/nouveau/nouveau_gem.c | 4 +-- drivers/md/bcache/util.h | 12 ++------ drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h | 3 -- drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 25 ++-------------- drivers/net/ethernet/chelsio/cxgb3/l2t.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 31 ++++---------------- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 9 ++---- drivers/net/ethernet/mellanox/mlx4/mr.c | 9 ++---- drivers/nvdimm/dimm_devs.c | 5 +--- .../staging/lustre/lnet/libcfs/linux/linux-mem.c | 11 +------ drivers/xen/evtchn.c | 14 +-------- fs/btrfs/ctree.c | 9 ++---- fs/btrfs/ioctl.c | 9 ++---- fs/btrfs/send.c | 27 ++++++----------- fs/ceph/file.c | 9 ++---- fs/select.c | 5 +--- fs/xattr.c | 27 ++++++----------- kernel/bpf/hashtab.c | 11 ++----- lib/iov_iter.c | 5 +--- mm/frame_vector.c | 5 +--- net/ipv4/inet_hashtables.c | 6 +--- net/ipv4/tcp_metrics.c | 5 +--- net/mpls/af_mpls.c | 5 +--- net/netfilter/x_tables.c | 34 ++++++---------------- net/netfilter/xt_recent.c | 5 +--- net/sched/sch_choke.c | 5 +--- net/sched/sch_fq_codel.c | 26 ++++------------- net/sched/sch_hhf.c | 33 ++++++--------------- net/sched/sch_netem.c | 6 +--- net/sched/sch_sfq.c | 6 +--- security/keys/keyctl.c | 22 ++++---------- 35 files changed, 96 insertions(+), 319 deletions(-)arch/s390/kvm/kvm-s390.c +2
-8@@ -1126,10 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL );if (!keys)return -ENOMEM ;@@ -1171,10 +1168,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (sizeof (uint8_t ) * args->count,GFP_KERNEL );if (!keys)return -ENOMEM ;crypto/lzo.c +1
-3@@ -32,9 +32,7 @@ static void *lzo_alloc_ctx(struct crypto_scomp *tfm) {void *ctx; - ctx =kmalloc (LZO1X_MEM_COMPRESS ,GFP_KERNEL | __GFP_NOWARN); -if (!ctx) - ctx =vmalloc (LZO1X_MEM_COMPRESS ); + ctx =kvmalloc (LZO1X_MEM_COMPRESS ,GFP_KERNEL );if (!ctx)return ERR_PTR (-ENOMEM );drivers/acpi/apei/erst.c +2
-6@@ -513,7 +513,7 @@ static int __erst_record_id_cache_add_one(void)if (i < erst_record_id_cache.len) goto retry;if (erst_record_id_cache.len >= erst_record_id_cache.size) { -int new_size, alloc_size; +int new_size;u64 *new_entries; new_size = erst_record_id_cache.size *2 ;@@ -524,11 +524,7 @@ static int __erst_record_id_cache_add_one(void)pr_warn (FW_WARN "too many record IDs!\n" );return 0 ; } - alloc_size = new_size *sizeof (entries[0 ]); -if (alloc_size <PAGE_SIZE ) - new_entries =kmalloc (alloc_size,GFP_KERNEL ); -else - new_entries =vmalloc (alloc_size); + new_entries =kvmalloc (new_size *sizeof (entries[0 ]),GFP_KERNEL );if (!new_entries)return -ENOMEM ; memcpy(new_entries, entries,drivers/char/agp/generic.c +1
-7@@ -88,13 +88,7 @@ static int agp_get_key(void)void agp_alloc_page_array (size_t size,struct agp_memory *mem) { - mem->pages =NULL ; - -if (size <=2 *PAGE_SIZE ) - mem->pages =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (mem->pages ==NULL ) { - mem->pages =vmalloc (size); - } + mem->pages =kvmalloc (size,GFP_KERNEL ); }EXPORT_SYMBOL (agp_alloc_page_array);drivers/gpu/drm/nouveau/nouveau_gem.c +1
-3@@ -568,9 +568,7 @@ u_memcpya(uint64_t user, unsigned nmemb, unsigned size) size *= nmemb; - mem =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!mem) - mem =vmalloc (size); + mem =kvmalloc (size,GFP_KERNEL );if (!mem)return ERR_PTR (-ENOMEM );drivers/md/bcache/util.h +2
-10@@ -43,11 +43,7 @@ struct closure; (heap)->used =0 ; \ (heap)->size = (_size); \ _bytes = (heap)->size *sizeof (*(heap)->data); \ - (heap)->data =NULL ; \ -if (_bytes <KMALLOC_MAX_SIZE ) \ - (heap)->data =kmalloc (_bytes, (gfp)); \ -if ((!(heap)->data) && ((gfp) &GFP_KERNEL )) \ - (heap)->data =vmalloc (_bytes); \ + (heap)->data =kvmalloc (_bytes, (gfp) &GFP_KERNEL ); \ (heap)->data; \ })@@ -136,12 +132,8 @@ do { \ \ (fifo)->mask = _allocated_size -1 ; \ (fifo)->front = (fifo)->back =0 ; \ - (fifo)->data =NULL ; \ \ -if (_bytes <KMALLOC_MAX_SIZE ) \ - (fifo)->data =kmalloc (_bytes, (gfp)); \ -if ((!(fifo)->data) && ((gfp) &GFP_KERNEL )) \ - (fifo)->data =vmalloc (_bytes); \ + (fifo)->data =kvmalloc (_bytes, (gfp) &GFP_KERNEL ); \ (fifo)->data; \ })drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h +0
-3@@ -41,9 +41,6 @@#define VALIDATE_TID 1 -void *cxgb_alloc_mem (unsigned long size); -void cxgb_free_mem (void *addr); -/* * Map an ATID or STID to their entries in the corresponding TID tables. */ drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c +2
-23@@ -1152,27 +1152,6 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new, }/* -* Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. -* The allocated memory is cleared. -*/ -void *cxgb_alloc_mem (unsigned long size) -{ -void *p =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); - -if (!p) - p =vzalloc (size); -return p; -} - -/* -* Free memory allocated through t3_alloc_mem(). -*/ -void cxgb_free_mem (void *addr) -{ -kvfree (addr); -} - -/* * Allocate and initialize the TID tables. Returns 0 on success. */ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,@@ -1182,7 +1161,7 @@ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,unsigned long size = ntids *sizeof (*t->tid_tab) + natids *sizeof (*t->atid_tab) + nstids *sizeof (*t->stid_tab); - t->tid_tab =cxgb_alloc_mem (size); + t->tid_tab =kvmalloc (size,GFP_KERNEL );if (!t->tid_tab)return -ENOMEM ;@@ -1218,7 +1197,7 @@ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,static void free_tid_maps (struct tid_info *t) { -cxgb_free_mem (t->tid_tab); +kvfree (t->tid_tab); }static inline void add_adapter (struct adapter *adap)drivers/net/ethernet/chelsio/cxgb3/l2t.c +1
-1@@ -444,7 +444,7 @@ struct l2t_data *t3_init_l2t(unsigned int l2t_capacity)struct l2t_data *d;int i, size =sizeof (*d) + l2t_capacity *sizeof (struct l2t_entry ); - d =cxgb_alloc_mem (size); + d =kvmalloc (size,GFP_KERNEL );if (!d)return NULL ;drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +5
-26@@ -881,27 +881,6 @@ static int setup_sge_queues(struct adapter *adap)return err; } -/* -* Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. -* The allocated memory is cleared. -*/ -void *t4_alloc_mem (size_t size) -{ -void *p =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); - -if (!p) - p =vzalloc (size); -return p; -} - -/* -* Free memory allocated through alloc_mem(). -*/ -void t4_free_mem (void *addr) -{ -kvfree (addr); -} -static u16 cxgb_select_queue (struct net_device *dev,struct sk_buff *skb,void *accel_priv,select_queue_fallback_t fallback) {@@ -1300,7 +1279,7 @@ static int tid_init(struct tid_info *t) max_ftids *sizeof (*t->ftid_tab) + ftid_bmap_size *sizeof (long ); - t->tid_tab =t4_alloc_mem (size); + t->tid_tab =kvmalloc (size,GFP_KERNEL );if (!t->tid_tab)return -ENOMEM ;@@ -3416,7 +3395,7 @@ static int adap_init0(struct adapter *adap)/* allocate memory to read the header of the firmware on the * card */ - card_fw =t4_alloc_mem (sizeof (*card_fw)); + card_fw =kvmalloc (sizeof (*card_fw),GFP_KERNEL );/* Get FW from from /lib/firmware/ */ ret = request_firmware(&fw, fw_info->fw_mod_name,@@ -3436,7 +3415,7 @@ static int adap_init0(struct adapter *adap)/* Cleaning up */ release_firmware (fw); -t4_free_mem (card_fw); +kvfree (card_fw);if (ret <0 ) goto bye;@@ -4432,9 +4411,9 @@ static void free_some_resources(struct adapter *adapter) {unsigned int i; -t4_free_mem (adapter->l2t); +kvfree (adapter->l2t);t4_cleanup_sched (adapter); -t4_free_mem (adapter->tids.tid_tab); +kvfree (adapter->tids.tid_tab);cxgb4_cleanup_tc_u32 (adapter);kfree (adapter->sge.egr_map);kfree (adapter->sge.ingr_map);drivers/net/ethernet/mellanox/mlx4/en_tx.c +3
-6@@ -70,13 +70,10 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, ring->full_size = ring->size -HEADROOM -MAX_DESC_TXBBS ; tmp = size *sizeof (struct mlx4_en_tx_info ); - ring->tx_info =kmalloc_node (tmp,GFP_KERNEL | __GFP_NOWARN, node); + ring->tx_info =kvmalloc_node (tmp,GFP_KERNEL , node);if (!ring->tx_info) { - ring->tx_info =vmalloc (tmp); -if (!ring->tx_info) { - err = -ENOMEM ; - goto err_ring; - } + err = -ENOMEM ; + goto err_ring; } en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",drivers/net/ethernet/mellanox/mlx4/mr.c +3
-6@@ -115,12 +115,9 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)for (i =0 ; i <= buddy->max_order; ++i) { s =BITS_TO_LONGS (1 << (buddy->max_order - i)); - buddy->bits[i] =kcalloc (s,sizeof (long ),GFP_KERNEL | __GFP_NOWARN); -if (!buddy->bits[i]) { - buddy->bits[i] =vzalloc (s *sizeof (long )); -if (!buddy->bits[i]) - goto err_out_free; - } + buddy->bits[i] =kvzalloc (s *sizeof (long ),GFP_KERNEL ); +if (!buddy->bits[i]) + goto err_out_free; }set_bit (0 , buddy->bits[buddy->max_order]);drivers/nvdimm/dimm_devs.c +1
-4@@ -102,10 +102,7 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)return -ENXIO ; } - ndd->data =kmalloc (ndd->nsarea.config_size,GFP_KERNEL ); -if (!ndd->data) - ndd->data =vmalloc (ndd->nsarea.config_size); - + ndd->data =kvmalloc (ndd->nsarea.config_size,GFP_KERNEL );if (!ndd->data)return -ENOMEM ;drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c +1
-10@@ -45,15 +45,6 @@ EXPORT_SYMBOL(libcfs_kvzalloc);void *libcfs_kvzalloc_cpt (struct cfs_cpt_table *cptab,int cpt,size_t size,gfp_t flags) { -void *ret; - - ret =kzalloc_node (size, flags | __GFP_NOWARN, -cfs_cpt_spread_node (cptab, cpt)); -if (!ret) { -WARN_ON (!(flags & (__GFP_FS | __GFP_HIGH))); - ret =vmalloc_node (size,cfs_cpt_spread_node (cptab, cpt)); - } - -return ret; +return kvzalloc_node (size, flags,cfs_cpt_spread_node (cptab, cpt)); }EXPORT_SYMBOL (libcfs_kvzalloc_cpt);drivers/xen/evtchn.c +1
-13@@ -87,18 +87,6 @@ struct user_evtchn {bool enabled; }; -static evtchn_port_t *evtchn_alloc_ring (unsigned int size) -{ -evtchn_port_t *ring; -size_t s = size *sizeof (*ring); - - ring =kmalloc (s,GFP_KERNEL ); -if (!ring) - ring =vmalloc (s); - -return ring; -} -static void evtchn_free_ring (evtchn_port_t *ring) {kvfree (ring);@@ -334,7 +322,7 @@ static int evtchn_resize_ring(struct per_user_data *u)else new_size =2 * u->ring_size; - new_ring =evtchn_alloc_ring (new_size); + new_ring =kvmalloc (new_size *sizeof (*new_ring),GFP_KERNEL );if (!new_ring)return -ENOMEM ;fs/btrfs/ctree.c +3
-6@@ -5391,13 +5391,10 @@ int btrfs_compare_trees(struct btrfs_root *left_root, goto out; } - tmp_buf =kmalloc (fs_info->nodesize,GFP_KERNEL | __GFP_NOWARN); + tmp_buf =kvmalloc (fs_info->nodesize,GFP_KERNEL );if (!tmp_buf) { - tmp_buf =vmalloc (fs_info->nodesize); -if (!tmp_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } left_path->search_commit_root =1 ;fs/btrfs/ioctl.c +3
-6@@ -3547,12 +3547,9 @@ static int btrfs_clone(struct inode *src, struct inode *inode,u64 last_dest_end = destoff; ret = -ENOMEM ; - buf =kmalloc (fs_info->nodesize,GFP_KERNEL | __GFP_NOWARN); -if (!buf) { - buf =vmalloc (fs_info->nodesize); -if (!buf) -return ret; - } + buf =kvmalloc (fs_info->nodesize,GFP_KERNEL ); +if (!buf) +return ret; path =btrfs_alloc_path ();if (!path) {fs/btrfs/send.c +9
-18@@ -6242,22 +6242,16 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) sctx->clone_roots_cnt = arg->clone_sources_count; sctx->send_max_size =BTRFS_SEND_BUF_SIZE ; - sctx->send_buf =kmalloc (sctx->send_max_size,GFP_KERNEL | __GFP_NOWARN); + sctx->send_buf =kvmalloc (sctx->send_max_size,GFP_KERNEL );if (!sctx->send_buf) { - sctx->send_buf =vmalloc (sctx->send_max_size); -if (!sctx->send_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } - sctx->read_buf =kmalloc (BTRFS_SEND_READ_SIZE ,GFP_KERNEL | __GFP_NOWARN); + sctx->read_buf =kvmalloc (BTRFS_SEND_READ_SIZE ,GFP_KERNEL );if (!sctx->read_buf) { - sctx->read_buf =vmalloc (BTRFS_SEND_READ_SIZE ); -if (!sctx->read_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } sctx->pending_dir_moves =RB_ROOT ;@@ -6278,13 +6272,10 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) alloc_size = arg->clone_sources_count *sizeof (*arg->clone_sources);if (arg->clone_sources_count) { - clone_sources_tmp =kmalloc (alloc_size,GFP_KERNEL | __GFP_NOWARN); + clone_sources_tmp =kvmalloc (alloc_size,GFP_KERNEL );if (!clone_sources_tmp) { - clone_sources_tmp =vmalloc (alloc_size); -if (!clone_sources_tmp) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } ret = copy_from_user(clone_sources_tmp, arg->clone_sources,fs/ceph/file.c +0
-0@@ -74,12 +74,9 @@ dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes, align = (unsigned long )(it->iov->iov_base + it->iov_offset) & (PAGE_SIZE -1 );
fs/ceph/file.c dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes, · line 79
Quoted 10 lines
fs/ceph/file.c +3
-6npages =calc_pages_for (align, nbytes); - pages =kmalloc (sizeof (*pages) * npages,GFP_KERNEL ); -if (!pages) { - pages =vmalloc (sizeof (*pages) * npages); -if (!pages) -return ERR_PTR (-ENOMEM ); - } + pages =kvmalloc (sizeof (*pages) * npages,GFP_KERNEL ); +if (!pages) +return ERR_PTR (-ENOMEM );
ceph hunk looks fine:
However I noticed that in some cases you've dropped the zeroing part:fq_codel_init() and hhf_zalloc() zeroed both k and v, and some others were inconsistent and zeroed only k. Given that the fallback branch was probably dead, I'd keep the k behaviour. Was that intentional?
Thanks,
Ilya
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 583 lines · Ilya Dryomov
Quoted 569 lines · Michal Hocko
From: Michal Hocko <[email protected]>
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
Cc Martin Schwidefsky <[email protected]>Cc Heiko Carstens <[email protected]>Cc Herbert Xu <[email protected]>Cc Anton Vorontsov <[email protected]>Cc Colin Cross <[email protected]>Cc Kees Cook <[email protected]>Cc Tony Luck <[email protected]>Cc "Rafael J. Wysocki" <[email protected]>Cc Ben Skeggs <[email protected]>Cc Kent Overstreet <[email protected]>Cc Santosh Raspatur <[email protected]>Cc Hariprasad S <[email protected]>Cc Tariq Toukan <[email protected]>Cc Yishai Hadas <[email protected]>Cc Dan Williams <[email protected]>Cc Oleg Drokin <[email protected]>Cc Andreas Dilger <[email protected]>Cc Boris Ostrovsky <[email protected]>Cc David Sterba <[email protected]>Cc "Yan, Zheng" <[email protected]>Cc Ilya Dryomov <[email protected]>Cc Alexander Viro <[email protected]>Cc Alexei Starovoitov <[email protected]>Cc Eric Dumazet <[email protected]>Signed-off-by Michal Hocko <[email protected]>--- arch/s390/kvm/kvm-s390.c | 10 ++----- crypto/lzo.c | 4 +-- drivers/acpi/apei/erst.c | 8 ++--- drivers/char/agp/generic.c | 8 +---- drivers/gpu/drm/nouveau/nouveau_gem.c | 4 +-- drivers/md/bcache/util.h | 12 ++------ drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h | 3 -- drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 25 ++-------------- drivers/net/ethernet/chelsio/cxgb3/l2t.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 31 ++++---------------- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 9 ++---- drivers/net/ethernet/mellanox/mlx4/mr.c | 9 ++---- drivers/nvdimm/dimm_devs.c | 5 +--- .../staging/lustre/lnet/libcfs/linux/linux-mem.c | 11 +------ drivers/xen/evtchn.c | 14 +-------- fs/btrfs/ctree.c | 9 ++---- fs/btrfs/ioctl.c | 9 ++---- fs/btrfs/send.c | 27 ++++++----------- fs/ceph/file.c | 9 ++---- fs/select.c | 5 +--- fs/xattr.c | 27 ++++++----------- kernel/bpf/hashtab.c | 11 ++----- lib/iov_iter.c | 5 +--- mm/frame_vector.c | 5 +--- net/ipv4/inet_hashtables.c | 6 +--- net/ipv4/tcp_metrics.c | 5 +--- net/mpls/af_mpls.c | 5 +--- net/netfilter/x_tables.c | 34 ++++++---------------- net/netfilter/xt_recent.c | 5 +--- net/sched/sch_choke.c | 5 +--- net/sched/sch_fq_codel.c | 26 ++++------------- net/sched/sch_hhf.c | 33 ++++++--------------- net/sched/sch_netem.c | 6 +--- net/sched/sch_sfq.c | 6 +--- security/keys/keyctl.c | 22 ++++---------- 35 files changed, 96 insertions(+), 319 deletions(-)arch/s390/kvm/kvm-s390.c +2
-8@@ -1126,10 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL );if (!keys)return -ENOMEM ;@@ -1171,10 +1168,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (sizeof (uint8_t ) * args->count,GFP_KERNEL );if (!keys)return -ENOMEM ;crypto/lzo.c +1
-3@@ -32,9 +32,7 @@ static void *lzo_alloc_ctx(struct crypto_scomp *tfm) {void *ctx; - ctx =kmalloc (LZO1X_MEM_COMPRESS ,GFP_KERNEL | __GFP_NOWARN); -if (!ctx) - ctx =vmalloc (LZO1X_MEM_COMPRESS ); + ctx =kvmalloc (LZO1X_MEM_COMPRESS ,GFP_KERNEL );if (!ctx)return ERR_PTR (-ENOMEM );drivers/acpi/apei/erst.c +2
-6@@ -513,7 +513,7 @@ static int __erst_record_id_cache_add_one(void)if (i < erst_record_id_cache.len) goto retry;if (erst_record_id_cache.len >= erst_record_id_cache.size) { -int new_size, alloc_size; +int new_size;u64 *new_entries; new_size = erst_record_id_cache.size *2 ;@@ -524,11 +524,7 @@ static int __erst_record_id_cache_add_one(void)pr_warn (FW_WARN "too many record IDs!\n" );return 0 ; } - alloc_size = new_size *sizeof (entries[0 ]); -if (alloc_size <PAGE_SIZE ) - new_entries =kmalloc (alloc_size,GFP_KERNEL ); -else - new_entries =vmalloc (alloc_size); + new_entries =kvmalloc (new_size *sizeof (entries[0 ]),GFP_KERNEL );if (!new_entries)return -ENOMEM ; memcpy(new_entries, entries,drivers/char/agp/generic.c +1
-7@@ -88,13 +88,7 @@ static int agp_get_key(void)void agp_alloc_page_array (size_t size,struct agp_memory *mem) { - mem->pages =NULL ; - -if (size <=2 *PAGE_SIZE ) - mem->pages =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (mem->pages ==NULL ) { - mem->pages =vmalloc (size); - } + mem->pages =kvmalloc (size,GFP_KERNEL ); }EXPORT_SYMBOL (agp_alloc_page_array);drivers/gpu/drm/nouveau/nouveau_gem.c +1
-3@@ -568,9 +568,7 @@ u_memcpya(uint64_t user, unsigned nmemb, unsigned size) size *= nmemb; - mem =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!mem) - mem =vmalloc (size); + mem =kvmalloc (size,GFP_KERNEL );if (!mem)return ERR_PTR (-ENOMEM );drivers/md/bcache/util.h +2
-10@@ -43,11 +43,7 @@ struct closure; (heap)->used =0 ; \ (heap)->size = (_size); \ _bytes = (heap)->size *sizeof (*(heap)->data); \ - (heap)->data =NULL ; \ -if (_bytes <KMALLOC_MAX_SIZE ) \ - (heap)->data =kmalloc (_bytes, (gfp)); \ -if ((!(heap)->data) && ((gfp) &GFP_KERNEL )) \ - (heap)->data =vmalloc (_bytes); \ + (heap)->data =kvmalloc (_bytes, (gfp) &GFP_KERNEL ); \ (heap)->data; \ })@@ -136,12 +132,8 @@ do { \ \ (fifo)->mask = _allocated_size -1 ; \ (fifo)->front = (fifo)->back =0 ; \ - (fifo)->data =NULL ; \ \ -if (_bytes <KMALLOC_MAX_SIZE ) \ - (fifo)->data =kmalloc (_bytes, (gfp)); \ -if ((!(fifo)->data) && ((gfp) &GFP_KERNEL )) \ - (fifo)->data =vmalloc (_bytes); \ + (fifo)->data =kvmalloc (_bytes, (gfp) &GFP_KERNEL ); \ (fifo)->data; \ })drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h +0
-3@@ -41,9 +41,6 @@#define VALIDATE_TID 1 -void *cxgb_alloc_mem (unsigned long size); -void cxgb_free_mem (void *addr); -/* * Map an ATID or STID to their entries in the corresponding TID tables. */ drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c +2
-23@@ -1152,27 +1152,6 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new, }/* -* Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. -* The allocated memory is cleared. -*/ -void *cxgb_alloc_mem (unsigned long size) -{ -void *p =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); - -if (!p) - p =vzalloc (size); -return p; -} - -/* -* Free memory allocated through t3_alloc_mem(). -*/ -void cxgb_free_mem (void *addr) -{ -kvfree (addr); -} - -/* * Allocate and initialize the TID tables. Returns 0 on success. */ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,@@ -1182,7 +1161,7 @@ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,unsigned long size = ntids *sizeof (*t->tid_tab) + natids *sizeof (*t->atid_tab) + nstids *sizeof (*t->stid_tab); - t->tid_tab =cxgb_alloc_mem (size); + t->tid_tab =kvmalloc (size,GFP_KERNEL );if (!t->tid_tab)return -ENOMEM ;@@ -1218,7 +1197,7 @@ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,static void free_tid_maps (struct tid_info *t) { -cxgb_free_mem (t->tid_tab); +kvfree (t->tid_tab); }static inline void add_adapter (struct adapter *adap)drivers/net/ethernet/chelsio/cxgb3/l2t.c +1
-1@@ -444,7 +444,7 @@ struct l2t_data *t3_init_l2t(unsigned int l2t_capacity)struct l2t_data *d;int i, size =sizeof (*d) + l2t_capacity *sizeof (struct l2t_entry ); - d =cxgb_alloc_mem (size); + d =kvmalloc (size,GFP_KERNEL );if (!d)return NULL ;drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +5
-26@@ -881,27 +881,6 @@ static int setup_sge_queues(struct adapter *adap)return err; } -/* -* Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. -* The allocated memory is cleared. -*/ -void *t4_alloc_mem (size_t size) -{ -void *p =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); - -if (!p) - p =vzalloc (size); -return p; -} - -/* -* Free memory allocated through alloc_mem(). -*/ -void t4_free_mem (void *addr) -{ -kvfree (addr); -} -static u16 cxgb_select_queue (struct net_device *dev,struct sk_buff *skb,void *accel_priv,select_queue_fallback_t fallback) {@@ -1300,7 +1279,7 @@ static int tid_init(struct tid_info *t) max_ftids *sizeof (*t->ftid_tab) + ftid_bmap_size *sizeof (long ); - t->tid_tab =t4_alloc_mem (size); + t->tid_tab =kvmalloc (size,GFP_KERNEL );if (!t->tid_tab)return -ENOMEM ;@@ -3416,7 +3395,7 @@ static int adap_init0(struct adapter *adap)/* allocate memory to read the header of the firmware on the * card */ - card_fw =t4_alloc_mem (sizeof (*card_fw)); + card_fw =kvmalloc (sizeof (*card_fw),GFP_KERNEL );/* Get FW from from /lib/firmware/ */ ret = request_firmware(&fw, fw_info->fw_mod_name,@@ -3436,7 +3415,7 @@ static int adap_init0(struct adapter *adap)/* Cleaning up */ release_firmware (fw); -t4_free_mem (card_fw); +kvfree (card_fw);if (ret <0 ) goto bye;@@ -4432,9 +4411,9 @@ static void free_some_resources(struct adapter *adapter) {unsigned int i; -t4_free_mem (adapter->l2t); +kvfree (adapter->l2t);t4_cleanup_sched (adapter); -t4_free_mem (adapter->tids.tid_tab); +kvfree (adapter->tids.tid_tab);cxgb4_cleanup_tc_u32 (adapter);kfree (adapter->sge.egr_map);kfree (adapter->sge.ingr_map);drivers/net/ethernet/mellanox/mlx4/en_tx.c +3
-6@@ -70,13 +70,10 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, ring->full_size = ring->size -HEADROOM -MAX_DESC_TXBBS ; tmp = size *sizeof (struct mlx4_en_tx_info ); - ring->tx_info =kmalloc_node (tmp,GFP_KERNEL | __GFP_NOWARN, node); + ring->tx_info =kvmalloc_node (tmp,GFP_KERNEL , node);if (!ring->tx_info) { - ring->tx_info =vmalloc (tmp); -if (!ring->tx_info) { - err = -ENOMEM ; - goto err_ring; - } + err = -ENOMEM ; + goto err_ring; } en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",drivers/net/ethernet/mellanox/mlx4/mr.c +3
-6@@ -115,12 +115,9 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)for (i =0 ; i <= buddy->max_order; ++i) { s =BITS_TO_LONGS (1 << (buddy->max_order - i)); - buddy->bits[i] =kcalloc (s,sizeof (long ),GFP_KERNEL | __GFP_NOWARN); -if (!buddy->bits[i]) { - buddy->bits[i] =vzalloc (s *sizeof (long )); -if (!buddy->bits[i]) - goto err_out_free; - } + buddy->bits[i] =kvzalloc (s *sizeof (long ),GFP_KERNEL ); +if (!buddy->bits[i]) + goto err_out_free; }set_bit (0 , buddy->bits[buddy->max_order]);drivers/nvdimm/dimm_devs.c +1
-4@@ -102,10 +102,7 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)return -ENXIO ; } - ndd->data =kmalloc (ndd->nsarea.config_size,GFP_KERNEL ); -if (!ndd->data) - ndd->data =vmalloc (ndd->nsarea.config_size); - + ndd->data =kvmalloc (ndd->nsarea.config_size,GFP_KERNEL );if (!ndd->data)return -ENOMEM ;drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c +1
-10@@ -45,15 +45,6 @@ EXPORT_SYMBOL(libcfs_kvzalloc);void *libcfs_kvzalloc_cpt (struct cfs_cpt_table *cptab,int cpt,size_t size,gfp_t flags) { -void *ret; - - ret =kzalloc_node (size, flags | __GFP_NOWARN, -cfs_cpt_spread_node (cptab, cpt)); -if (!ret) { -WARN_ON (!(flags & (__GFP_FS | __GFP_HIGH))); - ret =vmalloc_node (size,cfs_cpt_spread_node (cptab, cpt)); - } - -return ret; +return kvzalloc_node (size, flags,cfs_cpt_spread_node (cptab, cpt)); }EXPORT_SYMBOL (libcfs_kvzalloc_cpt);drivers/xen/evtchn.c +1
-13@@ -87,18 +87,6 @@ struct user_evtchn {bool enabled; }; -static evtchn_port_t *evtchn_alloc_ring (unsigned int size) -{ -evtchn_port_t *ring; -size_t s = size *sizeof (*ring); - - ring =kmalloc (s,GFP_KERNEL ); -if (!ring) - ring =vmalloc (s); - -return ring; -} -static void evtchn_free_ring (evtchn_port_t *ring) {kvfree (ring);@@ -334,7 +322,7 @@ static int evtchn_resize_ring(struct per_user_data *u)else new_size =2 * u->ring_size; - new_ring =evtchn_alloc_ring (new_size); + new_ring =kvmalloc (new_size *sizeof (*new_ring),GFP_KERNEL );if (!new_ring)return -ENOMEM ;fs/btrfs/ctree.c +3
-6@@ -5391,13 +5391,10 @@ int btrfs_compare_trees(struct btrfs_root *left_root, goto out; } - tmp_buf =kmalloc (fs_info->nodesize,GFP_KERNEL | __GFP_NOWARN); + tmp_buf =kvmalloc (fs_info->nodesize,GFP_KERNEL );if (!tmp_buf) { - tmp_buf =vmalloc (fs_info->nodesize); -if (!tmp_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } left_path->search_commit_root =1 ;fs/btrfs/ioctl.c +3
-6@@ -3547,12 +3547,9 @@ static int btrfs_clone(struct inode *src, struct inode *inode,u64 last_dest_end = destoff; ret = -ENOMEM ; - buf =kmalloc (fs_info->nodesize,GFP_KERNEL | __GFP_NOWARN); -if (!buf) { - buf =vmalloc (fs_info->nodesize); -if (!buf) -return ret; - } + buf =kvmalloc (fs_info->nodesize,GFP_KERNEL ); +if (!buf) +return ret; path =btrfs_alloc_path ();if (!path) {fs/btrfs/send.c +9
-18@@ -6242,22 +6242,16 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) sctx->clone_roots_cnt = arg->clone_sources_count; sctx->send_max_size =BTRFS_SEND_BUF_SIZE ; - sctx->send_buf =kmalloc (sctx->send_max_size,GFP_KERNEL | __GFP_NOWARN); + sctx->send_buf =kvmalloc (sctx->send_max_size,GFP_KERNEL );if (!sctx->send_buf) { - sctx->send_buf =vmalloc (sctx->send_max_size); -if (!sctx->send_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } - sctx->read_buf =kmalloc (BTRFS_SEND_READ_SIZE ,GFP_KERNEL | __GFP_NOWARN); + sctx->read_buf =kvmalloc (BTRFS_SEND_READ_SIZE ,GFP_KERNEL );if (!sctx->read_buf) { - sctx->read_buf =vmalloc (BTRFS_SEND_READ_SIZE ); -if (!sctx->read_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } sctx->pending_dir_moves =RB_ROOT ;@@ -6278,13 +6272,10 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) alloc_size = arg->clone_sources_count *sizeof (*arg->clone_sources);if (arg->clone_sources_count) { - clone_sources_tmp =kmalloc (alloc_size,GFP_KERNEL | __GFP_NOWARN); + clone_sources_tmp =kvmalloc (alloc_size,GFP_KERNEL );if (!clone_sources_tmp) { - clone_sources_tmp =vmalloc (alloc_size); -if (!clone_sources_tmp) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } ret = copy_from_user(clone_sources_tmp, arg->clone_sources,fs/ceph/file.c +0
-0@@ -74,12 +74,9 @@ dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes, align = (unsigned long )(it->iov->iov_base + it->iov_offset) & (PAGE_SIZE -1 );fs/ceph/file.c dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes, · line 79
Quoted 10 lines
fs/ceph/file.c +3
-6npages =calc_pages_for (align, nbytes); - pages =kmalloc (sizeof (*pages) * npages,GFP_KERNEL ); -if (!pages) { - pages =vmalloc (sizeof (*pages) * npages); -if (!pages) -return ERR_PTR (-ENOMEM ); - } + pages =kvmalloc (sizeof (*pages) * npages,GFP_KERNEL ); +if (!pages) +return ERR_PTR (-ENOMEM );ceph hunk looks fine:
Quoted 1 line
Acked-by Ilya Dryomov <[email protected]>
thanks!
[...]
Quoted 4 lines
However I noticed that in some cases you've dropped the zeroing part:
fq_codel_init()andhhf_zalloc()zeroed both k and v, and some others were inconsistent and zeroed only k. Given that the fallback branch was probably dead, I'd keep the k behaviour. Was that intentional?
No, that is an omission. Thanks for noticing. I will send the updated patch.
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoQuoted 15 lines · Michal Hocko
From: Michal Hocko <[email protected]>
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
[..]
Quoted 1 line
Cc Dan Williams <[email protected]>
[..]
Quoted 1 line
drivers/nvdimm/dimm_devs.c | 5 +---
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoQuoted 84 lines · Michal Hocko
From: Michal Hocko <[email protected]>
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
Cc Martin Schwidefsky <[email protected]>Cc Heiko Carstens <[email protected]>Cc Herbert Xu <[email protected]>Cc Anton Vorontsov <[email protected]>Cc Colin Cross <[email protected]>Cc Kees Cook <[email protected]>Cc Tony Luck <[email protected]>Cc "Rafael J. Wysocki" <[email protected]>Cc Ben Skeggs <[email protected]>Cc Kent Overstreet <[email protected]>Cc Santosh Raspatur <[email protected]>Cc Hariprasad S <[email protected]>Cc Tariq Toukan <[email protected]>Cc Yishai Hadas <[email protected]>Cc Dan Williams <[email protected]>Cc Oleg Drokin <[email protected]>Cc Andreas Dilger <[email protected]>Cc Boris Ostrovsky <[email protected]>Cc David Sterba <[email protected]>Cc "Yan, Zheng" <[email protected]>Cc Ilya Dryomov <[email protected]>Cc Alexander Viro <[email protected]>Cc Alexei Starovoitov <[email protected]>Cc Eric Dumazet <[email protected]>Signed-off-by Michal Hocko <[email protected]>--- arch/s390/kvm/kvm-s390.c | 10 ++----- crypto/lzo.c | 4 +-- drivers/acpi/apei/erst.c | 8 ++--- drivers/char/agp/generic.c | 8 +---- drivers/gpu/drm/nouveau/nouveau_gem.c | 4 +-- drivers/md/bcache/util.h | 12 ++------ drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h | 3 -- drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 25 ++-------------- drivers/net/ethernet/chelsio/cxgb3/l2t.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 31 ++++---------------- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 9 ++---- drivers/net/ethernet/mellanox/mlx4/mr.c | 9 ++---- drivers/nvdimm/dimm_devs.c | 5 +--- .../staging/lustre/lnet/libcfs/linux/linux-mem.c | 11 +------ drivers/xen/evtchn.c | 14 +-------- fs/btrfs/ctree.c | 9 ++---- fs/btrfs/ioctl.c | 9 ++---- fs/btrfs/send.c | 27 ++++++----------- fs/ceph/file.c | 9 ++---- fs/select.c | 5 +--- fs/xattr.c | 27 ++++++----------- kernel/bpf/hashtab.c | 11 ++----- lib/iov_iter.c | 5 +--- mm/frame_vector.c | 5 +--- net/ipv4/inet_hashtables.c | 6 +--- net/ipv4/tcp_metrics.c | 5 +--- net/mpls/af_mpls.c | 5 +--- net/netfilter/x_tables.c | 34 ++++++---------------- net/netfilter/xt_recent.c | 5 +--- net/sched/sch_choke.c | 5 +--- net/sched/sch_fq_codel.c | 26 ++++------------- net/sched/sch_hhf.c | 33 ++++++--------------- net/sched/sch_netem.c | 6 +--- net/sched/sch_sfq.c | 6 +--- security/keys/keyctl.c | 22 ++++---------- 35 files changed, 96 insertions(+), 319 deletions(-)arch/s390/kvm/kvm-s390.c +0
-0
arch/s390/kvm/kvm-s390.c static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args) · line 1129
Quoted 8 lines
arch/s390/kvm/kvm-s390.c +1
-4@@ -1126,10 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL );
Before doing this conversion, can we add a kvmalloc_array() API? This conversion could allow for the reintroduction of integer overflow flaws. (This particular situation isn't at risk since ->count is checked, but I'd prefer we not create a risky set of examples for using kvmalloc.)
Besides that: yes please. Less open coding. :)
-Kees
Signature · 8 lines
Kees Cook Nexus Security -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 1 line · Kees Cook
On Thu, Jan 12, 2017 at 7:37 AM, Michal Hocko <[email protected]> wrote:
[...]
Quoted 8 lines
Quoted 8 lines
arch/s390/kvm/kvm-s390.c +0
-0@@ -1126,10 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ;
Quoted 11 lines
arch/s390/kvm/kvm-s390.c static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args) · line 1129
Quoted 5 lines
arch/s390/kvm/kvm-s390.c +1
-4- keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL );Before doing this conversion, can we add a
kvmalloc_array()API? This conversion could allow for the reintroduction of integer overflow flaws. (This particular situation isn't at risk since ->count is checked, but I'd prefer we not create a risky set of examples for using kvmalloc.)
Well, I am not opposed to kvmalloc_array but I would argue that this conversion cannot introduce new overflow issues. The code would have to be broken already because even though kmalloc_array checks for the overflow but vmalloc fallback doesn't...
If there is a general interest for this API I can add it.
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 23 lines · Michal Hocko
Quoted 1 line · Kees Cook
On Thu, Jan 12, 2017 at 7:37 AM, Michal Hocko <[email protected]> wrote:
[...]
Quoted 8 lines
Quoted 8 lines
arch/s390/kvm/kvm-s390.c +0
-0@@ -1126,10 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ;Quoted 11 lines
arch/s390/kvm/kvm-s390.c static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args) · line 1129
Quoted 5 lines
arch/s390/kvm/kvm-s390.c +1
-4- keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL );Before doing this conversion, can we add a
kvmalloc_array()API? This conversion could allow for the reintroduction of integer overflow flaws. (This particular situation isn't at risk since ->count is checked, but I'd prefer we not create a risky set of examples for using kvmalloc.)
Quoted 4 lines
Well, I am not opposed to
kvmalloc_arraybut I would argue that this conversion cannot introduce new overflow issues. The code would have to be broken already because even thoughkmalloc_arraychecks for the overflow but vmalloc fallback doesn't...
Yeah I agree, but if some of the places were really wrong, after the conversion we won't see them anymore.
Quoted 1 line
If there is a general interest for this API I can add it.
I think it would be better, yes.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 29 lines · Vlastimil Babka
Quoted 23 lines · Michal Hocko
Quoted 1 line · Kees Cook
On Thu, Jan 12, 2017 at 7:37 AM, Michal Hocko <[email protected]> wrote:
[...]
Quoted 8 lines
Quoted 8 lines
arch/s390/kvm/kvm-s390.c +0
-0@@ -1126,10 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ;Quoted 11 lines
arch/s390/kvm/kvm-s390.c static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args) · line 1129
Quoted 5 lines
arch/s390/kvm/kvm-s390.c +1
-4- keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL );Before doing this conversion, can we add a
kvmalloc_array()API? This conversion could allow for the reintroduction of integer overflow flaws. (This particular situation isn't at risk since ->count is checked, but I'd prefer we not create a risky set of examples for using kvmalloc.)Quoted 4 lines
Well, I am not opposed to
kvmalloc_arraybut I would argue that this conversion cannot introduce new overflow issues. The code would have to be broken already because even thoughkmalloc_arraychecks for the overflow but vmalloc fallback doesn't...
Quoted 6 lines
Yeah I agree, but if some of the places were really wrong, after the conversion we won't see them anymore.
Quoted 1 line
If there is a general interest for this API I can add it.
I think it would be better, yes.
OK, fair enough. I will fold the following into the original patch. I was little bit reluctant to create kvcalloc so I've made the original callers more talkative and added | __GFP_ZERO. To be honest I do not really like how kcalloc...
---
arch/s390/kvm/kvm-s390.c +2 -2
@@ -1126,7 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL ); + keys =kvmalloc_array (args->count,sizeof (uint8_t ),GFP_KERNEL );if (!keys)return -ENOMEM ;
@@ -1168,7 +1168,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kvmalloc (sizeof (uint8_t ) * args->count,GFP_KERNEL ); + keys =kvmalloc_array (args->count,sizeof (uint8_t ),GFP_KERNEL );if (!keys)return -ENOMEM ;
drivers/net/ethernet/mellanox/mlx4/mr.c +1 -1
@@ -115,7 +115,7 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)for (i =0 ; i <= buddy->max_order; ++i) { s =BITS_TO_LONGS (1 << (buddy->max_order - i)); - buddy->bits[i] =kvzalloc (s *sizeof (long ),GFP_KERNEL ); + buddy->bits[i] =kvmalloc_array (s,sizeof (long ),GFP_KERNEL | __GFP_ZERO);if (!buddy->bits[i]) goto err_out_free; }
include/linux/mm.h +8 -0
@@ -498,6 +498,14 @@ static inline void *kvzalloc(size_t size, gfp_t flags)return kvmalloc (size, flags | __GFP_ZERO); } +static inline void *kvmalloc_array (size_t n,size_t size,gfp_t flags) +{ +if (size !=0 && n >SIZE_MAX / size) +return NULL ; + +return kvmalloc (n * size, flags); +} +extern void kvfree (const void *addr);static inline atomic_t *compound_mapcount_ptr (struct page *page)
kernel/bpf/hashtab.c +1 -1
@@ -320,7 +320,7 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) goto free_htab; err = -ENOMEM ; - htab->buckets =kvmalloc (htab->n_buckets *sizeof (struct bucket ),GFP_USER ); + htab->buckets =kvmalloc_array (htab->n_buckets,sizeof (struct bucket ),GFP_USER );if (!htab->buckets) goto free_htab;
lib/iov_iter.c +1 -1
@@ -957,7 +957,7 @@ EXPORT_SYMBOL(iov_iter_get_pages);static struct page **get_pages_array (size_t n) { -return kvmalloc (n *sizeof (struct page *),GFP_KERNEL ); +return kvmalloc_array (n,sizeof (struct page *),GFP_KERNEL ); } static ssize_t pipe_get_pages_alloc(struct iov_iter *i,
net/ipv4/inet_hashtables.c +1 -1
@@ -687,7 +687,7 @@ int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo)/* no more locks than number of hash buckets */ nblocks =min (nblocks, hashinfo->ehash_mask +1 ); - hashinfo->ehash_locks =kvmalloc (nblocks * locksz,GFP_KERNEL ); + hashinfo->ehash_locks =kvmalloc_array (nblocks, locksz,GFP_KERNEL );if (!hashinfo->ehash_locks)return -ENOMEM ;
net/netfilter/x_tables.c +1 -4
@@ -712,10 +712,7 @@ EXPORT_SYMBOL(xt_check_entry_offsets);*/ unsigned int *xt_alloc_entry_offsets (unsigned int size) { -if (size < (SIZE_MAX /sizeof (unsigned int ))) -return kvzalloc (size *sizeof (unsigned int ),GFP_KERNEL ); - -return NULL ; +return kvmalloc_array (size *sizeof (unsigned int ),GFP_KERNEL | __GFP_ZERO); }EXPORT_SYMBOL (xt_alloc_entry_offsets);
net/sched/sch_choke.c +1 -1
@@ -431,7 +431,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)if (mask != q->tab_mask) {struct sk_buff **ntab; - ntab =kvzalloc ((mask +1 ) *sizeof (struct sk_buff *),GFP_KERNEL ); + ntab =kvmalloc_array ((mask +1 ),sizeof (struct sk_buff *),GFP_KERNEL | __GFP_ZERO);if (!ntab)return -ENOMEM ;
Signature · 2 lines
Michal Hocko SUSE Labs
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 8 lines · Michal Hocko
Quoted 8 lines
Quoted 4 lines
Well, I am not opposed to
kvmalloc_arraybut I would argue that this conversion cannot introduce new overflow issues. The code would have to be broken already because even thoughkmalloc_arraychecks for the overflow but vmalloc fallback doesn't...Yeah I agree, but if some of the places were really wrong, after the conversion we won't see them anymore.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
If there is a general interest for this API I can add it.
I think it would be better, yes.
OK, fair enough. I will fold the following into the original patch. I was little bit reluctant to create kvcalloc so I've made the original callers more talkative and added |
__GFP_ZERO.
Fair enough,
Quoted 2 lines
To be honest I do not
really like how kcalloc...
how kcalloc what?
[...]
net/netfilter/x_tables.c EXPORT_SYMBOL(xt_check_entry_offsets); · line 715
Quoted 13 lines
net/netfilter/x_tables.c +1
-4@@ -712,10 +712,7 @@ EXPORT_SYMBOL(xt_check_entry_offsets);*/ unsigned int *xt_alloc_entry_offsets (unsigned int size) { -if (size < (SIZE_MAX /sizeof (unsigned int ))) -return kvzalloc (size *sizeof (unsigned int ),GFP_KERNEL ); - -return NULL ; +return kvmalloc_array (size *sizeof (unsigned int ),GFP_KERNEL | __GFP_ZERO);
This one wouldn't compile.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 17 lines · Vlastimil Babka
Quoted 8 lines · Michal Hocko
Quoted 8 lines
Quoted 4 lines
Well, I am not opposed to
kvmalloc_arraybut I would argue that this conversion cannot introduce new overflow issues. The code would have to be broken already because even thoughkmalloc_arraychecks for the overflow but vmalloc fallback doesn't...Yeah I agree, but if some of the places were really wrong, after the conversion we won't see them anymore.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
If there is a general interest for this API I can add it.
I think it would be better, yes.
OK, fair enough. I will fold the following into the original patch. I was little bit reluctant to create kvcalloc so I've made the original callers more talkative and added |
__GFP_ZERO.
Quoted 6 lines
Fair enough,
Quoted 2 lines
To be honest I do not
really like how kcalloc...how kcalloc what?
how kcalloc hides the GFP_ZERO and the name doesn't reflect that.
Quoted 16 lines
[...]
net/netfilter/x_tables.c EXPORT_SYMBOL(xt_check_entry_offsets); · line 715
Quoted 13 lines
net/netfilter/x_tables.c +1
-4@@ -712,10 +712,7 @@ EXPORT_SYMBOL(xt_check_entry_offsets);*/ unsigned int *xt_alloc_entry_offsets (unsigned int size) { -if (size < (SIZE_MAX /sizeof (unsigned int ))) -return kvzalloc (size *sizeof (unsigned int ),GFP_KERNEL ); - -return NULL ; +return kvmalloc_array (size *sizeof (unsigned int ),GFP_KERNEL | __GFP_ZERO);This one wouldn't compile.
fixed, thanks!
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Ilya Dryomov
maintainerRe: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 18 lines · Michal Hocko
Quoted 17 lines · Vlastimil Babka
Quoted 15 lines · Michal Hocko
Quoted 11 lines
Quoted 4 lines
Well, I am not opposed to
kvmalloc_arraybut I would argue that this conversion cannot introduce new overflow issues. The code would have to be broken already because even thoughkmalloc_arraychecks for the overflow but vmalloc fallback doesn't...Yeah I agree, but if some of the places were really wrong, after the conversion we won't see them anymore.
Quoted 1 line
If there is a general interest for this API I can add it.
I think it would be better, yes.
OK, fair enough. I will fold the following into the original patch. I was little bit reluctant to create kvcalloc so I've made the original callers more talkative and added |
__GFP_ZERO.
Quoted 8 lines
Quoted 6 lines
Fair enough,
Quoted 2 lines
To be honest I do not
really like how kcalloc...how kcalloc what?
how kcalloc hides the
GFP_ZEROand the name doesn't reflect that.
The userspace calloc() is specified to zero memory, so I'd say the name does reflect that.
Thanks,
Ilya
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michal Hocko
Acked-by Christian Borntraeger Acked-by Dan Williams Acked-by David Sterba Acked-by Ilya Dryomov on v3 5/6Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoIlya has noticed that I've screwed up some k[zc]alloc conversions and didn't use the kvzalloc. This is an updated patch with some acks collected on the way
---
Quoted 1 line
From
a7b89c6d0a3c685045e37740c8f97b065f37e0a4Mon Sep 17 00:00:00 2001
From: Michal Hocko <[email protected]>
Date: Wed, 4 Jan 2017 13:30:32 +0100
Subject: [PATCH] treewide: use kv[mz]alloc* rather than opencoded variants
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
--- arch/s390/kvm/kvm-s390.c | 10 ++----- crypto/lzo.c | 4 +-- drivers/acpi/apei/erst.c | 8 ++--- drivers/char/agp/generic.c | 8 +---- drivers/gpu/drm/nouveau/nouveau_gem.c | 4 +-- drivers/md/bcache/util.h | 12 ++------ drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h | 3 -- drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 25 ++-------------- drivers/net/ethernet/chelsio/cxgb3/l2t.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 31 ++++---------------- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 9 ++---- drivers/net/ethernet/mellanox/mlx4/mr.c | 9 ++---- drivers/nvdimm/dimm_devs.c | 5 +--- .../staging/lustre/lnet/libcfs/linux/linux-mem.c | 11 +------ drivers/xen/evtchn.c | 14 +-------- fs/btrfs/ctree.c | 9 ++---- fs/btrfs/ioctl.c | 9 ++---- fs/btrfs/send.c | 27 ++++++----------- fs/ceph/file.c | 9 ++---- fs/select.c | 5 +--- fs/xattr.c | 27 ++++++----------- kernel/bpf/hashtab.c | 11 ++----- lib/iov_iter.c | 5 +--- mm/frame_vector.c | 5 +--- net/ipv4/inet_hashtables.c | 6 +--- net/ipv4/tcp_metrics.c | 5 +--- net/mpls/af_mpls.c | 5 +--- net/netfilter/x_tables.c | 34 ++++++---------------- net/netfilter/xt_recent.c | 5 +--- net/sched/sch_choke.c | 5 +--- net/sched/sch_fq_codel.c | 26 ++++------------- net/sched/sch_hhf.c | 33 ++++++--------------- net/sched/sch_netem.c | 6 +--- net/sched/sch_sfq.c | 6 +--- security/keys/keyctl.c | 22 ++++---------- 35 files changed, 96 insertions(+), 319 deletions(-)
arch/s390/kvm/kvm-s390.c +2 -8
@@ -1126,10 +1126,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (args->count *sizeof (uint8_t ),GFP_KERNEL );if (!keys)return -ENOMEM ;
@@ -1171,10 +1168,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)if (args->count <1 || args->count >KVM_S390_SKEYS_MAX )return -EINVAL ; - keys =kmalloc_array (args->count,sizeof (uint8_t ), -GFP_KERNEL | __GFP_NOWARN); -if (!keys) - keys =vmalloc (sizeof (uint8_t ) * args->count); + keys =kvmalloc (sizeof (uint8_t ) * args->count,GFP_KERNEL );if (!keys)return -ENOMEM ;
crypto/lzo.c +1 -3
@@ -32,9 +32,7 @@ static void *lzo_alloc_ctx(struct crypto_scomp *tfm) {void *ctx; - ctx =kmalloc (LZO1X_MEM_COMPRESS ,GFP_KERNEL | __GFP_NOWARN); -if (!ctx) - ctx =vmalloc (LZO1X_MEM_COMPRESS ); + ctx =kvmalloc (LZO1X_MEM_COMPRESS ,GFP_KERNEL );if (!ctx)return ERR_PTR (-ENOMEM );
drivers/acpi/apei/erst.c +2 -6
@@ -513,7 +513,7 @@ static int __erst_record_id_cache_add_one(void)if (i < erst_record_id_cache.len) goto retry;if (erst_record_id_cache.len >= erst_record_id_cache.size) { -int new_size, alloc_size; +int new_size;u64 *new_entries; new_size = erst_record_id_cache.size *2 ;
@@ -524,11 +524,7 @@ static int __erst_record_id_cache_add_one(void)pr_warn (FW_WARN "too many record IDs!\n" );return 0 ; } - alloc_size = new_size *sizeof (entries[0 ]); -if (alloc_size <PAGE_SIZE ) - new_entries =kmalloc (alloc_size,GFP_KERNEL ); -else - new_entries =vmalloc (alloc_size); + new_entries =kvmalloc (new_size *sizeof (entries[0 ]),GFP_KERNEL );if (!new_entries)return -ENOMEM ; memcpy(new_entries, entries,
drivers/char/agp/generic.c +1 -7
@@ -88,13 +88,7 @@ static int agp_get_key(void)void agp_alloc_page_array (size_t size,struct agp_memory *mem) { - mem->pages =NULL ; - -if (size <=2 *PAGE_SIZE ) - mem->pages =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (mem->pages ==NULL ) { - mem->pages =vmalloc (size); - } + mem->pages =kvmalloc (size,GFP_KERNEL ); }EXPORT_SYMBOL (agp_alloc_page_array);
drivers/gpu/drm/nouveau/nouveau_gem.c +1 -3
@@ -568,9 +568,7 @@ u_memcpya(uint64_t user, unsigned nmemb, unsigned size) size *= nmemb; - mem =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!mem) - mem =vmalloc (size); + mem =kvmalloc (size,GFP_KERNEL );if (!mem)return ERR_PTR (-ENOMEM );
drivers/md/bcache/util.h +2 -10
@@ -43,11 +43,7 @@ struct closure; (heap)->used =0 ; \ (heap)->size = (_size); \ _bytes = (heap)->size *sizeof (*(heap)->data); \ - (heap)->data =NULL ; \ -if (_bytes <KMALLOC_MAX_SIZE ) \ - (heap)->data =kmalloc (_bytes, (gfp)); \ -if ((!(heap)->data) && ((gfp) &GFP_KERNEL )) \ - (heap)->data =vmalloc (_bytes); \ + (heap)->data =kvmalloc (_bytes, (gfp) &GFP_KERNEL ); \ (heap)->data; \ })
@@ -136,12 +132,8 @@ do { \ \ (fifo)->mask = _allocated_size -1 ; \ (fifo)->front = (fifo)->back =0 ; \ - (fifo)->data =NULL ; \ \ -if (_bytes <KMALLOC_MAX_SIZE ) \ - (fifo)->data =kmalloc (_bytes, (gfp)); \ -if ((!(fifo)->data) && ((gfp) &GFP_KERNEL )) \ - (fifo)->data =vmalloc (_bytes); \ + (fifo)->data =kvmalloc (_bytes, (gfp) &GFP_KERNEL ); \ (fifo)->data; \ })
drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h +0 -3
@@ -41,9 +41,6 @@#define VALIDATE_TID 1 -void *cxgb_alloc_mem (unsigned long size); -void cxgb_free_mem (void *addr); -/* * Map an ATID or STID to their entries in the corresponding TID tables. */
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c +2 -23
@@ -1152,27 +1152,6 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new, }/* -* Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. -* The allocated memory is cleared. -*/ -void *cxgb_alloc_mem (unsigned long size) -{ -void *p =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); - -if (!p) - p =vzalloc (size); -return p; -} - -/* -* Free memory allocated through t3_alloc_mem(). -*/ -void cxgb_free_mem (void *addr) -{ -kvfree (addr); -} - -/* * Allocate and initialize the TID tables. Returns 0 on success. */ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,
@@ -1182,7 +1161,7 @@ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,unsigned long size = ntids *sizeof (*t->tid_tab) + natids *sizeof (*t->atid_tab) + nstids *sizeof (*t->stid_tab); - t->tid_tab =cxgb_alloc_mem (size); + t->tid_tab =kvzalloc (size,GFP_KERNEL );if (!t->tid_tab)return -ENOMEM ;
@@ -1218,7 +1197,7 @@ static int init_tid_tabs(struct tid_info *t, unsigned int ntids,static void free_tid_maps (struct tid_info *t) { -cxgb_free_mem (t->tid_tab); +kvfree (t->tid_tab); }static inline void add_adapter (struct adapter *adap)
drivers/net/ethernet/chelsio/cxgb3/l2t.c +1 -1
@@ -444,7 +444,7 @@ struct l2t_data *t3_init_l2t(unsigned int l2t_capacity)struct l2t_data *d;int i, size =sizeof (*d) + l2t_capacity *sizeof (struct l2t_entry ); - d =cxgb_alloc_mem (size); + d =kzmalloc (size,GFP_KERNEL );if (!d)return NULL ;
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +5 -26
@@ -881,27 +881,6 @@ static int setup_sge_queues(struct adapter *adap)return err; } -/* -* Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. -* The allocated memory is cleared. -*/ -void *t4_alloc_mem (size_t size) -{ -void *p =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); - -if (!p) - p =vzalloc (size); -return p; -} - -/* -* Free memory allocated through alloc_mem(). -*/ -void t4_free_mem (void *addr) -{ -kvfree (addr); -} -static u16 cxgb_select_queue (struct net_device *dev,struct sk_buff *skb,void *accel_priv,select_queue_fallback_t fallback) {
@@ -1300,7 +1279,7 @@ static int tid_init(struct tid_info *t) max_ftids *sizeof (*t->ftid_tab) + ftid_bmap_size *sizeof (long ); - t->tid_tab =t4_alloc_mem (size); + t->tid_tab =kvzalloc (size,GFP_KERNEL );if (!t->tid_tab)return -ENOMEM ;
@@ -3416,7 +3395,7 @@ static int adap_init0(struct adapter *adap)/* allocate memory to read the header of the firmware on the * card */ - card_fw =t4_alloc_mem (sizeof (*card_fw)); + card_fw =kvzalloc (sizeof (*card_fw),GFP_KERNEL );/* Get FW from from /lib/firmware/ */ ret = request_firmware(&fw, fw_info->fw_mod_name,
@@ -3436,7 +3415,7 @@ static int adap_init0(struct adapter *adap)/* Cleaning up */ release_firmware (fw); -t4_free_mem (card_fw); +kvfree (card_fw);if (ret <0 ) goto bye;
@@ -4432,9 +4411,9 @@ static void free_some_resources(struct adapter *adapter) {unsigned int i; -t4_free_mem (adapter->l2t); +kvfree (adapter->l2t);t4_cleanup_sched (adapter); -t4_free_mem (adapter->tids.tid_tab); +kvfree (adapter->tids.tid_tab);cxgb4_cleanup_tc_u32 (adapter);kfree (adapter->sge.egr_map);kfree (adapter->sge.ingr_map);
drivers/net/ethernet/mellanox/mlx4/en_tx.c +3 -6
@@ -70,13 +70,10 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, ring->full_size = ring->size -HEADROOM -MAX_DESC_TXBBS ; tmp = size *sizeof (struct mlx4_en_tx_info ); - ring->tx_info =kmalloc_node (tmp,GFP_KERNEL | __GFP_NOWARN, node); + ring->tx_info =kvmalloc_node (tmp,GFP_KERNEL , node);if (!ring->tx_info) { - ring->tx_info =vmalloc (tmp); -if (!ring->tx_info) { - err = -ENOMEM ; - goto err_ring; - } + err = -ENOMEM ; + goto err_ring; } en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",
drivers/net/ethernet/mellanox/mlx4/mr.c +3 -6
@@ -115,12 +115,9 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order)for (i =0 ; i <= buddy->max_order; ++i) { s =BITS_TO_LONGS (1 << (buddy->max_order - i)); - buddy->bits[i] =kcalloc (s,sizeof (long ),GFP_KERNEL | __GFP_NOWARN); -if (!buddy->bits[i]) { - buddy->bits[i] =vzalloc (s *sizeof (long )); -if (!buddy->bits[i]) - goto err_out_free; - } + buddy->bits[i] =kvzalloc (s *sizeof (long ),GFP_KERNEL ); +if (!buddy->bits[i]) + goto err_out_free; }set_bit (0 , buddy->bits[buddy->max_order]);
drivers/nvdimm/dimm_devs.c +1 -4
@@ -102,10 +102,7 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)return -ENXIO ; } - ndd->data =kmalloc (ndd->nsarea.config_size,GFP_KERNEL ); -if (!ndd->data) - ndd->data =vmalloc (ndd->nsarea.config_size); - + ndd->data =kvmalloc (ndd->nsarea.config_size,GFP_KERNEL );if (!ndd->data)return -ENOMEM ;
drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c +1 -10
@@ -45,15 +45,6 @@ EXPORT_SYMBOL(libcfs_kvzalloc);void *libcfs_kvzalloc_cpt (struct cfs_cpt_table *cptab,int cpt,size_t size,gfp_t flags) { -void *ret; - - ret =kzalloc_node (size, flags | __GFP_NOWARN, -cfs_cpt_spread_node (cptab, cpt)); -if (!ret) { -WARN_ON (!(flags & (__GFP_FS | __GFP_HIGH))); - ret =vmalloc_node (size,cfs_cpt_spread_node (cptab, cpt)); - } - -return ret; +return kvzalloc_node (size, flags,cfs_cpt_spread_node (cptab, cpt)); }EXPORT_SYMBOL (libcfs_kvzalloc_cpt);
drivers/xen/evtchn.c +1 -13
@@ -87,18 +87,6 @@ struct user_evtchn {bool enabled; }; -static evtchn_port_t *evtchn_alloc_ring (unsigned int size) -{ -evtchn_port_t *ring; -size_t s = size *sizeof (*ring); - - ring =kmalloc (s,GFP_KERNEL ); -if (!ring) - ring =vmalloc (s); - -return ring; -} -static void evtchn_free_ring (evtchn_port_t *ring) {kvfree (ring);
@@ -334,7 +322,7 @@ static int evtchn_resize_ring(struct per_user_data *u)else new_size =2 * u->ring_size; - new_ring =evtchn_alloc_ring (new_size); + new_ring =kvmalloc (new_size *sizeof (*new_ring),GFP_KERNEL );if (!new_ring)return -ENOMEM ;
fs/btrfs/ctree.c +3 -6
@@ -5391,13 +5391,10 @@ int btrfs_compare_trees(struct btrfs_root *left_root, goto out; } - tmp_buf =kmalloc (fs_info->nodesize,GFP_KERNEL | __GFP_NOWARN); + tmp_buf =kvmalloc (fs_info->nodesize,GFP_KERNEL );if (!tmp_buf) { - tmp_buf =vmalloc (fs_info->nodesize); -if (!tmp_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } left_path->search_commit_root =1 ;
fs/btrfs/ioctl.c +3 -6
@@ -3547,12 +3547,9 @@ static int btrfs_clone(struct inode *src, struct inode *inode,u64 last_dest_end = destoff; ret = -ENOMEM ; - buf =kmalloc (fs_info->nodesize,GFP_KERNEL | __GFP_NOWARN); -if (!buf) { - buf =vmalloc (fs_info->nodesize); -if (!buf) -return ret; - } + buf =kvmalloc (fs_info->nodesize,GFP_KERNEL ); +if (!buf) +return ret; path =btrfs_alloc_path ();if (!path) {
fs/btrfs/send.c +9 -18
@@ -6242,22 +6242,16 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) sctx->clone_roots_cnt = arg->clone_sources_count; sctx->send_max_size =BTRFS_SEND_BUF_SIZE ; - sctx->send_buf =kmalloc (sctx->send_max_size,GFP_KERNEL | __GFP_NOWARN); + sctx->send_buf =kvmalloc (sctx->send_max_size,GFP_KERNEL );if (!sctx->send_buf) { - sctx->send_buf =vmalloc (sctx->send_max_size); -if (!sctx->send_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } - sctx->read_buf =kmalloc (BTRFS_SEND_READ_SIZE ,GFP_KERNEL | __GFP_NOWARN); + sctx->read_buf =kvmalloc (BTRFS_SEND_READ_SIZE ,GFP_KERNEL );if (!sctx->read_buf) { - sctx->read_buf =vmalloc (BTRFS_SEND_READ_SIZE ); -if (!sctx->read_buf) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } sctx->pending_dir_moves =RB_ROOT ;
@@ -6278,13 +6272,10 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) alloc_size = arg->clone_sources_count *sizeof (*arg->clone_sources);if (arg->clone_sources_count) { - clone_sources_tmp =kmalloc (alloc_size,GFP_KERNEL | __GFP_NOWARN); + clone_sources_tmp =kvmalloc (alloc_size,GFP_KERNEL );if (!clone_sources_tmp) { - clone_sources_tmp =vmalloc (alloc_size); -if (!clone_sources_tmp) { - ret = -ENOMEM ; - goto out; - } + ret = -ENOMEM ; + goto out; } ret = copy_from_user(clone_sources_tmp, arg->clone_sources,
fs/ceph/file.c +3 -6
@@ -74,12 +74,9 @@ dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes, align = (unsigned long )(it->iov->iov_base + it->iov_offset) & (PAGE_SIZE -1 ); npages =calc_pages_for (align, nbytes); - pages =kmalloc (sizeof (*pages) * npages,GFP_KERNEL ); -if (!pages) { - pages =vmalloc (sizeof (*pages) * npages); -if (!pages) -return ERR_PTR (-ENOMEM ); - } + pages =kvmalloc (sizeof (*pages) * npages,GFP_KERNEL ); +if (!pages) +return ERR_PTR (-ENOMEM );for (idx =0 ; idx < npages; ) {size_t start;
fs/select.c +1 -4
@@ -586,10 +586,7 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, goto out_nofds; alloc_size =6 * size; - bits =kmalloc (alloc_size,GFP_KERNEL |__GFP_NOWARN); -if (!bits && alloc_size >PAGE_SIZE ) - bits =vmalloc (alloc_size); - + bits =kvmalloc (alloc_size,GFP_KERNEL );if (!bits) goto out_nofds; }
fs/xattr.c +9 -18
@@ -431,12 +431,9 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,if (size) {if (size >XATTR_SIZE_MAX )return -E2BIG ; - kvalue =kmalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!kvalue) { - kvalue =vmalloc (size); -if (!kvalue) -return -ENOMEM ; - } + kvalue =kvmalloc (size,GFP_KERNEL ); +if (!kvalue) +return -ENOMEM ;if (copy_from_user (kvalue, value, size)) { error = -EFAULT ; goto out;
@@ -528,12 +525,9 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,if (size) {if (size >XATTR_SIZE_MAX ) size =XATTR_SIZE_MAX ; - kvalue =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!kvalue) { - kvalue =vmalloc (size); -if (!kvalue) -return -ENOMEM ; - } + kvalue =kzmalloc (size,GFP_KERNEL ); +if (!kvalue) +return -ENOMEM ; } error =vfs_getxattr (d, kname, kvalue, size);
@@ -611,12 +605,9 @@ listxattr(struct dentry *d, char __user *list, size_t size)if (size) {if (size >XATTR_LIST_MAX ) size =XATTR_LIST_MAX ; - klist =kmalloc (size, __GFP_NOWARN |GFP_KERNEL ); -if (!klist) { - klist =vmalloc (size); -if (!klist) -return -ENOMEM ; - } + klist =kvmalloc (size,GFP_KERNEL ); +if (!klist) +return -ENOMEM ; } error =vfs_listxattr (d, klist, size);
kernel/bpf/hashtab.c +3 -8
@@ -320,14 +320,9 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) goto free_htab; err = -ENOMEM ; - htab->buckets =kmalloc_array (htab->n_buckets,sizeof (struct bucket ), -GFP_USER | __GFP_NOWARN); - -if (!htab->buckets) { - htab->buckets =vmalloc (htab->n_buckets *sizeof (struct bucket )); -if (!htab->buckets) - goto free_htab; - } + htab->buckets =kvmalloc (htab->n_buckets *sizeof (struct bucket ),GFP_USER ); +if (!htab->buckets) + goto free_htab;for (i =0 ; i < htab->n_buckets; i++) {INIT_HLIST_HEAD (&htab->buckets[i].head);
lib/iov_iter.c +1 -4
@@ -957,10 +957,7 @@ EXPORT_SYMBOL(iov_iter_get_pages);static struct page **get_pages_array (size_t n) { -struct page **p =kmalloc (n *sizeof (struct page *),GFP_KERNEL ); -if (!p) - p =vmalloc (n *sizeof (struct page *)); -return p; +return kvmalloc (n *sizeof (struct page *),GFP_KERNEL ); } static ssize_t pipe_get_pages_alloc(struct iov_iter *i,
mm/frame_vector.c +1 -4
@@ -200,10 +200,7 @@ struct frame_vector *frame_vector_create(unsigned int nr_frames)* Avoid higher order allocations, use vmalloc instead. It should * be rare anyway. */ -if (size <=PAGE_SIZE ) - vec =kmalloc (size,GFP_KERNEL ); -else - vec =vmalloc (size); + vec =kvmalloc (size,GFP_KERNEL );if (!vec)return NULL ; vec->nr_allocated = nr_frames;
net/ipv4/inet_hashtables.c +1 -5
@@ -687,11 +687,7 @@ int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo)/* no more locks than number of hash buckets */ nblocks =min (nblocks, hashinfo->ehash_mask +1 ); - hashinfo->ehash_locks =kmalloc_array (nblocks, locksz, -GFP_KERNEL | __GFP_NOWARN); -if (!hashinfo->ehash_locks) - hashinfo->ehash_locks =vmalloc (nblocks * locksz); - + hashinfo->ehash_locks =kvmalloc (nblocks * locksz,GFP_KERNEL );if (!hashinfo->ehash_locks)return -ENOMEM ;
net/ipv4/tcp_metrics.c +1 -4
@@ -1155,10 +1155,7 @@ static int __net_init tcp_net_metrics_init(struct net *net) tcp_metrics_hash_log =order_base_2 (slots); size =sizeof (struct tcpm_hash_bucket ) << tcp_metrics_hash_log; - tcp_metrics_hash =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!tcp_metrics_hash) - tcp_metrics_hash =vzalloc (size); - + tcp_metrics_hash =kvzalloc (size,GFP_KERNEL );if (!tcp_metrics_hash)return -ENOMEM ;
net/mpls/af_mpls.c +1 -4
@@ -1525,10 +1525,7 @@ static int resize_platform_label_table(struct net *net, size_t limit)unsigned index;if (size) { - labels =kzalloc (size,GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); -if (!labels) - labels =vzalloc (size); - + labels =kvzalloc (size,GFP_KERNEL );if (!labels) goto nolabels; }
net/netfilter/x_tables.c +9 -25
@@ -712,17 +712,11 @@ EXPORT_SYMBOL(xt_check_entry_offsets);*/ unsigned int *xt_alloc_entry_offsets (unsigned int size) { -unsigned int *off; - - off =kcalloc (size,sizeof (unsigned int ),GFP_KERNEL | __GFP_NOWARN); - -if (off) -return off; -if (size < (SIZE_MAX /sizeof (unsigned int ))) - off =vmalloc (size *sizeof (unsigned int )); +return kvzalloc (size *sizeof (unsigned int ),GFP_KERNEL ); + +return NULL ; -return off; }EXPORT_SYMBOL (xt_alloc_entry_offsets);
@@ -956,15 +950,9 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size)if ((SMP_ALIGN (size) >>PAGE_SHIFT ) +2 > totalram_pages)return NULL ; -if (sz <= (PAGE_SIZE <<PAGE_ALLOC_COSTLY_ORDER )) - info =kmalloc (sz,GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); -if (!info) { - info =__vmalloc (sz,GFP_KERNEL | __GFP_NOWARN | - __GFP_NORETRY | __GFP_HIGHMEM, -PAGE_KERNEL ); -if (!info) -return NULL ; - } + info =kvmalloc (sz,GFP_KERNEL ); +if (!info) +return NULL ;memset (info,0 ,sizeof (*info)); info->size = size;return info;
@@ -1066,7 +1054,7 @@ static int xt_jumpstack_alloc(struct xt_table_info *i) size =sizeof (void **) * nr_cpu_ids;if (size >PAGE_SIZE ) - i->jumpstack =vzalloc (size); + i->jumpstack =kvzalloc (size,GFP_KERNEL );else i->jumpstack =kzalloc (size,GFP_KERNEL );if (i->jumpstack ==NULL )
@@ -1088,12 +1076,8 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)*/ size =sizeof (void *) * i->stacksize *2u ;for_each_possible_cpu (cpu) { -if (size >PAGE_SIZE ) - i->jumpstack[cpu] =vmalloc_node (size, -cpu_to_node (cpu)); -else - i->jumpstack[cpu] =kmalloc_node (size, -GFP_KERNEL ,cpu_to_node (cpu)); + i->jumpstack[cpu] =kvmalloc_node (size,GFP_KERNEL , +cpu_to_node (cpu));if (i->jumpstack[cpu] ==NULL )/* * Freeing will be done later on by the callers. The
net/netfilter/xt_recent.c +1 -4
@@ -388,10 +388,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par, } sz =sizeof (*t) +sizeof (t->iphash[0 ]) * ip_list_hash_size; -if (sz <=PAGE_SIZE ) - t =kzalloc (sz,GFP_KERNEL ); -else - t =vzalloc (sz); + t =kvzalloc (sz,GFP_KERNEL );if (t ==NULL ) { ret = -ENOMEM ; goto out;
net/sched/sch_choke.c +1 -4
@@ -431,10 +431,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)if (mask != q->tab_mask) {struct sk_buff **ntab; - ntab =kcalloc (mask +1 ,sizeof (struct sk_buff *), -GFP_KERNEL | __GFP_NOWARN); -if (!ntab) - ntab =vzalloc ((mask +1 ) *sizeof (struct sk_buff *)); + ntab =kvzalloc ((mask +1 ) *sizeof (struct sk_buff *),GFP_KERNEL );if (!ntab)return -ENOMEM ;
net/sched/sch_fq_codel.c +6 -20
@@ -449,27 +449,13 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt)return 0 ; } -static void *fq_codel_zalloc (size_t sz) -{ -void *ptr =kzalloc (sz,GFP_KERNEL | __GFP_NOWARN); - -if (!ptr) - ptr =vzalloc (sz); -return ptr; -} - -static void fq_codel_free (void *addr) -{ -kvfree (addr); -} -static void fq_codel_destroy (struct Qdisc *sch) {struct fq_codel_sched_data *q =qdisc_priv (sch);tcf_destroy_chain (&q->filter_list); -fq_codel_free (q->backlogs); -fq_codel_free (q->flows); +kvfree (q->backlogs); +kvfree (q->flows); }static int fq_codel_init (struct Qdisc *sch,struct nlattr *opt)
@@ -497,13 +483,13 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) }if (!q->flows) { - q->flows =fq_codel_zalloc (q->flows_cnt * -sizeof (struct fq_codel_flow )); + q->flows =kvzalloc (q->flows_cnt * +sizeof (struct fq_codel_flow ),GFP_KERNEL );if (!q->flows)return -ENOMEM ; - q->backlogs =fq_codel_zalloc (q->flows_cnt *sizeof (u32)); + q->backlogs =kvzalloc (q->flows_cnt *sizeof (u32),GFP_KERNEL );if (!q->backlogs) { -fq_codel_free (q->flows); +kvfree (q->flows);return -ENOMEM ; }for (i =0 ; i < q->flows_cnt; i++) {
net/sched/sch_hhf.c +9 -24
@@ -467,29 +467,14 @@ static void hhf_reset(struct Qdisc *sch)rtnl_kfree_skbs (skb, skb); } -static void *hhf_zalloc (size_t sz) -{ -void *ptr =kzalloc (sz,GFP_KERNEL | __GFP_NOWARN); - -if (!ptr) - ptr =vzalloc (sz); - -return ptr; -} - -static void hhf_free (void *addr) -{ -kvfree (addr); -} -static void hhf_destroy (struct Qdisc *sch) {int i;struct hhf_sched_data *q =qdisc_priv (sch);for (i =0 ; i <HHF_ARRAYS_CNT ; i++) { -hhf_free (q->hhf_arrays[i]); -hhf_free (q->hhf_valid_bits[i]); +kvfree (q->hhf_arrays[i]); +kvfree (q->hhf_valid_bits[i]); }for (i =0 ; i <HH_FLOWS_CNT ; i++) {
@@ -503,7 +488,7 @@ static void hhf_destroy(struct Qdisc *sch)kfree (flow); } } -hhf_free (q->hh_flows); +kvfree (q->hh_flows); }static const struct nla_policy hhf_policy[TCA_HHF_MAX +1 ] = {
@@ -609,8 +594,8 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt)if (!q->hh_flows) {/* Initialize heavy-hitter flow table. */ - q->hh_flows =hhf_zalloc (HH_FLOWS_CNT * -sizeof (struct list_head )); + q->hh_flows =kvzalloc (HH_FLOWS_CNT * +sizeof (struct list_head ),GFP_KERNEL );if (!q->hh_flows)return -ENOMEM ;for (i =0 ; i <HH_FLOWS_CNT ; i++)
@@ -624,8 +609,8 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt)/* Initialize heavy-hitter filter arrays. */ for (i =0 ; i <HHF_ARRAYS_CNT ; i++) { - q->hhf_arrays[i] =hhf_zalloc (HHF_ARRAYS_LEN * -sizeof (u32)); + q->hhf_arrays[i] =kvzalloc (HHF_ARRAYS_LEN * +sizeof (u32),GFP_KERNEL );if (!q->hhf_arrays[i]) {hhf_destroy (sch);return -ENOMEM ;
@@ -635,8 +620,8 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt)/* Initialize valid bits of heavy-hitter filter arrays. */ for (i =0 ; i <HHF_ARRAYS_CNT ; i++) { - q->hhf_valid_bits[i] =hhf_zalloc (HHF_ARRAYS_LEN / -BITS_PER_BYTE ); + q->hhf_valid_bits[i] =kvzalloc (HHF_ARRAYS_LEN / +BITS_PER_BYTE ,GFP_KERNEL );if (!q->hhf_valid_bits[i]) {hhf_destroy (sch);return -ENOMEM ;
net/sched/sch_netem.c +1 -5
@@ -692,15 +692,11 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)spinlock_t *root_lock;struct disttable *d;int i; -size_t s;if (n >NETEM_DIST_MAX )return -EINVAL ; - s =sizeof (struct disttable ) + n *sizeof (s16); - d =kmalloc (s,GFP_KERNEL | __GFP_NOWARN); -if (!d) - d =vmalloc (s); + d =kvmalloc (sizeof (struct disttable ) + n *sizeof (s16),GFP_KERNEL );if (!d)return -ENOMEM ;
net/sched/sch_sfq.c +1 -5
@@ -684,11 +684,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)static void *sfq_alloc (size_t sz) { -void *ptr =kmalloc (sz,GFP_KERNEL | __GFP_NOWARN); - -if (!ptr) - ptr =vmalloc (sz); -return ptr; +return kvmalloc (sz,GFP_KERNEL ); }static void sfq_free (void *addr)
security/keys/keyctl.c +6 -16
@@ -99,14 +99,9 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,if (_payload) { ret = -ENOMEM ; - payload =kmalloc (plen,GFP_KERNEL | __GFP_NOWARN); -if (!payload) { -if (plen <=PAGE_SIZE ) - goto error2; - payload =vmalloc (plen); -if (!payload) - goto error2; - } + payload =kvmalloc (plen,GFP_KERNEL ); +if (!payload) + goto error2; ret = -EFAULT ;if (copy_from_user (payload, _payload, plen) !=0 )
@@ -1064,14 +1059,9 @@ long keyctl_instantiate_key_common(key_serial_t id,if (from) { ret = -ENOMEM ; - payload =kmalloc (plen,GFP_KERNEL ); -if (!payload) { -if (plen <=PAGE_SIZE ) - goto error; - payload =vmalloc (plen); -if (!payload) - goto error; - } + payload =kvmalloc (plen,GFP_KERNEL ); +if (!payload) + goto error; ret = -EFAULT ;if (!copy_from_iter_full (payload, plen, from))
Signature · 11 lines
2.11.0 -- Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 9 lines · Michal Hocko
Ilya has noticed that I've screwed up some k[zc]alloc conversions and didn't use the kvzalloc. This is an updated patch with some acks collected on the way
---
Froma7b89c6d0a3c685045e37740c8f97b065f37e0a4Mon Sep 17 00:00:00 2001
From: Michal Hocko <[email protected]>
Date: Wed, 4 Jan 2017 13:30:32 +0100
Subject: [PATCH] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 4 lines
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to
Isn't this "requests <= 32kB" because allocation requests for 33kB will be rounded up to 64kB?
Same for "smaller than 64kB" in PATCH 6/6. But strictly speaking, isn't it bogus to refer actual size because PAGE_SIZE is not always 4096?
---------- arch/ia64/include/asm/page.h ---------- /*
* PAGE_SHIFT determines the actual kernel page size. */
#if defined(CONFIG_IA64_PAGE_SIZE_4KB)
# define PAGE_SHIFT 12 #elif defined(CONFIG_IA64_PAGE_SIZE_8KB) # define PAGE_SHIFT 13 #elif defined(CONFIG_IA64_PAGE_SIZE_16KB) # define PAGE_SHIFT 14 #elif defined(CONFIG_IA64_PAGE_SIZE_64KB) # define PAGE_SHIFT 16 #else # error Unsupported page size! #endif
#define PAGE_SIZE (__IA64_UL_CONST(1) << PAGE_SHIFT)
Quoted 8 lines
satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 10 lines · Tetsuo Handa
Quoted 9 lines · Michal Hocko
Ilya has noticed that I've screwed up some k[zc]alloc conversions and didn't use the kvzalloc. This is an updated patch with some acks collected on the way
---
Froma7b89c6d0a3c685045e37740c8f97b065f37e0a4Mon Sep 17 00:00:00 2001
From: Michal Hocko <[email protected]>
Date: Wed, 4 Jan 2017 13:30:32 +0100
Subject: [PATCH] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 7 lines
Quoted 4 lines
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to
Isn't this "requests <= 32kB" because allocation requests for 33kB will be rounded up to 64kB?
Yes
Quoted 2 lines
Same for "smaller than 64kB" in PATCH 6/6. But strictly speaking, isn't it bogus to refer actual size because
PAGE_SIZEis not always 4096?
This is just an example and I didn't want to pull PAGE_ALLOC_COSTLY_ORDER here. So I've instead fixed the wording to:
"
E.g. allocation requests <= 32kB (with 4kB pages) are basically never failing and invoke OOM killer to satisfy the allocation.
"
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoQuoted 25 lines
drivers/xen/evtchn.c +0
-12@@ -87,18 +87,6 @@ struct user_evtchn {bool enabled; }; -static evtchn_port_t *evtchn_alloc_ring (unsigned int size) -{ -evtchn_port_t *ring; -size_t s = size *sizeof (*ring); - - ring =kmalloc (s,GFP_KERNEL ); -if (!ring) - ring =vmalloc (s); - -return ring; -} -static void evtchn_free_ring (evtchn_port_t *ring) {kvfree (ring);
drivers/xen/evtchn.c static int evtchn_resize_ring(struct per_user_data *u) · line 328
Quoted 8 lines
drivers/xen/evtchn.c +1
-1@@ -334,7 +322,7 @@ static int evtchn_resize_ring(struct per_user_data *u)else new_size =2 * u->ring_size; - new_ring =evtchn_alloc_ring (new_size); + new_ring =kvmalloc (new_size *sizeof (*new_ring),GFP_KERNEL );if (!new_ring)return -ENOMEM ;
Xen bits:
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoQuoted 15 lines · Michal Hocko
From: Michal Hocko <[email protected]>
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
Quoted 4 lines
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
Signed-off-by Michal Hocko <[email protected]>
Lustre part can be
[snip]
Quoted 11 lines
drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c +0
-3@@ -45,15 +45,6 @@ EXPORT_SYMBOL(libcfs_kvzalloc);void *libcfs_kvzalloc_cpt (struct cfs_cpt_table *cptab,int cpt,size_t size,gfp_t flags) { -void *ret; - - ret = kzalloc_node(size, flags | __GFP_NOWARN,
drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c EXPORT_SYMBOL(libcfs_kvzalloc); · line 50
Quoted 10 lines
drivers/staging/lustre/lnet/libcfs/linux/linux-mem.c +1
-7- cfs_cpt_spread_node(cptab, cpt)); -if (!ret) { -WARN_ON (!(flags & (__GFP_FS | __GFP_HIGH))); - ret =vmalloc_node (size,cfs_cpt_spread_node (cptab, cpt)); - } - -return ret; +return kvzalloc_node (size, flags,cfs_cpt_spread_node (cptab, cpt)); }EXPORT_SYMBOL (libcfs_kvzalloc_cpt);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoQuoted 70 lines · Michal Hocko
From: Michal Hocko <[email protected]>
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
Cc Martin Schwidefsky <[email protected]>Cc Heiko Carstens <[email protected]>Cc Herbert Xu <[email protected]>Cc Anton Vorontsov <[email protected]>Cc Colin Cross <[email protected]>Cc Kees Cook <[email protected]>Cc Tony Luck <[email protected]>Cc "Rafael J. Wysocki" <[email protected]>Cc Ben Skeggs <[email protected]>Cc Kent Overstreet <[email protected]>Cc Santosh Raspatur <[email protected]>Cc Hariprasad S <[email protected]>Cc Tariq Toukan <[email protected]>Cc Yishai Hadas <[email protected]>Cc Dan Williams <[email protected]>Cc Oleg Drokin <[email protected]>Cc Andreas Dilger <[email protected]>Cc Boris Ostrovsky <[email protected]>Cc David Sterba <[email protected]>Cc "Yan, Zheng" <[email protected]>Cc Ilya Dryomov <[email protected]>Cc Alexander Viro <[email protected]>Cc Alexei Starovoitov <[email protected]>Cc Eric Dumazet <[email protected]>Signed-off-by Michal Hocko <[email protected]>--- arch/s390/kvm/kvm-s390.c | 10 ++----- crypto/lzo.c | 4 +-- drivers/acpi/apei/erst.c | 8 ++--- drivers/char/agp/generic.c | 8 +---- drivers/gpu/drm/nouveau/nouveau_gem.c | 4 +-- drivers/md/bcache/util.h | 12 ++------ drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h | 3 -- drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 25 ++-------------- drivers/net/ethernet/chelsio/cxgb3/l2t.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 31 ++++---------------- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 9 ++---- drivers/net/ethernet/mellanox/mlx4/mr.c | 9 ++---- drivers/nvdimm/dimm_devs.c | 5 +--- .../staging/lustre/lnet/libcfs/linux/linux-mem.c | 11 +------ drivers/xen/evtchn.c | 14 +-------- fs/btrfs/ctree.c | 9 ++---- fs/btrfs/ioctl.c | 9 ++---- fs/btrfs/send.c | 27 ++++++----------- fs/ceph/file.c | 9 ++---- fs/select.c | 5 +--- fs/xattr.c | 27 ++++++----------- kernel/bpf/hashtab.c | 11 ++----- lib/iov_iter.c | 5 +--- mm/frame_vector.c | 5 +--- net/ipv4/inet_hashtables.c | 6 +--- net/ipv4/tcp_metrics.c | 5 +--- net/mpls/af_mpls.c | 5 +--- net/netfilter/x_tables.c | 34 ++++++----------------
Quoted 8 lines
net/netfilter/xt_recent.c | 5 +--- net/sched/sch_choke.c | 5 +--- net/sched/sch_fq_codel.c | 26 ++++------------- net/sched/sch_hhf.c | 33 ++++++--------------- net/sched/sch_netem.c | 6 +--- net/sched/sch_sfq.c | 6 +--- security/keys/keyctl.c | 22 ++++---------- 35 files changed, 96 insertions(+), 319 deletions(-)
Hi Michal,
I don't see mlx5_vzalloc in the changed list. Any reason why did you skip it?
881 static inline void *mlx5_vzalloc(unsigned long size) 882 {
883 void *rtn;
884
885 rtn = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
886 if (!rtn)
887 rtn = vzalloc(size);
888 return rtn;
889 }
Thanks
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
On Sat 14-01-17 12:56:32, Leon Romanovsky wrote:
[...]
Quoted 4 lines
Hi Michal,
I don't see
mlx5_vzallocin the changed list. Any reason why did you skip it?
Quoted 9 lines
881 static inline void *mlx5_vzalloc(unsigned long size) 882 {
883 void *rtn;
884
885 rtn =kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
886 if (!rtn)
887 rtn = vzalloc(size);
888 return rtn;
889 }
No reason to skip it, I just didn't see it. I will fold the following in if you are OK with it
---
include/linux/mlx5/driver.h +1 -6
@@ -874,12 +874,7 @@ static inline u16 cmdif_rev(struct mlx5_core_dev *dev)static inline void *mlx5_vzalloc (unsigned long size) { -void *rtn; - - rtn =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!rtn) - rtn =vzalloc (size); -return rtn; +return kvzalloc (GFP_KERNEL , size); }static inline u32 mlx5_base_mkey (const u32 key)
Signature · 2 lines
Michal Hocko SUSE Labs
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
Quoted 16 lines · Michal Hocko
On Sat 14-01-17 12:56:32, Leon Romanovsky wrote:
[...]Quoted 4 lines
Hi Michal,
I don't see
mlx5_vzallocin the changed list. Any reason why did you skip it?Quoted 9 lines
881 static inline void *mlx5_vzalloc(unsigned long size) 882 {
883 void *rtn;
884
885 rtn =kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
886 if (!rtn)
887 rtn = vzalloc(size);
888 return rtn;
889 }
Quoted 2 lines
No reason to skip it, I just didn't see it. I will fold the following in if you are OK with it
Sure, no problem.
Once, the patch set is accepted, we (Mellanox) will get rid of mlx5_vzalloc().
Thanks
Quoted 29 lines
---
include/linux/mlx5/driver.h +1
-7@@ -874,12 +874,7 @@ static inline u16 cmdif_rev(struct mlx5_core_dev *dev)static inline void *mlx5_vzalloc (unsigned long size) { -void *rtn; - - rtn =kzalloc (size,GFP_KERNEL | __GFP_NOWARN); -if (!rtn) - rtn =vzalloc (size); -return rtn; +return kvzalloc (GFP_KERNEL , size); }static inline u32 mlx5_base_mkey (const u32 key) --Michal Hocko
SUSE Labs--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants
In reply to Michal HockoQuoted 41 lines · Michal Hocko
From: Michal Hocko <[email protected]>
There are many code paths opencoding kvmalloc. Let's use the helper instead. The main difference to kvmalloc is that those users are usually not considering all the aspects of the memory allocator. E.g. allocation requests < 64kB are basically never failing and invoke OOM killer to satisfy the allocation. This sounds too disruptive for something that has a reasonable fallback - the vmalloc. On the other hand those requests might fallback to vmalloc even when the memory allocator would succeed after several more reclaim/compaction attempts previously. There is no guarantee something like that happens though.
This patch converts many of those places to kv[mz]alloc* helpers because they are more conservative.
Cc Martin Schwidefsky <[email protected]>Cc Heiko Carstens <[email protected]>Cc Herbert Xu <[email protected]>Cc Anton Vorontsov <[email protected]>Cc Colin Cross <[email protected]>Cc Kees Cook <[email protected]>Cc Tony Luck <[email protected]>Cc "Rafael J. Wysocki" <[email protected]>Cc Ben Skeggs <[email protected]>Cc Kent Overstreet <[email protected]>Cc Santosh Raspatur <[email protected]>Cc Hariprasad S <[email protected]>Cc Tariq Toukan <[email protected]>Cc Yishai Hadas <[email protected]>Cc Dan Williams <[email protected]>Cc Oleg Drokin <[email protected]>Cc Andreas Dilger <[email protected]>Cc Boris Ostrovsky <[email protected]>Cc David Sterba <[email protected]>Cc "Yan, Zheng" <[email protected]>Cc Ilya Dryomov <[email protected]>Cc Alexander Viro <[email protected]>Cc Alexei Starovoitov <[email protected]>Cc Eric Dumazet <[email protected]>Signed-off-by Michal Hocko <[email protected]>
Quoted 1 line
---
For the mlx4 parts.
Regards.
Tariq
RFC PATCH v3 6/6 net: use kvmalloc with __GFP_REPEAT rather than open coded variant
In reply to Michal HockoFrom: Michal Hocko <[email protected]>
fq_alloc_node, alloc_netdev_mqs and netif_alloc* open code kmalloc with vmalloc fallback. Use the kvmalloc variant instead. Keep the __GFP_REPEAT flag based on explanation from Eric:
"
At the time, tests on the hardware I had in my labs showed that vmalloc() could deliver pages spread all over the memory and that was a small penalty (once memory is fragmented enough, not at boot time) "
The way how the code is constructed means, however, that we prefer to go and hit the OOM killer before we fall back to the vmalloc for requests smaller than 64kB in the current code. This is rather disruptive for something that can be achived with the fallback. On the other hand __GFP_REPEAT doesn't have any useful semantic for these requests. So the effect of this patch is that requests smaller than 64kB will fallback to vmalloc esier now.
--- net/core/dev.c | 24 +++++++++--------------- net/sched/sch_fq.c | 12 +----------- 2 files changed, 10 insertions(+), 26 deletions(-)
net/core/dev.c +9 -15
@@ -7111,12 +7111,10 @@ static int netif_alloc_rx_queues(struct net_device *dev)BUG_ON (count <1 ); - rx =kzalloc (sz,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!rx) { - rx =vzalloc (sz); -if (!rx) -return -ENOMEM ; - } + rx =kvzalloc (sz,GFP_KERNEL | __GFP_REPEAT); +if (!rx) +return -ENOMEM ; + dev->_rx = rx;for (i =0 ; i < count; i++)
@@ -7153,12 +7151,10 @@ static int netif_alloc_netdev_queues(struct net_device *dev)if (count <1 || count >0xffff )return -EINVAL ; - tx =kzalloc (sz,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!tx) { - tx =vzalloc (sz); -if (!tx) -return -ENOMEM ; - } + tx =kvzalloc (sz,GFP_KERNEL | __GFP_REPEAT); +if (!tx) +return -ENOMEM ; + dev->_tx = tx;netdev_for_each_tx_queue (dev, netdev_init_one_queue,NULL );
@@ -7691,9 +7687,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,/* ensure 32-byte alignment of whole construct */ alloc_size +=NETDEV_ALIGN -1 ; - p =kzalloc (alloc_size,GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); -if (!p) - p =vzalloc (alloc_size); + p =kvzalloc (alloc_size,GFP_KERNEL | __GFP_REPEAT);if (!p)return NULL ;
net/sched/sch_fq.c +1 -11
@@ -624,16 +624,6 @@ static void fq_rehash(struct fq_sched_data *q, q->stat_gc_flows += fcnt; } -static void *fq_alloc_node (size_t sz,int node) -{ -void *ptr; - - ptr =kmalloc_node (sz,GFP_KERNEL | __GFP_REPEAT | __GFP_NOWARN, node); -if (!ptr) - ptr =vmalloc_node (sz, node); -return ptr; -} -static void fq_free (void *addr) {kvfree (addr);
@@ -650,7 +640,7 @@ static int fq_resize(struct Qdisc *sch, u32 log)return 0 ;/* If XPS was setup, we can allocate memory on right NUMA node */ - array =fq_alloc_node (sizeof (struct rb_root ) << log, + array =kvmalloc_node (sizeof (struct rb_root ) << log,GFP_KERNEL | __GFP_REPEAT,netdev_queue_numa_node_read (sch->dev_queue));if (!array)return -ENOMEM ;
Signature · 7 lines
2.11.0 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 22 lines · Michal Hocko
Hi,
this has been previously posted as a single patch [1] but later on more built on top. It turned out that there are users who would like to have__GFP_REPEATsemantic. This is currently implemented for costly >64B requests. Doing the same for smaller requests would require to redefine__GFP_REPEATsemantic in the page allocator which is out of scope of this series.There are many open coded kmalloc with vmalloc fallback instances in the tree. Most of them are not careful enough or simply do not care about the underlying semantic of the kmalloc/page allocator which means that a) some vmalloc fallbacks are basically unreachable because the kmalloc part will keep retrying until it succeeds b) the page allocator can invoke a really disruptive steps like the OOM killer to move forward which doesn't sound appropriate when we consider that the vmalloc fallback is available.
As it can be seen implementing kvmalloc requires quite an intimate knowledge if the page allocator and the memory reclaim internals which strongly suggests that a helper should be implemented in the memory subsystem proper.
Quoted 5 lines
Most callers I could find have been converted to use the helper instead. This is patch 5. There are some more relying on
__GFP_REPEATin the networking stack which I have converted as well but considering we do not have a support for__GFP_REPEATfor requests smaller than 64kB I have marked it RFC.
Are there any more comments? I would really appreciate to hear from networking folks before I resubmit the series.
Thanks!
Quoted 2 lines
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 4 lines · Michal Hocko
On Thu 12-01-17 16:37:11, Michal Hocko wrote:
Are there any more comments? I would really appreciate to hear from networking folks before I resubmit the series.
I do not see any issues right now.
I am happy to see this thing finally coming, after years of resistance ;)
Quoted 10 lines · Eric Dumazet
Quoted 4 lines · Michal Hocko
On Thu 12-01-17 16:37:11, Michal Hocko wrote:
Are there any more comments? I would really appreciate to hear from networking folks before I resubmit the series.
I do not see any issues right now.
I am happy to see this thing finally coming, after years of resistance ;)
OK, so I will repost the series and ask Andrew for inclusion after it passes my compile test battery after the rebase.
Thanks!
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 23 lines · Michal Hocko
Quoted 22 lines · Michal Hocko
Hi,
this has been previously posted as a single patch [1] but later on more built on top. It turned out that there are users who would like to have__GFP_REPEATsemantic. This is currently implemented for costly >64B requests. Doing the same for smaller requests would require to redefine__GFP_REPEATsemantic in the page allocator which is out of scope of this series.There are many open coded kmalloc with vmalloc fallback instances in the tree. Most of them are not careful enough or simply do not care about the underlying semantic of the kmalloc/page allocator which means that a) some vmalloc fallbacks are basically unreachable because the kmalloc part will keep retrying until it succeeds b) the page allocator can invoke a really disruptive steps like the OOM killer to move forward which doesn't sound appropriate when we consider that the vmalloc fallback is available.
As it can be seen implementing kvmalloc requires quite an intimate knowledge if the page allocator and the memory reclaim internals which strongly suggests that a helper should be implemented in the memory subsystem proper.
Quoted 8 lines
Quoted 5 lines
Most callers I could find have been converted to use the helper instead. This is patch 5. There are some more relying on
__GFP_REPEATin the networking stack which I have converted as well but considering we do not have a support for__GFP_REPEATfor requests smaller than 64kB I have marked it RFC.Are there any more comments? I would really appreciate to hear from networking folks before I resubmit the series.
while this patchset was baking the bpf side switched to use bpf_map_area_alloc() which fixes the issue with missing __GFP_NORETRY that we had to fix quickly. See commit d407bd25a204 ("bpf: don't trigger OOM killer under pressure with map alloc") it covers all kmalloc/vmalloc pairs instead of just one place as in this set. So please rebase and switch bpf_map_area_alloc() to use kvmalloc(). Thanks
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 30 lines · Alexei Starovoitov
Quoted 29 lines · Michal Hocko
Quoted 27 lines · Michal Hocko
Hi,
this has been previously posted as a single patch [1] but later on more built on top. It turned out that there are users who would like to have__GFP_REPEATsemantic. This is currently implemented for costly >64B requests. Doing the same for smaller requests would require to redefine__GFP_REPEATsemantic in the page allocator which is out of scope of this series.There are many open coded kmalloc with vmalloc fallback instances in the tree. Most of them are not careful enough or simply do not care about the underlying semantic of the kmalloc/page allocator which means that a) some vmalloc fallbacks are basically unreachable because the kmalloc part will keep retrying until it succeeds b) the page allocator can invoke a really disruptive steps like the OOM killer to move forward which doesn't sound appropriate when we consider that the vmalloc fallback is available.
As it can be seen implementing kvmalloc requires quite an intimate knowledge if the page allocator and the memory reclaim internals which strongly suggests that a helper should be implemented in the memory subsystem proper.
Most callers I could find have been converted to use the helper instead. This is patch 5. There are some more relying on
__GFP_REPEATin the networking stack which I have converted as well but considering we do not have a support for__GFP_REPEATfor requests smaller than 64kB I have marked it RFC.
Quoted 8 lines
Quoted 2 lines
Are there any more comments? I would really appreciate to hear from networking folks before I resubmit the series.
while this patchset was baking the bpf side switched to use
bpf_map_area_alloc()which fixes the issue with missing__GFP_NORETRYthat we had to fix quickly. See commitd407bd25a204("bpf: don't trigger OOM killer under pressure with map alloc") it covers all kmalloc/vmalloc pairs instead of just one place as in this set. So please rebase and switchbpf_map_area_alloc()to usekvmalloc().
OK, will do. Thanks for the heads up.
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 34 lines · Michal Hocko
Quoted 33 lines · Alexei Starovoitov
Quoted 31 lines · Michal Hocko
Quoted 22 lines · Michal Hocko
Hi,
this has been previously posted as a single patch [1] but later on more built on top. It turned out that there are users who would like to have__GFP_REPEATsemantic. This is currently implemented for costly >64B requests. Doing the same for smaller requests would require to redefine__GFP_REPEATsemantic in the page allocator which is out of scope of this series.There are many open coded kmalloc with vmalloc fallback instances in the tree. Most of them are not careful enough or simply do not care about the underlying semantic of the kmalloc/page allocator which means that a) some vmalloc fallbacks are basically unreachable because the kmalloc part will keep retrying until it succeeds b) the page allocator can invoke a really disruptive steps like the OOM killer to move forward which doesn't sound appropriate when we consider that the vmalloc fallback is available.
As it can be seen implementing kvmalloc requires quite an intimate knowledge if the page allocator and the memory reclaim internals which strongly suggests that a helper should be implemented in the memory subsystem proper.
Quoted 5 lines
Most callers I could find have been converted to use the helper instead. This is patch 5. There are some more relying on
__GFP_REPEATin the networking stack which I have converted as well but considering we do not have a support for__GFP_REPEATfor requests smaller than 64kB I have marked it RFC.Are there any more comments? I would really appreciate to hear from networking folks before I resubmit the series.
Quoted 7 lines
Quoted 5 lines
while this patchset was baking the bpf side switched to use
bpf_map_area_alloc()which fixes the issue with missing__GFP_NORETRYthat we had to fix quickly. See commitd407bd25a204("bpf: don't trigger OOM killer under pressure with map alloc") it covers all kmalloc/vmalloc pairs instead of just one place as in this set. So please rebase and switchbpf_map_area_alloc()to usekvmalloc().OK, will do. Thanks for the heads up.
Just for the record, I will fold the following into the patch 1
---
kernel/bpf/syscall.c +1 -15
@@ -53,21 +53,7 @@ void bpf_register_map_type(struct bpf_map_type_list *tl)void *bpf_map_area_alloc (size_t size) { -/* We definitely need __GFP_NORETRY, so OOM killer doesn't -* trigger under memory pressure as we really just want to -* fail instead. -*/ -const gfp_t flags = __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO; -void *area; - -if (size <= (PAGE_SIZE <<PAGE_ALLOC_COSTLY_ORDER )) { - area =kmalloc (size,GFP_USER | flags); -if (area !=NULL ) -return area; - } - -return __vmalloc (size,GFP_KERNEL | __GFP_HIGHMEM | flags, -PAGE_KERNEL ); +return kvzalloc (size,GFP_USER ); }void bpf_map_area_free (void *area)
Signature · 8 lines
Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>