From: Aleksandr Nogikh <nogikh@google.com>
To: kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org,
akpm@linux-foundation.org
Cc: dvyukov@google.com, andreyknvl@gmail.com, elver@google.com,
glider@google.com, tarasmadan@google.com, bigeasy@linutronix.de,
nogikh@google.com
Subject: [PATCH v2 1/2] kcov: split ioctl handling into locked and unlocked parts
Date: Tue, 21 Dec 2021 17:03:47 +0000 [thread overview]
Message-ID: <20211221170348.1113266-2-nogikh@google.com> (raw)
In-Reply-To: <20211221170348.1113266-1-nogikh@google.com>
Currently all ioctls are de facto processed under a spin lock in order
to serialise them. This, however, prohibits the use of vmalloc and other
memory management functions in the implementation of those ioctls,
unnecessary complicating any further changes.
Let all ioctls first be processed inside the kcov_ioctl_unlocked()
function which should execute the ones that are not compatible with
spinlock and pass control to kcov_ioctl_locked() for all other ones.
Although it is still compatible with a spinlock, move KCOV_INIT_TRACE
handling to kcov_ioctl_unlocked(), so that its planned change is easier
to follow.
Signed-off-by: Aleksandr Nogikh <nogikh@google.com>
---
kernel/kcov.c | 64 +++++++++++++++++++++++++++++++--------------------
1 file changed, 39 insertions(+), 25 deletions(-)
diff --git a/kernel/kcov.c b/kernel/kcov.c
index 36ca640c4f8e..5d87b4e0126f 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -564,31 +564,12 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
unsigned long arg)
{
struct task_struct *t;
- unsigned long size, unused;
+ unsigned long flags, unused;
int mode, i;
struct kcov_remote_arg *remote_arg;
struct kcov_remote *remote;
- unsigned long flags;
switch (cmd) {
- case KCOV_INIT_TRACE:
- /*
- * Enable kcov in trace mode and setup buffer size.
- * Must happen before anything else.
- */
- if (kcov->mode != KCOV_MODE_DISABLED)
- return -EBUSY;
- /*
- * Size must be at least 2 to hold current position and one PC.
- * Later we allocate size * sizeof(unsigned long) memory,
- * that must not overflow.
- */
- size = arg;
- if (size < 2 || size > INT_MAX / sizeof(unsigned long))
- return -EINVAL;
- kcov->size = size;
- kcov->mode = KCOV_MODE_INIT;
- return 0;
case KCOV_ENABLE:
/*
* Enable coverage for the current task.
@@ -685,6 +666,43 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
}
}
+static int kcov_ioctl_unlocked(struct kcov *kcov, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned long size, flags;
+ int res;
+
+ switch (cmd) {
+ case KCOV_INIT_TRACE:
+ /*
+ * Enable kcov in trace mode and setup buffer size.
+ * Must happen before anything else.
+ */
+ if (kcov->mode != KCOV_MODE_DISABLED)
+ return -EBUSY;
+ /*
+ * Size must be at least 2 to hold current position and one PC.
+ * Later we allocate size * sizeof(unsigned long) memory,
+ * that must not overflow.
+ */
+ size = arg;
+ if (size < 2 || size > INT_MAX / sizeof(unsigned long))
+ return -EINVAL;
+ kcov->size = size;
+ kcov->mode = KCOV_MODE_INIT;
+ return 0;
+ default:
+ /*
+ * All other commands can be fully executed under a spin lock, so we
+ * obtain and release it here to simplify the code of kcov_ioctl_locked().
+ */
+ spin_lock_irqsave(&kcov->lock, flags);
+ res = kcov_ioctl_locked(kcov, cmd, arg);
+ spin_unlock_irqrestore(&kcov->lock, flags);
+ return res;
+ }
+}
+
static long kcov_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
struct kcov *kcov;
@@ -692,7 +710,6 @@ static long kcov_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
struct kcov_remote_arg *remote_arg = NULL;
unsigned int remote_num_handles;
unsigned long remote_arg_size;
- unsigned long flags;
if (cmd == KCOV_REMOTE_ENABLE) {
if (get_user(remote_num_handles, (unsigned __user *)(arg +
@@ -713,10 +730,7 @@ static long kcov_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
}
kcov = filep->private_data;
- spin_lock_irqsave(&kcov->lock, flags);
- res = kcov_ioctl_locked(kcov, cmd, arg);
- spin_unlock_irqrestore(&kcov->lock, flags);
-
+ res = kcov_ioctl_unlocked(kcov, cmd, arg);
kfree(remote_arg);
return res;
--
2.34.1.307.g9b7440fafd-goog
next prev parent reply other threads:[~2021-12-21 17:04 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-21 17:03 [PATCH v2 0/2] kcov: improve mmap processing Aleksandr Nogikh
2021-12-21 17:03 ` Aleksandr Nogikh [this message]
2021-12-21 20:19 ` [PATCH v2 1/2] kcov: split ioctl handling into locked and unlocked parts Marco Elver
2021-12-22 12:28 ` Aleksandr Nogikh
2021-12-21 17:03 ` [PATCH v2 2/2] kcov: properly handle subsequent mmap calls Aleksandr Nogikh
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=20211221170348.1113266-2-nogikh@google.com \
--to=nogikh@google.com \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@gmail.com \
--cc=bigeasy@linutronix.de \
--cc=dvyukov@google.com \
--cc=elver@google.com \
--cc=glider@google.com \
--cc=kasan-dev@googlegroups.com \
--cc=linux-kernel@vger.kernel.org \
--cc=tarasmadan@google.com \
/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
all inboxes | Powered by JetHome®