Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5d36e2c authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi Committed by Blagovest Kolenichev
Browse files

ANDROID: Incremental fs: wake up log pollers less often



Waking up the waiters accounts for 80+% of the total logging
time, and about 40% of overall read_single_page() with no
signature verification. By throttling it to once every 16ms
we get back all read performance, reduce the waiter's CPU
usage and still leave it enough time to pull the logs out.

Bug: 155996534
Test: adb install megacity.apk & dd from the installed apk

Signed-off-by: default avatarYurii Zubrytskyi <zyy@google.com>
Signed-off-by: default avatarPaul Lawrence <paullawrence@google.com>
Change-Id: I4a118dc226d7ca318cf099ba3e239f0120bb23c2
Git-commit: 1c8f02e0
Git-repo: https://android.googlesource.com/kernel/common/


Signed-off-by: default avatarSayali Lokhande <sayalil@codeaurora.org>
parent 81def041
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/file.h>
#include <linux/ktime.h>
#include <linux/mm.h>
#include <linux/workqueue.h>
#include <linux/pagemap.h>
#include <linux/lz4.h>
#include <linux/crc32.h>
@@ -16,6 +17,13 @@
#include "format.h"
#include "integrity.h"

static void log_wake_up_all(struct work_struct *work)
{
	struct delayed_work *dw = container_of(work, struct delayed_work, work);
	struct read_log *rl = container_of(dw, struct read_log, ml_wakeup_work);
	wake_up_all(&rl->ml_notif_wq);
}

struct mount_info *incfs_alloc_mount_info(struct super_block *sb,
					  struct mount_options *options,
					  struct path *backing_dir_path)
@@ -35,6 +43,7 @@ struct mount_info *incfs_alloc_mount_info(struct super_block *sb,
	mutex_init(&mi->mi_pending_reads_mutex);
	init_waitqueue_head(&mi->mi_pending_reads_notif_wq);
	init_waitqueue_head(&mi->mi_log.ml_notif_wq);
	INIT_DELAYED_WORK(&mi->mi_log.ml_wakeup_work, log_wake_up_all);
	spin_lock_init(&mi->mi_log.rl_lock);
	INIT_LIST_HEAD(&mi->mi_reads_list_head);

@@ -95,6 +104,8 @@ void incfs_free_mount_info(struct mount_info *mi)
	if (!mi)
		return;

	flush_delayed_work(&mi->mi_log.ml_wakeup_work);

	dput(mi->mi_index_dir);
	path_put(&mi->mi_backing_dir_path);
	mutex_destroy(&mi->mi_dir_struct_mutex);
@@ -297,11 +308,20 @@ static void log_block_read(struct mount_info *mi, incfs_uuid_t *id,
{
	struct read_log *log = &mi->mi_log;
	struct read_log_state *head, *tail;
	s64 now_us = ktime_to_us(ktime_get());
	s64 now_us;
	s64 relative_us;
	union log_record record;
	size_t record_size;

	/*
	 * This may read the old value, but it's OK to delay the logging start
	 * right after the configuration update.
	 */
	if (READ_ONCE(log->rl_size) == 0)
		return;

	now_us = ktime_to_us(ktime_get());

	spin_lock(&log->rl_lock);
	if (log->rl_size == 0) {
		spin_unlock(&log->rl_lock);
@@ -320,6 +340,7 @@ static void log_block_read(struct mount_info *mi, incfs_uuid_t *id,
			.file_id = *id,
			.absolute_ts_us = now_us,
		};
		head->base_record.file_id = *id;
		record_size = sizeof(struct full_record);
	} else if (block_index != head->base_record.block_index + 1 ||
		   relative_us >= 1 << 30) {
@@ -344,7 +365,6 @@ static void log_block_read(struct mount_info *mi, incfs_uuid_t *id,
		record_size = sizeof(struct same_file_next_block_short);
	}

	head->base_record.file_id = *id;
	head->base_record.block_index = block_index;
	head->base_record.absolute_ts_us = now_us;

@@ -363,7 +383,8 @@ static void log_block_read(struct mount_info *mi, incfs_uuid_t *id,
	++head->current_record_no;

	spin_unlock(&log->rl_lock);
	wake_up_all(&log->ml_notif_wq);
	if (schedule_delayed_work(&log->ml_wakeup_work, msecs_to_jiffies(16)))
		pr_debug("incfs: scheduled a log pollers wakeup");
}

static int validate_hash_tree(struct file *bf, struct data_file *df,
+3 −0
Original line number Diff line number Diff line
@@ -89,6 +89,9 @@ struct read_log {

	/* A queue of waiters who want to be notified about reads */
	wait_queue_head_t ml_notif_wq;

	/* A work item to wake up those waiters without slowing down readers */
	struct delayed_work ml_wakeup_work;
};

struct mount_options {