linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Laight <David.Laight@ACULAB.COM>
To: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	netdev <netdev@vger.kernel.org>
Subject: [PATCH 3/3] Optimise kfree() of memory used for large user iovecs.
Date: Fri, 24 Jan 2020 15:46:06 +0000	[thread overview]
Message-ID: <92b426959a1b4ecba8539006572bf21d@AcuMS.aculab.com> (raw)

Although kfree(NULL) is valid it is slower that checking in the
calling code.
Most of the time passing NULL is unusual, but in the code that
is reading iovecs from the user NULL is the normal case
(only large SG vectors require kmalloc()).
Add a check in the callers before calling kfree().

Signed-off-by: David Laight <david.laight@aculab.com>
---

Note this patch probably needs splitting in 3.

 fs/read_write.c        | 12 ++++++++----
 fs/splice.c            |  6 ++++--
 net/socket.c           |  3 ++-
 security/keys/compat.c |  3 ++-
 security/keys/keyctl.c |  3 ++-
 5 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/fs/read_write.c b/fs/read_write.c
index 0241d68..8f77982 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -995,7 +995,8 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
 	ret = import_iovec(READ, vec, vlen, &iov, &iter);
 	if (ret >= 0) {
 		ret = do_iter_read(file, &iter, pos, flags);
-		kfree(iov);
+		if (unlikely(iov))
+			kfree(iov);
 	}
 
 	return ret;
@@ -1014,7 +1015,8 @@ static ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
 		file_start_write(file);
 		ret = do_iter_write(file, &iter, pos, flags);
 		file_end_write(file);
-		kfree(iov);
+		if (unlikely(iov))
+			kfree(iov);
 	}
 	return ret;
 }
@@ -1184,7 +1186,8 @@ static size_t compat_readv(struct file *file,
 	ret = compat_import_iovec(READ, vec, vlen, &iov, &iter);
 	if (ret >= 0) {
 		ret = do_iter_read(file, &iter, pos, flags);
-		kfree(iov);
+		if (unlikely(iov))
+			kfree(iov);
 	}
 	if (ret > 0)
 		add_rchar(current, ret);
@@ -1294,7 +1297,8 @@ static size_t compat_writev(struct file *file,
 		file_start_write(file);
 		ret = do_iter_write(file, &iter, pos, flags);
 		file_end_write(file);
-		kfree(iov);
+		if (unlikely(iov))
+			kfree(iov);
 	}
 	if (ret > 0)
 		add_wchar(current, ret);
diff --git a/fs/splice.c b/fs/splice.c
index ef919db..c2787d2 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1368,7 +1368,8 @@ static long do_vmsplice(struct file *f, struct iov_iter *iter, unsigned int flag
 	error = import_iovec(type, uiov, nr_segs, &iov, &iter);
 	if (error >= 0) {
 		error = do_vmsplice(f.file, &iter, flags);
-		kfree(iov);
+		if (unlikely(iov))
+			kfree(iov);
 	}
 	fdput(f);
 	return error;
@@ -1393,7 +1394,8 @@ static long do_vmsplice(struct file *f, struct iov_iter *iter, unsigned int flag
 	error = compat_import_iovec(type, iov32, nr_segs, &iov, &iter);
 	if (error >= 0) {
 		error = do_vmsplice(f.file, &iter, flags);
-		kfree(iov);
+		if (unlikely(iov))
+			kfree(iov);
 	}
 	fdput(f);
 	return error;
diff --git a/net/socket.c b/net/socket.c
index cb67d82..249d743 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2324,7 +2324,8 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
 	if (ctl_buf != ctl)
 		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
 out_freeiov:
-	kfree(iov);
+	if (unlikely(iov))
+		kfree(iov);
 	return err;
 }
 
diff --git a/security/keys/compat.c b/security/keys/compat.c
index d5ddf80..e73c009 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -38,7 +38,8 @@ static long compat_keyctl_instantiate_key_iov(
 		return ret;
 
 	ret = keyctl_instantiate_key_common(id, &from, ringid);
-	kfree(iov);
+	if (unlikely(iov))
+		kfree(iov);
 	return ret;
 }
 
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index ee26360..74aeb32 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1219,7 +1219,8 @@ long keyctl_instantiate_key_iov(key_serial_t id,
 	if (ret < 0)
 		return ret;
 	ret = keyctl_instantiate_key_common(id, &from, ringid);
-	kfree(iov);
+	if (unlikely(iov))
+		kfree(iov);
 	return ret;
 }
 
-- 
1.8.1.2

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


                 reply	other threads:[~2020-01-24 15:46 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=92b426959a1b4ecba8539006572bf21d@AcuMS.aculab.com \
    --to=david.laight@aculab.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).