[rh7,2/2] net/sock: teach sock_kmalloc() to call kvmalloc() when possible

Submitted by Konstantin Khorenko on March 21, 2018, 11:11 a.m.

Details

Message ID 20180321111149.21260-2-khorenko@virtuozzo.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Konstantin Khorenko March 21, 2018, 11:11 a.m.
sock_setsockopt()
 sk_attach_filter()
  sock_kmalloc()

Memory size to be allocated depends on the number of rules provided by
userspace, but not more than net.core.optmem_max (20480 by default),
which still allows to allocate 3rd order pages via kmalloc() =>
it's better to substitute it with kvmalloc().

But sock_kmalloc() can be called with GFP_ATOMIC from some places,
so we cannot unconditionally call kvmalloc() instead of kmalloc().

Hopefully sk_attach_filter() calls sock_kmalloc() with GFP_KERNEL,
so kvmalloc() can be used there.

=> use kvmalloc_check() which calls kvmalloc() if it's allowed
by provided flags.

https://jira.sw.ru/browse/PSBM-82593

Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 net/core/sock.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/net/core/sock.c b/net/core/sock.c
index b4abbbf35797..5d2016807042 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1707,7 +1707,7 @@  void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
 		 * might sleep.
 		 */
 		atomic_add(size, &sk->sk_omem_alloc);
-		mem = kmalloc(size, priority);
+		mem = kvmalloc_check(size, priority);
 		if (mem)
 			return mem;
 		atomic_sub(size, &sk->sk_omem_alloc);
@@ -1721,7 +1721,7 @@  EXPORT_SYMBOL(sock_kmalloc);
  */
 void sock_kfree_s(struct sock *sk, void *mem, int size)
 {
-	kfree(mem);
+	kvfree(mem);
 	atomic_sub(size, &sk->sk_omem_alloc);
 }
 EXPORT_SYMBOL(sock_kfree_s);

Comments

Andrey Ryabinin March 21, 2018, 12:59 p.m.
On 03/21/2018 02:11 PM, Konstantin Khorenko wrote:
> sock_setsockopt()
>  sk_attach_filter()
>   sock_kmalloc()
> 
> Memory size to be allocated depends on the number of rules provided by
> userspace, but not more than net.core.optmem_max (20480 by default),
> which still allows to allocate 3rd order pages via kmalloc() =>
> it's better to substitute it with kvmalloc().
> 
> But sock_kmalloc() can be called with GFP_ATOMIC from some places,
> so we cannot unconditionally call kvmalloc() instead of kmalloc().
> 
> Hopefully sk_attach_filter() calls sock_kmalloc() with GFP_KERNEL,
> so kvmalloc() can be used there.
> 
> => use kvmalloc_check() which calls kvmalloc() if it's allowed
> by provided flags.
> 

seems fishy. What we are going to do when we GFP_ATOMIC will ask for 3 order?

> https://jira.sw.ru/browse/PSBM-82593
> 
> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
> ---
>  net/core/sock.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/core/sock.c b/net/core/sock.c
> index b4abbbf35797..5d2016807042 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -1707,7 +1707,7 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
>  		 * might sleep.
>  		 */
>  		atomic_add(size, &sk->sk_omem_alloc);
> -		mem = kmalloc(size, priority);
> +		mem = kvmalloc_check(size, priority);
>  		if (mem)
>  			return mem;
>  		atomic_sub(size, &sk->sk_omem_alloc);
> @@ -1721,7 +1721,7 @@ EXPORT_SYMBOL(sock_kmalloc);
>   */
>  void sock_kfree_s(struct sock *sk, void *mem, int size)
>  {
> -	kfree(mem);
> +	kvfree(mem);
>  	atomic_sub(size, &sk->sk_omem_alloc);
>  }
>  EXPORT_SYMBOL(sock_kfree_s);
>
Konstantin Khorenko March 21, 2018, 1:10 p.m.
On 03/21/2018 03:59 PM, Andrey Ryabinin wrote:
>
>
> On 03/21/2018 02:11 PM, Konstantin Khorenko wrote:
>> sock_setsockopt()
>>  sk_attach_filter()
>>   sock_kmalloc()
>>
>> Memory size to be allocated depends on the number of rules provided by
>> userspace, but not more than net.core.optmem_max (20480 by default),
>> which still allows to allocate 3rd order pages via kmalloc() =>
>> it's better to substitute it with kvmalloc().
>>
>> But sock_kmalloc() can be called with GFP_ATOMIC from some places,
>> so we cannot unconditionally call kvmalloc() instead of kmalloc().
>>
>> Hopefully sk_attach_filter() calls sock_kmalloc() with GFP_KERNEL,
>> so kvmalloc() can be used there.
>>
>> => use kvmalloc_check() which calls kvmalloc() if it's allowed
>> by provided flags.
>>
>
> seems fishy. What we are going to do when we GFP_ATOMIC will ask for 3 order?

In this particular case (from sk_attach_filter()) sock_kmalloc() is called with GFP_KERNEL,
so we cover the problem case we've got.

When we face high-order kmalloc with GFP_ATOMIC, well, we'll find a way.


>> https://jira.sw.ru/browse/PSBM-82593
>>
>> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
>> ---
>>  net/core/sock.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/core/sock.c b/net/core/sock.c
>> index b4abbbf35797..5d2016807042 100644
>> --- a/net/core/sock.c
>> +++ b/net/core/sock.c
>> @@ -1707,7 +1707,7 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
>>  		 * might sleep.
>>  		 */
>>  		atomic_add(size, &sk->sk_omem_alloc);
>> -		mem = kmalloc(size, priority);
>> +		mem = kvmalloc_check(size, priority);
>>  		if (mem)
>>  			return mem;
>>  		atomic_sub(size, &sk->sk_omem_alloc);
>> @@ -1721,7 +1721,7 @@ EXPORT_SYMBOL(sock_kmalloc);
>>   */
>>  void sock_kfree_s(struct sock *sk, void *mem, int size)
>>  {
>> -	kfree(mem);
>> +	kvfree(mem);
>>  	atomic_sub(size, &sk->sk_omem_alloc);
>>  }
>>  EXPORT_SYMBOL(sock_kfree_s);
>>
> .
>
Andrey Ryabinin March 21, 2018, 5:07 p.m.
On 03/21/2018 04:10 PM, Konstantin Khorenko wrote:
> On 03/21/2018 03:59 PM, Andrey Ryabinin wrote:
>>
>>
>> On 03/21/2018 02:11 PM, Konstantin Khorenko wrote:
>>> sock_setsockopt()
>>>  sk_attach_filter()
>>>   sock_kmalloc()
>>>
>>> Memory size to be allocated depends on the number of rules provided by
>>> userspace, but not more than net.core.optmem_max (20480 by default),
>>> which still allows to allocate 3rd order pages via kmalloc() =>
>>> it's better to substitute it with kvmalloc().
>>>
>>> But sock_kmalloc() can be called with GFP_ATOMIC from some places,
>>> so we cannot unconditionally call kvmalloc() instead of kmalloc().
>>>
>>> Hopefully sk_attach_filter() calls sock_kmalloc() with GFP_KERNEL,
>>> so kvmalloc() can be used there.
>>>
>>> => use kvmalloc_check() which calls kvmalloc() if it's allowed
>>> by provided flags.
>>>
>>
>> seems fishy. What we are going to do when we GFP_ATOMIC will ask for 3 order?
> 
> In this particular case (from sk_attach_filter()) sock_kmalloc() is called with GFP_KERNEL,
> so we cover the problem case we've got.
> 
> When we face high-order kmalloc with GFP_ATOMIC, well, we'll find a way.

Ughh, but ok.

Reviewed-by: Andrey Ryabinin <aryabinin@virtuozzo.com>