hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAASLU
--------------------------------
When multiple processes or threads write to the same file concurrently,
if a network disruption occurs during the write operation, it may lead
to a deadlock situation as follow:
Process 1 (dd) Process 2 (cifsd) Process 3 (cifsiod)
cifs_writepages
lock_page - [1]
wait_on_page_writeback - [2] Waiting for writeback, blocked by [4]
wait_on_page_bit
cifs_demultiplex_thread
cifs_read_from_socket
cifs_readv_from_socket
- If another process triggers reconnect at this point
cifs_reconnect
- mid->mid_state updated to MID_RETRY_NEEDED
smb2_writev_callback mid_entry->callback()
- mid_state leads to wdata->result = -EAGAIN
wdata->result = -EAGAIN
queue_work(cifsiod_wq, &wdata->work);
cifs_writev_complete - work function
- Condition satisfied
- wdata->result == -EAGAIN
cifs_writev_requeue
lock_page - [3] Blocked by [1]
end_page_writeback
- [4] Won't execute, blocked by [3]
unlock_page
Mainline refactoring patch d08089f649a0 ("cifs: Change the I/O paths to
use an iterator rather than a page list") unlock page while waiting for
the writeback to complete, thus avoiding potential deadlocks caused by
lock ordering issues during reconnection.
Due to the large refactor of the mainline, the patch cannot be backport
directly. Therefore, This patch only uses a part of the idea of the
mainline patch to fix deadlock.
Fixes: c28c89fc43e3 ("cifs: add cifs_async_writev")
Signed-off-by: Wang Zhaolong <wangzhaolong1(a)huawei.com>
---
fs/cifs/file.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 0b840555a175..e0c10fd93b64 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2223,6 +2223,7 @@ wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
* back from swapper_space to tmpfs file mapping
*/
+relock_recheck:
if (nr_pages == 0)
lock_page(page);
else if (!trylock_page(page))
@@ -2245,11 +2246,16 @@ wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
break;
}
- if (wbc->sync_mode != WB_SYNC_NONE)
- wait_on_page_writeback(page);
+ if (PageWriteback(page)) {
+ unlock_page(page);
+ if (wbc->sync_mode != WB_SYNC_NONE) {
+ wait_on_page_writeback(page);
+ goto relock_recheck;
+ }
+ break;
+ }
- if (PageWriteback(page) ||
- !clear_page_dirty_for_io(page)) {
+ if (!clear_page_dirty_for_io(page)) {
unlock_page(page);
break;
}
--
2.39.2
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IA7L2U
---------------------------
If the chip not having RDT function, resctrl_arch_system_num_rmid_idx()
would return 0. rmid_ptrs points to an illegal buffer after kcalloc()
allocation, which would cause illegal access fault when accessing.
Consequently, when we found resctrl_arch_system_num_rmid_idx() return 0,
just return EOPNOTSUPP immediatly and skip initializing the resctrl file
system.
Signed-off-by: Zeng Heng <zengheng4(a)huawei.com>
---
fs/resctrl/monitor.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index 6ef878f5afdd..a7bd84f9a440 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -728,6 +728,9 @@ static int dom_data_init(struct rdt_resource *r)
int err = 0, i;
u32 idx;
+ if (!idx_limit)
+ return -EOPNOTSUPP;
+
mutex_lock(&rdtgroup_mutex);
if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
u32 *tmp;
--
2.25.1
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAASLU
--------------------------------
When multiple processes or threads write to the same file concurrently,
if a network disruption occurs during the write operation, it may lead
to a deadlock situation as follow:
Process 1 (dd) Process 2 (cifsd) Process 3 (cifsiod)
cifs_writepages
lock_page - [1]
wait_on_page_writeback - [2] Waiting for writeback, blocked by [4]
wait_on_page_bit
cifs_demultiplex_thread
cifs_read_from_socket
cifs_readv_from_socket
- If another process triggers reconnect at this point
cifs_reconnect
- mid->mid_state updated to MID_RETRY_NEEDED
smb2_writev_callback mid_entry->callback()
- mid_state leads to wdata->result = -EAGAIN
wdata->result = -EAGAIN
queue_work(cifsiod_wq, &wdata->work);
cifs_writev_complete - work function
- Condition satisfied
- wdata->result == -EAGAIN
cifs_writev_requeue
lock_page - [3] Blocked by [1]
end_page_writeback
- [4] Won't execute, blocked by [3]
unlock_page
Mainline refactoring patch d08089f649a0 ("cifs: Change the I/O paths to
use an iterator rather than a page list") unlock page while waiting for
the writeback to complete, thus avoiding potential deadlocks caused by
lock ordering issues during reconnection.
Due to the large refactor of the mainline, the patch cannot be backport
directly. Therefore, This patch only uses a part of the idea of the
mainline patch to fix deadlock.
Fixes: c28c89fc43e3 ("cifs: add cifs_async_writev")
Signed-off-by: Wang Zhaolong <wangzhaolong1(a)huawei.com>
---
fs/cifs/file.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 0b840555a175..e0c10fd93b64 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2223,6 +2223,7 @@ wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
* back from swapper_space to tmpfs file mapping
*/
+relock_recheck:
if (nr_pages == 0)
lock_page(page);
else if (!trylock_page(page))
@@ -2245,11 +2246,16 @@ wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
break;
}
- if (wbc->sync_mode != WB_SYNC_NONE)
- wait_on_page_writeback(page);
+ if (PageWriteback(page)) {
+ unlock_page(page);
+ if (wbc->sync_mode != WB_SYNC_NONE) {
+ wait_on_page_writeback(page);
+ goto relock_recheck;
+ }
+ break;
+ }
- if (PageWriteback(page) ||
- !clear_page_dirty_for_io(page)) {
+ if (!clear_page_dirty_for_io(page)) {
unlock_page(page);
break;
}
--
2.39.2
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAASLU
--------------------------------
When multiple processes or threads write to the same file concurrently,
if a network disruption occurs during the write operation, it may lead
to a deadlock situation as follow:
Process 1 (dd) Process 2 (cifsd) Process 3 (cifsiod)
cifs_writepages
lock_page - [1]
wait_on_page_writeback - [2] Waiting for writeback, blocked by [4]
wait_on_page_bit
cifs_demultiplex_thread
cifs_read_from_socket
cifs_readv_from_socket
- If another process triggers reconnect at this point
cifs_reconnect
- mid->mid_state updated to MID_RETRY_NEEDED
smb2_writev_callback mid_entry->callback()
- mid_state leads to wdata->result = -EAGAIN
wdata->result = -EAGAIN
queue_work(cifsiod_wq, &wdata->work);
cifs_writev_complete - work function
- Condition satisfied
- wdata->result == -EAGAIN
cifs_writev_requeue
lock_page - [3] Blocked by [1]
end_page_writeback
- [4] Won't execute, blocked by [3]
unlock_page
Mainline refactoring patch d08089f649a0 ("cifs: Change the I/O paths to
use an iterator rather than a page list") unlock page while waiting for
the writeback to complete, thus avoiding potential deadlocks caused by
lock ordering issues during reconnection.
Due to the large refactor of the mainline, the patch cannot be backport
directly. Therefore, This patch only uses a part of the idea of the
mainline patch to fix deadlock.
Fixes: c28c89fc43e3 ("cifs: add cifs_async_writev")
Signed-off-by: Wang Zhaolong <wangzhaolong1(a)huawei.com>
---
fs/cifs/file.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e914f4f5cc83..dc7175b75c26 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2226,6 +2226,7 @@ wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
* back from swapper_space to tmpfs file mapping
*/
+relock_recheck:
if (nr_pages == 0)
lock_page(page);
else if (!trylock_page(page))
@@ -2248,11 +2249,16 @@ wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
break;
}
- if (wbc->sync_mode != WB_SYNC_NONE)
- wait_on_page_writeback(page);
+ if (PageWriteback(page)) {
+ unlock_page(page);
+ if (wbc->sync_mode != WB_SYNC_NONE) {
+ wait_on_page_writeback(page);
+ goto relock_recheck;
+ }
+ break;
+ }
- if (PageWriteback(page) ||
- !clear_page_dirty_for_io(page)) {
+ if (!clear_page_dirty_for_io(page)) {
unlock_page(page);
break;
}
--
2.39.2
Offering: HULK
hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAASLU
--------------------------------
When multiple processes or threads write to the same file concurrently,
if a network disruption occurs during the write operation, it may lead
to a deadlock situation as follow:
Process 1 (dd) Process 2 (cifsd) Process 3 (cifsiod)
cifs_writepages
lock_page - [1]
wait_on_page_writeback - [2] Waiting for writeback, blocked by [4]
wait_on_page_bit
cifs_demultiplex_thread
cifs_read_from_socket
cifs_readv_from_socket
- If another process triggers reconnect at this point
cifs_reconnect
- mid->mid_state updated to MID_RETRY_NEEDED
smb2_writev_callback mid_entry->callback()
- mid_state leads to wdata->result = -EAGAIN
wdata->result = -EAGAIN
queue_work(cifsiod_wq, &wdata->work);
cifs_writev_complete - work function
- Condition satisfied
- wdata->result == -EAGAIN
cifs_writev_requeue
lock_page - [3] Blocked by [1]
end_page_writeback
- [4] Won't execute, blocked by [3]
unlock_page
Mainline refactoring patch d08089f649a0 ("cifs: Change the I/O paths to
use an iterator rather than a page list") unlock page while waiting for
the writeback to complete, thus avoiding potential deadlocks caused by
lock ordering issues during reconnection.
Due to the large refactor of the mainline, the patch cannot be backport
directly. Therefore, This patch only uses a part of the idea of the
mainline patch to fix deadlock.
Fixes: c28c89fc43e3 ("cifs: add cifs_async_writev")
Signed-off-by: Wang Zhaolong <wangzhaolong1(a)huawei.com>
---
fs/cifs/file.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 875cb44ba573..e346e6c2227a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2056,6 +2056,7 @@ wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
* back from swapper_space to tmpfs file mapping
*/
+relock_recheck:
if (nr_pages == 0)
lock_page(page);
else if (!trylock_page(page))
@@ -2078,11 +2079,16 @@ wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages,
break;
}
- if (wbc->sync_mode != WB_SYNC_NONE)
- wait_on_page_writeback(page);
+ if (PageWriteback(page)) {
+ unlock_page(page);
+ if (wbc->sync_mode != WB_SYNC_NONE) {
+ wait_on_page_writeback(page);
+ goto relock_recheck;
+ }
+ break;
+ }
- if (PageWriteback(page) ||
- !clear_page_dirty_for_io(page)) {
+ if (!clear_page_dirty_for_io(page)) {
unlock_page(page);
break;
}
--
2.39.2