From: David Disseldorp <ddiss@suse.de>
To: linux-fsdevel@vger.kernel.org, linux-doc@vger.kernel.org
Cc: viro@zeniv.linux.org.uk, willy@infradead.org,
David Disseldorp <ddiss@suse.de>
Subject: [PATCH 5/5] initramfs: add INITRAMFS_PRESERVE_MTIME Kconfig option
Date: Wed, 22 Sep 2021 13:52:22 +0200 [thread overview]
Message-ID: <20210922115222.8987-5-ddiss@suse.de> (raw)
In-Reply-To: <20210922115222.8987-1-ddiss@suse.de>
initramfs cpio mtime preservation, as implemented via
889d51a10712b6fd6175196626de2116858394f4, uses a linked list to defer
directory mtime processing until after all other items in the cpio
archive have been processed. This is done to ensure that parent
directory mtimes aren't overwritten via subsequent child creation.
This change adds a new INITRAMFS_PRESERVE_MTIME Kconfig option, which
can be used to disable on-by-default mtime retention and in turn
speed up initramfs extraction, particularly for cpio archives with large
directory counts.
For a cpio archive with ~1M directories, rough 20-run local benchmarks
demonstrated:
mean extraction time (s) std dev
INITRAMFS_PRESERVE_MTIME=y 3.789035 0.005474
INITRAMFS_PRESERVE_MTIME unset 3.111508 0.004132
Signed-off-by: David Disseldorp <ddiss@suse.de>
---
init/Kconfig | 10 +++++++++
init/Makefile | 3 +++
init/initramfs.c | 42 ++----------------------------------
init/initramfs_mtime.c | 49 ++++++++++++++++++++++++++++++++++++++++++
init/initramfs_mtime.h | 11 ++++++++++
5 files changed, 75 insertions(+), 40 deletions(-)
create mode 100644 init/initramfs_mtime.c
create mode 100644 init/initramfs_mtime.h
diff --git a/init/Kconfig b/init/Kconfig
index 55f9f7738ebb..a79b6ba4d76c 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1324,6 +1324,16 @@ config BOOT_CONFIG
If unsure, say Y.
+config INITRAMFS_PRESERVE_MTIME
+ bool "Preserve cpio archive mtimes in initramfs"
+ default y
+ help
+ Each entry in an initramfs cpio archive carries an mtime value. When
+ enabled, extracted cpio items take this mtime, with directory mtime
+ setting deferred until after creation of any child entries.
+
+ If unsure, say Y.
+
choice
prompt "Compiler optimization level"
default CC_OPTIMIZE_FOR_PERFORMANCE
diff --git a/init/Makefile b/init/Makefile
index 2846113677ee..d72bf80170ce 100644
--- a/init/Makefile
+++ b/init/Makefile
@@ -11,6 +11,9 @@ obj-y += noinitramfs.o
else
obj-$(CONFIG_BLK_DEV_INITRD) += initramfs.o
endif
+ifeq ($(CONFIG_INITRAMFS_PRESERVE_MTIME),y)
+obj-$(CONFIG_BLK_DEV_INITRD) += initramfs_mtime.o
+endif
obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
obj-y += init_task.o
diff --git a/init/initramfs.c b/init/initramfs.c
index 7f809a1c8e89..205fd62be616 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -16,6 +16,8 @@
#include <linux/namei.h>
#include <linux/init_syscalls.h>
+#include "initramfs_mtime.h"
+
static ssize_t __init xwrite(struct file *file, const char *p, size_t count,
loff_t *pos)
{
@@ -115,46 +117,6 @@ static void __init free_hash(void)
}
}
-static long __init do_utime(char *filename, time64_t mtime)
-{
- struct timespec64 t[2];
-
- t[0].tv_sec = mtime;
- t[0].tv_nsec = 0;
- t[1].tv_sec = mtime;
- t[1].tv_nsec = 0;
- return init_utimes(filename, t);
-}
-
-static __initdata LIST_HEAD(dir_list);
-struct dir_entry {
- struct list_head list;
- char *name;
- time64_t mtime;
-};
-
-static void __init dir_add(const char *name, time64_t mtime)
-{
- struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL);
- if (!de)
- panic_show_mem("can't allocate dir_entry buffer");
- INIT_LIST_HEAD(&de->list);
- de->name = kstrdup(name, GFP_KERNEL);
- de->mtime = mtime;
- list_add(&de->list, &dir_list);
-}
-
-static void __init dir_utime(void)
-{
- struct dir_entry *de, *tmp;
- list_for_each_entry_safe(de, tmp, &dir_list, list) {
- list_del(&de->list);
- do_utime(de->name, de->mtime);
- kfree(de->name);
- kfree(de);
- }
-}
-
static __initdata time64_t mtime;
/* cpio header parsing */
diff --git a/init/initramfs_mtime.c b/init/initramfs_mtime.c
new file mode 100644
index 000000000000..0020deb21f76
--- /dev/null
+++ b/init/initramfs_mtime.c
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/syscalls.h>
+#include <linux/utime.h>
+#include <linux/file.h>
+#include <linux/init_syscalls.h>
+
+#include "initramfs_mtime.h"
+
+long __init do_utime(char *filename, time64_t mtime)
+{
+ struct timespec64 t[2];
+
+ t[0].tv_sec = mtime;
+ t[0].tv_nsec = 0;
+ t[1].tv_sec = mtime;
+ t[1].tv_nsec = 0;
+ return init_utimes(filename, t);
+}
+
+static __initdata LIST_HEAD(dir_list);
+struct dir_entry {
+ struct list_head list;
+ char *name;
+ time64_t mtime;
+};
+
+void __init dir_add(const char *name, time64_t mtime)
+{
+ struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL);
+ if (!de)
+ panic("can't allocate dir_entry buffer");
+ INIT_LIST_HEAD(&de->list);
+ de->name = kstrdup(name, GFP_KERNEL);
+ de->mtime = mtime;
+ list_add(&de->list, &dir_list);
+}
+
+void __init dir_utime(void)
+{
+ struct dir_entry *de, *tmp;
+ list_for_each_entry_safe(de, tmp, &dir_list, list) {
+ list_del(&de->list);
+ do_utime(de->name, de->mtime);
+ kfree(de->name);
+ kfree(de);
+ }
+}
diff --git a/init/initramfs_mtime.h b/init/initramfs_mtime.h
new file mode 100644
index 000000000000..6d15c8b1171f
--- /dev/null
+++ b/init/initramfs_mtime.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifdef CONFIG_INITRAMFS_PRESERVE_MTIME
+long do_utime(char *filename, time64_t mtime) __init;
+void dir_add(const char *name, time64_t mtime) __init;
+void dir_utime(void) __init;
+#else
+static long __init do_utime(char *filename, time64_t mtime) { return 0; }
+static void __init dir_add(const char *name, time64_t mtime) {}
+static void __init dir_utime(void) {}
+#endif
--
2.31.1
next prev parent reply other threads:[~2021-09-22 11:52 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-22 11:52 [PATCH 1/5] initramfs: move unnecessary memcmp from hot path David Disseldorp
2021-09-22 11:52 ` [PATCH 2/5] initramfs: print helpful cpio error on "crc" magic David Disseldorp
2021-09-22 11:52 ` [PATCH v2 3/5] docs: remove mention of "crc" cpio format support David Disseldorp
2021-09-22 11:52 ` [PATCH 4/5] initramfs: use do_utime() wrapper consistently David Disseldorp
2021-09-22 11:52 ` David Disseldorp [this message]
2021-09-22 23:28 ` [PATCH 1/5] initramfs: move unnecessary memcmp from hot path Chaitanya Kulkarni
2021-09-23 7:43 ` David Disseldorp
2021-09-22 23:35 ` Al Viro
2021-09-22 23:51 ` Chaitanya Kulkarni
2021-09-23 7:33 ` David Disseldorp
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=20210922115222.8987-5-ddiss@suse.de \
--to=ddiss@suse.de \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.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).