From: NeilBrown <neilb@suse.de>
To: Tejun Heo <tj@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH] kernfs: use stack-buf for small writes.
Date: Tue, 23 Sep 2014 14:06:33 +1000 [thread overview]
Message-ID: <20140923140633.35efbe7a@notabene.brown> (raw)
[-- Attachment #1: Type: text/plain, Size: 2131 bytes --]
For a write <= 128 characters, don't use kmalloc.
mdmon, part of mdadm, will sometimes need to write
to a sysfs file in order to allow writes to the array
to continue. This is important to support RAID metadata
types that the kernel doesn't know about.
It is important that this write doesn't block on
memory allocation. The safest way to ensure that is to
use an on-stack buffer.
Writes are always small, typically less than 10 characters.
Note that reads from a sysfs file are already safe due to the use for
seqfile. The first read will allocate a buffer (m->buf) which will
be used for all subsequent reads.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Hi Tejun,
I wonder if you would consider this patch.
When mdmon needs to update metadata after a device failure in an array
there are two 'kmalloc' sources that can trigger deadlock if memory is tight
and needs to be written to the array (which cannot be allowed until mdmon
updates the metadata).
One is in O_DIRECT writes which I have patches for. The other is when
writing to the sysfs file to tell md that it is safe to continue.
This simple patch removes the second.
Thanks,
NeilBrown
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 4429d6d9217f..75b58669ce55 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -269,6 +269,7 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf,
const struct kernfs_ops *ops;
size_t len;
char *buf;
+ char stackbuf[129];
if (of->atomic_write_len) {
len = count;
@@ -278,7 +279,10 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf,
len = min_t(size_t, count, PAGE_SIZE);
}
- buf = kmalloc(len + 1, GFP_KERNEL);
+ if (len < sizeof(stackbuf))
+ buf = stackbuf;
+ else
+ buf = kmalloc(len + 1, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -311,7 +315,8 @@ static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf,
if (len > 0)
*ppos += len;
out_free:
- kfree(buf);
+ if (buf != stackbuf)
+ kfree(buf);
return len;
}
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
next reply other threads:[~2014-09-23 4:06 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-23 4:06 NeilBrown [this message]
2014-09-23 4:12 ` [PATCH] kernfs: use stack-buf for small writes Tejun Heo
2014-09-23 4:18 ` Tejun Heo
2014-09-23 4:46 ` NeilBrown
2014-09-23 4:55 ` Tejun Heo
2014-09-23 5:40 ` NeilBrown
2014-09-23 5:51 ` Tejun Heo
2014-09-23 6:11 ` NeilBrown
2014-09-23 6:15 ` Tejun Heo
2014-09-24 19:17 ` Al Viro
2014-09-24 23:58 ` NeilBrown
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=20140923140633.35efbe7a@notabene.brown \
--to=neilb@suse.de \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tj@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