Blob Blame History Raw
From: Wenjia Zhang <wenjia@linux.ibm.com>
Date: Wed, 12 Sep 2018 15:31:34 +0200
Subject: s390/qeth: use vzalloc for QUERY OAT buffer
Patch-mainline: v4.19-rc4
Git-commit: aec45e857c5538664edb76a60dd452e3265f37d1
References: LTC#171527, bsc#1106948

Description:  qeth: use vzalloc for QUERY OAT buffer
Symptom:      qethqoat tool fails. 
Problem:      qeth_query_oat_command() currently allocates the kernel 
              buffer for the SIOC_QETH_QUERY_OAT ioctl with kzalloc.
Solution:     Using vzalloc() instead of kzalloc(), backing the 
              allocation with non-contiguous memory.
Reproduction: -
Upstream-ID:  aec45e857c5538664edb76a60dd452e3265f37d1
Problem-ID:   171527

Upstream-Description:

              s390/qeth: use vzalloc for QUERY OAT buffer

              qeth_query_oat_command() currently allocates the kernel buffer for
              the SIOC_QETH_QUERY_OAT ioctl with kzalloc. So on systems with
              fragmented memory, large allocations may fail (eg. the qethqoat tool by
              default uses 132KB).

              Solve this issue by using vzalloc, backing the allocation with
              non-contiguous memory.

              Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
              Reviewed-by: Julian Wiedmann <jwi@linux.ibm.com>
              Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
              Signed-off-by: David S. Miller <davem@davemloft.net>


Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/s390/net/qeth_core_main.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -23,6 +23,7 @@
 #include <linux/netdevice.h>
 #include <linux/netdev_features.h>
 #include <linux/skbuff.h>
+#include <linux/vmalloc.h>
 
 #include <net/iucv/af_iucv.h>
 #include <net/dsfield.h>
@@ -4727,7 +4728,7 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
 
 	priv.buffer_len = oat_data.buffer_len;
 	priv.response_len = 0;
-	priv.buffer =  kzalloc(oat_data.buffer_len, GFP_KERNEL);
+	priv.buffer = vzalloc(oat_data.buffer_len);
 	if (!priv.buffer) {
 		rc = -ENOMEM;
 		goto out;
@@ -4768,7 +4769,7 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
 			rc = -EFAULT;
 
 out_free:
-	kfree(priv.buffer);
+	vfree(priv.buffer);
 out:
 	return rc;
 }