* [PATCH 0/1 RFC] read_policy type heuristic
@ 2022-07-21 11:52 Anand Jain
2022-07-21 11:52 ` [PATCH 1/1 RFC] btrfs: add read_policy heuristic Anand Jain
0 siblings, 1 reply; 2+ messages in thread
From: Anand Jain @ 2022-07-21 11:52 UTC (permalink / raw)
To: linux-btrfs
POC patch proposes a read_policy type Heuristic to solve the problem of
poor read performance for the mirrored stripes on mixed device types.
Read_policy Heuristic has benefits of both pid and has no dependency on
block layer iostats. Instead, it uses statically defined device_type and
its latency.
This patch is a POC patch that has no performance analysis yet. I am
sending this to get some early feedback.
For the read_policy type Latency, please refer here [1]. The read_policy
type Latency works better overall, and it is self-tuning based on the IO.
[1]
https://lore.kernel.org/linux-btrfs/20210120123437.OVx7ybGaVfmOdZxtpp43qcB_ORHQQs5OzPSzr3ZUGbo@z/T/#u
Anand Jain (1):
btrfs: add read_policy heuristic
fs/btrfs/sysfs.c | 2 +-
fs/btrfs/volumes.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++
fs/btrfs/volumes.h | 2 ++
3 files changed, 55 insertions(+), 1 deletion(-)
--
2.33.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH 1/1 RFC] btrfs: add read_policy heuristic
2022-07-21 11:52 [PATCH 0/1 RFC] read_policy type heuristic Anand Jain
@ 2022-07-21 11:52 ` Anand Jain
0 siblings, 0 replies; 2+ messages in thread
From: Anand Jain @ 2022-07-21 11:52 UTC (permalink / raw)
To: linux-btrfs
Read_policy type Heuristic provides the low latency device-type if
read_policy type PID fails. The read policy heuristic retains the
advantages of the PID-based read_policy and has no dependency on
block layer iostats. This policy can be a default policy.
This patch depends on the patches[1], which provides device types
in the order of their latency.
[1]
btrfs: create chunk device type aware
btrfs: keep device type in the struct btrfs_device
Usage:
$ echo heuristic > /sys/fs/btrfs/4b74dc57-526c-42c0-882a-8be30e1b8933/read_policy
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
fs/btrfs/sysfs.c | 2 +-
fs/btrfs/volumes.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++
fs/btrfs/volumes.h | 2 ++
3 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index d5d0717fd09a..501c216009fb 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -1169,7 +1169,7 @@ static bool strmatch(const char *buffer, const char *string)
return false;
}
-static const char * const btrfs_read_policy_name[] = { "pid" };
+static const char * const btrfs_read_policy_name[] = { "pid", "heuristic" };
static ssize_t btrfs_read_policy_show(struct kobject *kobj,
struct kobj_attribute *a, char *buf)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index ad053c2a63a5..7efdd1dabf7b 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -5896,6 +5896,54 @@ int btrfs_is_parity_mirror(struct btrfs_fs_info *fs_info, u64 logical, u64 len)
return ret;
}
+static int btrfs_read_heuristic(struct btrfs_fs_info *fs_info,
+ struct map_lookup *map, int first,
+ int num_stripes)
+{
+ int cur;
+ int new;
+ int stripe;
+ int latency;
+ int curlatency;
+
+ /*
+ * First get the preferred mirror as per current pid and check its
+ * latency
+ */
+ stripe = first + (current->pid % num_stripes);
+ latency = btrfs_dev_type_to_latency(map->stripes[stripe].dev->dev_type);
+
+ /* If the device selected already has the lowest latency then return */
+ if (latency == 0)
+ return stripe;
+
+ cur = stripe;
+ curlatency = latency;
+
+ /* Find if any other stripes have lower latency */
+ for (new = first; new < first + num_stripes; new++) {
+ struct btrfs_device *device = map->stripes[new].dev;
+ int newlatency;
+
+ newlatency = btrfs_dev_type_to_latency(device->dev_type);
+
+ if (newlatency < curlatency) {
+ cur = new;
+ curlatency = newlatency;
+ }
+ }
+
+ /*
+ * If the PID chosen device also has the same latency, then use that
+ * device.
+ */
+ if (curlatency == latency)
+ return stripe;
+
+ return cur;
+}
+
+
static int find_live_mirror(struct btrfs_fs_info *fs_info,
struct map_lookup *map, int first,
int dev_replace_is_ongoing)
@@ -5925,6 +5973,10 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
case BTRFS_READ_POLICY_PID:
preferred_mirror = first + (current->pid % num_stripes);
break;
+ case BTRFS_READ_POLICY_HEURISTIC:
+ preferred_mirror = btrfs_read_heuristic(fs_info, map, first,
+ num_stripes);
+ break;
}
if (dev_replace_is_ongoing &&
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 0fe20eb4087a..c8a73722bf60 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -277,6 +277,8 @@ enum btrfs_chunk_allocation_policy {
enum btrfs_read_policy {
/* Use process PID to choose the stripe */
BTRFS_READ_POLICY_PID,
+ /* Find and use device with the lowest latency */
+ BTRFS_READ_POLICY_HEURISTIC,
BTRFS_NR_READ_POLICY,
};
--
2.33.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-07-21 11:52 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-21 11:52 [PATCH 0/1 RFC] read_policy type heuristic Anand Jain
2022-07-21 11:52 ` [PATCH 1/1 RFC] btrfs: add read_policy heuristic Anand Jain
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.