Add support for high-priority dm-crypt flag.

This patch add new --perf-high_priority cryptsetup option
for flga added in Linux kernel 6.10, dm-crypt target version 1.26.
This commit is contained in:
Milan Broz
2024-04-09 16:11:58 +02:00
parent e32ea56b59
commit 98b4243432
10 changed files with 69 additions and 8 deletions

View File

@@ -1504,6 +1504,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26)
/** dm-verity: try to use tasklets */
#define CRYPT_ACTIVATE_TASKLETS (UINT32_C(1) << 27)
/** dm-crypt: use high-priority workqueues */
#define CRYPT_ACTIVATE_HIGH_PRIORITY (UINT32_C(1) << 28)
/**
* Active device runtime attributes

View File

@@ -157,6 +157,9 @@ static void _dm_set_crypt_compat(struct crypt_device *cd,
if (_dm_satisfies_version(1, 22, 0, crypt_maj, crypt_min, crypt_patch))
_dm_flags |= DM_CRYPT_NO_WORKQUEUE_SUPPORTED;
if (_dm_satisfies_version(1, 26, 0, crypt_maj, crypt_min, crypt_patch))
_dm_flags |= DM_CRYPT_HIGH_PRIORITY_SUPPORTED;
_dm_crypt_checked = true;
}
@@ -558,19 +561,22 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
num_options++;
if (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS)
num_options++;
if (flags & CRYPT_ACTIVATE_HIGH_PRIORITY)
num_options++;
if (tgt->u.crypt.integrity)
num_options++;
if (tgt->u.crypt.sector_size != SECTOR_SIZE)
num_options++;
if (num_options) { /* MAX length int32 + 15 + 15 + 23 + 18 + 19 + 17 + 13 + int32 + integrity_str */
r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s%s%s", num_options,
if (num_options) { /* MAX length int32 + 15 + 15 + 23 + 18 + 19 + 17 + 14 + 13 + int32 + integrity_str */
r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s%s%s%s", num_options,
(flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "",
(flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "",
(flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "",
(flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE) ? " no_read_workqueue" : "",
(flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) ? " no_write_workqueue" : "",
(flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) ? " iv_large_sectors" : "",
(flags & CRYPT_ACTIVATE_HIGH_PRIORITY) ? " high_priority" : "",
(tgt->u.crypt.sector_size != SECTOR_SIZE) ?
_uf(sector_feature, sizeof(sector_feature), "sector_size", tgt->u.crypt.sector_size) : "",
integrity_dm);
@@ -1580,6 +1586,14 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
ret = 1;
}
/* Drop high-priority workqueue options if not supported */
if ((*dmd_flags & CRYPT_ACTIVATE_HIGH_PRIORITY) &&
!(dmt_flags & DM_CRYPT_HIGH_PRIORITY_SUPPORTED)) {
log_dbg(cd, "dm-crypt does not support high-priority option");
*dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_HIGH_PRIORITY;
ret = 1;
}
return ret;
}
@@ -1973,6 +1987,8 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags,
*act_flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
else if (!strcasecmp(arg, "iv_large_sectors"))
*act_flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
else if (!strcasecmp(arg, "high_priority"))
*act_flags |= CRYPT_ACTIVATE_HIGH_PRIORITY;
else if (sscanf(arg, "integrity:%u:", &val) == 1) {
tgt->u.crypt.tag_size = val;
rintegrity = strchr(arg + strlen("integrity:"), ':');

View File

@@ -1553,6 +1553,7 @@ static const struct {
{ CRYPT_ACTIVATE_NO_JOURNAL, "no-journal" },
{ CRYPT_ACTIVATE_NO_READ_WORKQUEUE, "no-read-workqueue" },
{ CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE, "no-write-workqueue" },
{ CRYPT_ACTIVATE_HIGH_PRIORITY, "high_priority" },
{ 0, NULL }
};

View File

@@ -63,6 +63,7 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
#define DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */
#define DM_INTEGRITY_RESET_RECALC_SUPPORTED (1 << 27) /* dm-integrity automatic recalculation supported */
#define DM_VERITY_TASKLETS_SUPPORTED (1 << 28) /* dm-verity tasklets supported */
#define DM_CRYPT_HIGH_PRIORITY_SUPPORTED (1 << 29) /* dm-crypt high priority workqueue flag supported */
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
enum tdirection { TARGET_EMPTY = 0, TARGET_SET, TARGET_QUERY };

View File

@@ -779,6 +779,17 @@ that it is maximal value, it is decreased automatically if CPU online
count is lower. This option is not available for PBKDF2.
endif::[]
ifdef::ACTION_REFRESH,ACTION_OPEN[]
*--perf-high_priority*::
Set dm-crypt workqueues and the writer thread to high priority.
This i mproves throughput and latency of dm-crypt while degrading general
responsiveness of the system.
+
*NOTE:* This option is available only for low-level dm-crypt
performance tuning, use only if you need a change to default dm-crypt
behaviour. Needs kernel 6.10 or later.
endif::[]
ifdef::ACTION_REFRESH,ACTION_OPEN[]
*--perf-no_read_workqueue, --perf-no_write_workqueue*::
Bypass dm-crypt internal workqueue and process read or write requests

View File

@@ -1075,13 +1075,15 @@ static int action_status(void)
CRYPT_ACTIVATE_SAME_CPU_CRYPT|
CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS|
CRYPT_ACTIVATE_NO_READ_WORKQUEUE|
CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE))
log_std(" flags: %s%s%s%s%s\n",
CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE|
CRYPT_ACTIVATE_HIGH_PRIORITY))
log_std(" flags: %s%s%s%s%s%s\n",
(cad.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? "discards " : "",
(cad.flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? "same_cpu_crypt " : "",
(cad.flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? "submit_from_crypt_cpus " : "",
(cad.flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE) ? "no_read_workqueue " : "",
(cad.flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) ? "no_write_workqueue" : "");
(cad.flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) ? "no_write_workqueue" : "",
(cad.flags & CRYPT_ACTIVATE_HIGH_PRIORITY) ? "high_priority" : "");
}
out:
crypt_free(cd);

View File

@@ -130,6 +130,8 @@ ARG(OPT_PBKDF_MEMORY, '\0', POPT_ARG_STRING, N_("PBKDF memory cost limit"), N_("
ARG(OPT_PBKDF_PARALLEL, '\0', POPT_ARG_STRING, N_("PBKDF parallel cost"), N_("threads"), CRYPT_ARG_UINT32, { .u32_value = DEFAULT_LUKS2_PARALLEL_THREADS }, {})
ARG(OPT_PERF_HIGH_PRIORITY, '\0', POPT_ARG_NONE, N_("Set dm-crypt workqueues and the writer thread to high priority"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_PERF_NO_READ_WORKQUEUE, '\0', POPT_ARG_NONE, N_("Bypass dm-crypt workqueue and process read requests synchronously"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_PERF_NO_WRITE_WORKQUEUE, '\0', POPT_ARG_NONE, N_("Bypass dm-crypt workqueue and process write requests synchronously"), NULL, CRYPT_ARG_BOOL, {}, {})

View File

@@ -113,6 +113,7 @@
#define OPT_PBKDF_FORCE_ITERATIONS "pbkdf-force-iterations"
#define OPT_PBKDF_MEMORY "pbkdf-memory"
#define OPT_PBKDF_PARALLEL "pbkdf-parallel"
#define OPT_PERF_HIGH_PRIORITY "perf-high_priority"
#define OPT_PERF_NO_READ_WORKQUEUE "perf-no_read_workqueue"
#define OPT_PERF_NO_WRITE_WORKQUEUE "perf-no_write_workqueue"
#define OPT_PERF_SAME_CPU_CRYPT "perf-same_cpu_crypt"

View File

@@ -79,6 +79,9 @@ void set_activation_flags(uint32_t *flags)
if (ARG_SET(OPT_PERF_NO_WRITE_WORKQUEUE_ID))
*flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
if (ARG_SET(OPT_PERF_HIGH_PRIORITY_ID))
*flags |= CRYPT_ACTIVATE_HIGH_PRIORITY;
if (ARG_SET(OPT_INTEGRITY_NO_JOURNAL_ID))
*flags |= CRYPT_ACTIVATE_NO_JOURNAL;

View File

@@ -106,6 +106,9 @@ function dm_crypt_features()
[ $VER_MIN -lt 22 ] && return
DM_PERF_NO_WORKQUEUE=1
[ $VER_MIN -lt 26 ] && return
DM_PERF_HIGH_PRIORITY=1
}
format() # format
@@ -189,6 +192,12 @@ else
$CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail
check_io
fi
if [ -n "$DM_PERF_HIGH_PRIORITY" ]; then
echo -n "high_priority "
echo -e "$PWD1" | $CRYPTSETUP refresh $PLAIN_OPT -q $DEV_NAME --perf-high_priority || fail
$CRYPTSETUP status $DEV_NAME | grep -q high_priority || fail
check_io
fi
$CRYPTSETUP close $DEV_NAME || fail
echo
@@ -220,6 +229,11 @@ else
$CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail
$CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail
fi
if [ -n "$DM_PERF_HIGH_PRIORITY" ]; then
echo -n "high_priority "
echo -e "$PWD1" | $CRYPTSETUP refresh $DEV_NAME --perf-high_priority || fail
$CRYPTSETUP status $DEV_NAME | grep -q high_priority || fail
fi
$CRYPTSETUP close $DEV_NAME || fail
echo
@@ -289,6 +303,14 @@ else
$CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail
$CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail
fi
if [ -n "$DM_PERF_HIGH_PRIORITY" ]; then
echo -n "high_priority "
echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --perf-high_priority --persistent || fail
$CRYPTSETUP status $DEV_NAME | grep -q high_priority || fail
$CRYPTSETUP close $DEV_NAME || fail
echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME || fail
$CRYPTSETUP status $DEV_NAME | grep -q high_priority || fail
fi
echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME2 2>/dev/null && fail
$CRYPTSETUP close $DEV_NAME || fail
echo