diff --git a/0006-fix-rwlock-cause-schedule-bug-if-pagefault-or-wait-f.patch b/0006-fix-rwlock-cause-schedule-bug-if-pagefault-or-wait-f.patch new file mode 100644 index 0000000000000000000000000000000000000000..62245a0fbbdf5a484a5cde50c6a0db63c0b98fc0 --- /dev/null +++ b/0006-fix-rwlock-cause-schedule-bug-if-pagefault-or-wait-f.patch @@ -0,0 +1,404 @@ +From c2cfb702946d01480236b34c1dacaeca0758cff0 Mon Sep 17 00:00:00 2001 +From: liqiang +Date: Fri, 22 Nov 2024 09:31:03 +0800 +Subject: [PATCH] fix rwlock cause schedule bug if pagefault or wait for read + file page + +Signed-off-by: liqiang +--- + qtfs/include/conn.h | 2 +- + qtfs/qtfs_common/conn.c | 4 +-- + qtfs/qtfs_common/misc.c | 24 +++++++------- + qtfs/qtfs_server/fsops.c | 8 ++--- + qtfs/qtfs_server/qtfs-server.c | 57 +++++++++++++++++----------------- + qtfs/qtfs_server/qtfs-server.h | 2 +- + 6 files changed, 49 insertions(+), 48 deletions(-) + +diff --git a/qtfs/include/conn.h b/qtfs/include/conn.h +index 5f74a46..aaf746c 100644 +--- a/qtfs/include/conn.h ++++ b/qtfs/include/conn.h +@@ -206,7 +206,7 @@ struct qtfs_wl_cap { + }; + + struct qtfs_wl { +- rwlock_t rwlock; ++ struct rw_semaphore rwlock; + struct qtfs_wl_cap cap[QTFS_WHITELIST_MAX]; + }; + +diff --git a/qtfs/qtfs_common/conn.c b/qtfs/qtfs_common/conn.c +index fd5f654..1569bf8 100644 +--- a/qtfs/qtfs_common/conn.c ++++ b/qtfs/qtfs_common/conn.c +@@ -116,7 +116,7 @@ static int qtfs_uds_remote_whitelist(char *path) + int i; + int ret = 1; + struct qtfs_wl_cap *cap; +- read_lock(&g_qtfs_wl.rwlock); ++ down_read(&g_qtfs_wl.rwlock); + cap = &g_qtfs_wl.cap[QTFS_WHITELIST_UDSCONNECT]; + for (i = 0; i < cap->nums; i++) { + if (qtfs_white_list_match(path, cap->item[i], strlen(cap->item[i]), WHITELIST_MATCH_PREFIX)) { +@@ -124,7 +124,7 @@ static int qtfs_uds_remote_whitelist(char *path) + break; + } + } +- read_unlock(&g_qtfs_wl.rwlock); ++ up_read(&g_qtfs_wl.rwlock); + return ret; + } + +diff --git a/qtfs/qtfs_common/misc.c b/qtfs/qtfs_common/misc.c +index 3adfb57..1c57a85 100644 +--- a/qtfs/qtfs_common/misc.c ++++ b/qtfs/qtfs_common/misc.c +@@ -137,7 +137,7 @@ void qtfs_req_size(void) + void qtfs_whitelist_initset(void) + { + int type; +- rwlock_init(&g_qtfs_wl.rwlock); ++ init_rwsem(&g_qtfs_wl.rwlock); + for (type = 0; type < QTFS_WHITELIST_MAX; type++) { + memset(&g_qtfs_wl.cap[type], 0, sizeof(struct qtfs_wl_cap)); + } +@@ -158,7 +158,7 @@ static int qtfs_whitelist_add(struct qtfs_wl_item *uitem) + { + // uitem->type is checked + struct qtfs_wl_cap *cap = &g_qtfs_wl.cap[uitem->type]; +- write_lock(&g_qtfs_wl.rwlock); ++ down_write(&g_qtfs_wl.rwlock); + if (cap->nums >= QTFS_WL_MAX_NUM) { + qtfs_err("qtfs add white list failed, nums:%u reach upper limit:%d", cap->nums, QTFS_WL_MAX_NUM); + goto err_end; +@@ -178,11 +178,11 @@ static int qtfs_whitelist_add(struct qtfs_wl_item *uitem) + } + qtfs_info("Successed to add white list type:%u len:%u path:[%s]", uitem->type, uitem->len, cap->item[cap->nums]); + cap->nums++; +- write_unlock(&g_qtfs_wl.rwlock); ++ up_write(&g_qtfs_wl.rwlock); + return 0; + + err_end: +- write_unlock(&g_qtfs_wl.rwlock); ++ up_write(&g_qtfs_wl.rwlock); + return -1; + } + +@@ -190,7 +190,7 @@ static int qtfs_whitelist_del(struct qtfs_wl_item *uitem) + { + // type is checked + struct qtfs_wl_cap *cap = &g_qtfs_wl.cap[uitem->type]; +- write_lock(&g_qtfs_wl.rwlock); ++ down_write(&g_qtfs_wl.rwlock); + if (uitem->index >= cap->nums) { + qtfs_err("White list del type:%u nums:%u, invalid index:%u", uitem->type, cap->nums, uitem->index); + goto err_end; +@@ -206,10 +206,10 @@ static int qtfs_whitelist_del(struct qtfs_wl_item *uitem) + qtfs_info("white list del type:%u total nums:%u delindex:%u", uitem->type, cap->nums, uitem->index); + + cap->nums--; +- write_unlock(&g_qtfs_wl.rwlock); ++ up_write(&g_qtfs_wl.rwlock); + return 0; + err_end: +- write_unlock(&g_qtfs_wl.rwlock); ++ up_write(&g_qtfs_wl.rwlock); + return -1; + } + +@@ -218,7 +218,7 @@ static int qtfs_whitelist_get(struct qtfs_wl_item *uitem) + // type is checked + struct qtfs_wl_cap *cap = &g_qtfs_wl.cap[uitem->type]; + int len; +- read_lock(&g_qtfs_wl.rwlock); ++ down_read(&g_qtfs_wl.rwlock); + if (uitem->index >= cap->nums) { + qtfs_err("query white list invalid index:%u type:%u total nums:%u", uitem->index, uitem->type, cap->nums); + goto err_end; +@@ -233,11 +233,11 @@ static int qtfs_whitelist_get(struct qtfs_wl_item *uitem) + goto err_end; + } + qtfs_info("white list query type:%u total nums:%u index:%u len:%d", uitem->type, cap->nums, uitem->index, len); +- read_unlock(&g_qtfs_wl.rwlock); ++ up_read(&g_qtfs_wl.rwlock); + return 0; + + err_end: +- read_unlock(&g_qtfs_wl.rwlock); ++ up_read(&g_qtfs_wl.rwlock); + return -1; + } + +@@ -246,7 +246,7 @@ void qtfs_whitelist_clearall(void) + struct qtfs_wl_cap *cap = NULL; + int type; + int item; +- write_lock(&g_qtfs_wl.rwlock); ++ down_write(&g_qtfs_wl.rwlock); + for (type = 0; type < QTFS_WHITELIST_MAX; type++) { + cap = &g_qtfs_wl.cap[type]; + for (item = 0; item < cap->nums; item++) { +@@ -255,7 +255,7 @@ void qtfs_whitelist_clearall(void) + } + cap->nums = 0; + } +- write_unlock(&g_qtfs_wl.rwlock); ++ up_write(&g_qtfs_wl.rwlock); + return; + } + +diff --git a/qtfs/qtfs_server/fsops.c b/qtfs/qtfs_server/fsops.c +index f2f3749..f0dce2c 100644 +--- a/qtfs/qtfs_server/fsops.c ++++ b/qtfs/qtfs_server/fsops.c +@@ -62,7 +62,7 @@ static bool _in_white_list(char *path, int type, int match_type) + return false; + } + +- read_lock(&g_qtfs_wl.rwlock); ++ down_read(&g_qtfs_wl.rwlock); + cap = &g_qtfs_wl.cap[type]; + for (i = 0; i < cap->nums; i++) { + if (qtfs_white_list_match(path, cap->item[i], strlen(cap->item[i]), match_type)) { +@@ -70,7 +70,7 @@ static bool _in_white_list(char *path, int type, int match_type) + break; + } + } +- read_unlock(&g_qtfs_wl.rwlock); ++ up_read(&g_qtfs_wl.rwlock); + return in_wl != -1; + } + +@@ -1736,12 +1736,12 @@ int qtfs_conn_server_run(struct qtfs_conn_var_s *pvar) + qtfs_err("qtfs server req type:%u precheck failed.", req->type); + goto out; + } +- read_lock(&g_userp_rwlock); ++ down_read(&g_userp_rwlock); + arg.userp = &qtfs_userps[pvar->cur_threadidx]; + if (arg.userp->userp == NULL || arg.userp->userp2 == NULL) + qtfs_err("server run userp or userp2 is invalid"); + rsp->len = qtfs_server_handles[req->type].handle(&arg); +- read_unlock(&g_userp_rwlock); ++ up_read(&g_userp_rwlock); + rsp->type = req->type; + rsp->err = QTFS_OK; + totalproc++; +diff --git a/qtfs/qtfs_server/qtfs-server.c b/qtfs/qtfs_server/qtfs-server.c +index 48248ba..f7907ca 100644 +--- a/qtfs/qtfs_server/qtfs-server.c ++++ b/qtfs/qtfs_server/qtfs-server.c +@@ -28,7 +28,7 @@ + #define QTFS_EPOLL_RETRY_INTVL 500 // unit ms + + int qtfs_server_thread_run = 1; +-DEFINE_RWLOCK(g_userp_rwlock); ++struct rw_semaphore g_userp_rwlock; + struct qtserver_fd_bitmap qtfs_fd_bitmap; + + long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +@@ -44,18 +44,18 @@ struct qtfs_server_epoll_s qtfs_epoll = { + .events = NULL, + .kevents = NULL, + }; +-rwlock_t qtfs_epoll_rwlock; ++struct rw_semaphore qtfs_epoll_rwlock; + + void qtfs_server_epoll_exit(void) + { +- write_lock(&qtfs_epoll_rwlock); ++ down_write(&qtfs_epoll_rwlock); + if (qtfs_epoll.kevents == NULL) { +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + return; + } + kfree(qtfs_epoll.kevents); + qtfs_epoll.kevents = NULL; +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + return; + } + +@@ -211,35 +211,35 @@ long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long a + } else { + qtfs_conn_put_param(pvar); + } +- if (!write_trylock(&g_userp_rwlock)) { ++ if (!down_write_trylock(&g_userp_rwlock)) { + qtfs_err("try lock userps failed."); + return QTERROR; + } + if (qtfs_server_fd_bitmap_init() < 0) { + qtfs_err("fd bitmap init failed."); +- write_unlock(&g_userp_rwlock); ++ up_write(&g_userp_rwlock); + return QTERROR; + } + if (copy_from_user(&init_userp, (void __user *)arg, sizeof(struct qtfs_thread_init_s))) { + qtfs_err("qtfs ioctl thread init copy from user failed."); +- write_unlock(&g_userp_rwlock); ++ up_write(&g_userp_rwlock); + return QTERROR; + } + if (qtfs_userps == NULL || init_userp.thread_nums > QTFS_MAX_THREADS || init_userp.thread_nums == 0) { + qtfs_err("qtfs ioctl thread init userps invalid thread nums:%d.", init_userp.thread_nums); +- write_unlock(&g_userp_rwlock); ++ up_write(&g_userp_rwlock); + return QTERROR; + } + memset(qtfs_userps, 0, QTFS_MAX_THREADS * sizeof(struct qtfs_server_userp_s)); + if (init_userp.thread_nums > QTFS_MAX_THREADS) { + qtfs_err("qtfs ioctl thread init invalid input thread_num:%d", init_userp.thread_nums); +- write_unlock(&g_userp_rwlock); ++ up_write(&g_userp_rwlock); + return QTERROR; + } + if (copy_from_user(qtfs_userps, (void __user *)init_userp.userp, + init_userp.thread_nums * sizeof(struct qtfs_server_userp_s))) { + qtfs_err("qtfs ioctl thread init copy from userp failed."); +- write_unlock(&g_userp_rwlock); ++ up_write(&g_userp_rwlock); + return QTERROR; + } + for (i = 0; i < init_userp.thread_nums; i++) { +@@ -248,12 +248,12 @@ long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long a + !access_ok(qtfs_userps[i].userp2, qtfs_userps[i].size)) { + qtfs_err("userp set failed"); + ret = QTERROR; +- write_unlock(&g_userp_rwlock); ++ up_write(&g_userp_rwlock); + break; + } + qtfs_info("userp set idx:%d size:%lu", i, qtfs_userps[i].size); + } +- write_unlock(&g_userp_rwlock); ++ up_write(&g_userp_rwlock); + break; + case QTFS_IOCTL_THREAD_RUN: + pvar = qtfs_conn_get_param(); +@@ -268,7 +268,7 @@ long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long a + qtfs_conn_put_param(pvar); + break; + case QTFS_IOCTL_EPFDSET: +- write_lock(&qtfs_epoll_rwlock); ++ down_write(&qtfs_epoll_rwlock); + if (qtfs_epoll.kevents != NULL) { + kfree(qtfs_epoll.kevents); + qtfs_epoll.kevents = NULL; +@@ -276,25 +276,25 @@ long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long a + if (copy_from_user(&qtfs_epoll, (void __user *)arg, sizeof(struct qtfs_server_epoll_s))) { + qtfs_err("copy epoll struct from arg failed."); + ret = QTERROR; +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + break; + } + if (qtfs_epoll.event_nums > QTFS_MAX_EPEVENTS_NUM || qtfs_epoll.event_nums == 0) { + qtfs_err("epoll arg set failed, event nums:%d too big", qtfs_epoll.event_nums); + ret = QTERROR; +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + break; + } + if (qtfs_epoll.epfd < 3) { + qtfs_err("epoll epfd set failed, epfd:%d should be greater than 2", qtfs_epoll.epfd); + ret = QTERROR; +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + break; + } + if (!access_ok(qtfs_epoll.events, qtfs_epoll.event_nums * sizeof(struct epoll_event))) { + qtfs_err("epoll events set failed, check pointer of qtfs_epoll.events failed"); + ret = QTERROR; +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + break; + } + qtfs_info("epoll arg set, epfd:%d event nums:%d events.", +@@ -304,31 +304,31 @@ long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long a + if (qtfs_epoll.kevents == NULL) { + qtfs_err("epoll kernel events kmalloc failed."); + ret = QTERROR; +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + break; + } +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + break; + case QTFS_IOCTL_EPOLL_THREAD_INIT: + #ifdef EPOLL_PROXY +- write_lock(&qtfs_epoll_rwlock); ++ down_write(&qtfs_epoll_rwlock); + ret = qtfs_server_epoll_init(); +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + #else + qtfs_warn("Qtfs not support epoll proxy, please compile with EPOLL_PROXY=1 to enable it."); + #endif + break; + case QTFS_IOCTL_EPOLL_THREAD_RUN: + #ifdef EPOLL_PROXY +- write_lock(&qtfs_epoll_rwlock); ++ down_write(&qtfs_epoll_rwlock); + if (qtfs_epoll_var == NULL) { + qtfs_err("qtfs epoll thread run failed, var is invalid."); + ret = QTERROR; +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + break; + } + ret = qtfs_server_epoll_thread(qtfs_epoll_var); +- write_unlock(&qtfs_epoll_rwlock); ++ up_write(&qtfs_epoll_rwlock); + if (ret == QTEXIT) { + qtfs_info("qtfs epoll thread exit."); + qtfs_epoll_cut_conn(qtfs_epoll_var); +@@ -367,9 +367,10 @@ long qtfs_server_misc_ioctl(struct file *file, unsigned int cmd, unsigned long a + static int __init qtfs_server_init(void) + { + qtfs_log_init(qtfs_log_level, sizeof(qtfs_log_level)); ++ init_rwsem(&g_userp_rwlock); + if (qtfs_kallsyms_hack_init() != 0) + return -1; +- rwlock_init(&qtfs_epoll_rwlock); ++ init_rwsem(&qtfs_epoll_rwlock); + qtfs_whitelist_initset(); + + qtfs_diag_info = (struct qtinfo *)kmalloc(sizeof(struct qtinfo), GFP_KERNEL); +@@ -426,7 +427,7 @@ static void __exit qtfs_server_exit(void) + kfree(qtfs_diag_info); + qtfs_diag_info = NULL; + } +- write_lock(&g_userp_rwlock); ++ down_write(&g_userp_rwlock); + if (qtfs_userps != NULL) { + kfree(qtfs_userps); + qtfs_userps = NULL; +@@ -436,7 +437,7 @@ static void __exit qtfs_server_exit(void) + qtfs_fd_bitmap.bitmap = NULL; + qtfs_fd_bitmap.nbits = 0; + } +- write_unlock(&g_userp_rwlock); ++ up_write(&g_userp_rwlock); + qtfs_whitelist_exit(); + qtfs_server_epoll_exit(); + +diff --git a/qtfs/qtfs_server/qtfs-server.h b/qtfs/qtfs_server/qtfs-server.h +index 8135dbb..fa49ad9 100644 +--- a/qtfs/qtfs_server/qtfs-server.h ++++ b/qtfs/qtfs_server/qtfs-server.h +@@ -17,7 +17,7 @@ + extern int qtfs_server_thread_run; + extern struct qtfs_server_epoll_s qtfs_epoll; + extern int qtfs_mod_exiting; +-extern rwlock_t g_userp_rwlock; ++extern struct rw_semaphore g_userp_rwlock; + extern struct qtserver_fd_bitmap qtfs_fd_bitmap; + + struct qtserver_arg { +-- +2.39.2 (Apple Git-143) + diff --git a/dpu-utilities.spec b/dpu-utilities.spec index 6018af5031acea46417621faf39a3e1f19579466..11e83b9cd8c277b8e970b16f213288c153624b6f 100644 --- a/dpu-utilities.spec +++ b/dpu-utilities.spec @@ -1,7 +1,7 @@ Name: dpu-utilities Summary: openEuler dpu utilities Version: 1.10 -Release: 6 +Release: 7 License: GPL-2.0 Source: https://gitee.com/openeuler/dpu-utilities/repository/archive/v%{version}.tar.gz ExclusiveOS: linux @@ -18,6 +18,7 @@ Patch2: 0002-fix-readdir-bug-in-devtmpfs.patch Patch3: 0003-Change-the-maximum-number-of-qtfs-links-from-16-to-6.patch Patch4: 0004-add-compile-option-of-EPOLL_PROXY-and-fix-some-probl.patch Patch5: 0005-resolve-migration-issues.patch +Patch6: 0006-fix-rwlock-cause-schedule-bug-if-pagefault-or-wait-f.patch %description This package contains the software utilities on dpu. @@ -145,6 +146,9 @@ sed -i '/# product cut_conf/a\dpuos kiwi/minios/cfg_dpuos yes' /opt/imageT sed -i '//a\dpuos 1 rpm-dir euler_base' /opt/imageTailor/repos/RepositoryRule.conf %changelog +* Fri Nov 22 2024 liqiang 1.10-7 +- Fix rwlock caused schedule bug, change to semaphore + * Mon Oct 21 2024 l30022887 1.10-6 - resolve migration issues