net: use kvmalloc with __GFP_REPEAT rather than open coded variant
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 <=32kB (with 4kB pages) 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 which fit into 32kB will fall back to vmalloc easier now. Link: http://lkml.kernel.org/r/20170306103327.2766-3-mhocko@kernel.org Signed-off-by: Michal Hocko <mhocko@suse.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Cc: Eric Dumazet <edumazet@google.com> Cc: David Miller <davem@davemloft.net> Cc: Shakeel Butt <shakeelb@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
752ade68cb
commit
da6bc57a8f
|
@ -7264,12 +7264,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);
|
||||
rx = kvzalloc(sz, GFP_KERNEL | __GFP_REPEAT);
|
||||
if (!rx)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev->_rx = rx;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
|
@ -7306,12 +7304,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);
|
||||
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);
|
||||
|
@ -7845,9 +7841,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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue