From: Filipe Manana <fdmanana(a)suse.com>
commit 8184620ae21213d51eaf2e0bd4186baacb928172 upstream.
When doing a direct IO write using a iocb with nowait and dsync set, we
end up not syncing the file once the write completes.
This is because we tell iomap to not call generic_write_sync(), which
would result in calling btrfs_sync_file(), in order to avoid a deadlock
since iomap can call it while we are holding the inode's lock and
btrfs_sync_file() needs to acquire the inode's lock. The deadlock happens
only if the write happens synchronously, when iomap_dio_rw() calls
iomap_dio_complete() before it returns. Instead we do the sync ourselves
at btrfs_do_write_iter().
For a nowait write however we can end up not doing the sync ourselves at
at btrfs_do_write_iter() because the write could have been queued, and
therefore we get -EIOCBQUEUED returned from iomap in such case. That makes
us skip the sync call at btrfs_do_write_iter(), as we don't do it for
any error returned from btrfs_direct_write(). We can't simply do the call
even if -EIOCBQUEUED is returned, since that would block the task waiting
for IO, both for the data since there are bios still in progress as well
as potentially blocking when joining a log transaction and when syncing
the log (writing log trees, super blocks, etc).
So let iomap do the sync call itself and in order to avoid deadlocks for
the case of synchronous writes (without nowait), use __iomap_dio_rw() and
have ourselves call iomap_dio_complete() after unlocking the inode.
A test case will later be sent for fstests, after this is fixed in Linus'
tree.
Fixes: 51bd9563b678 ("btrfs: fix deadlock due to page faults during direct IO reads and writes")
Reported-by: Марк Коренберг <socketpair(a)gmail.com>
Link: https://lore.kernel.org/linux-btrfs/CAEmTpZGRKbzc16fWPvxbr6AfFsQoLmz-Lcg-7O…
CC: stable(a)vger.kernel.org # 6.0+
Signed-off-by: Filipe Manana <fdmanana(a)suse.com>
Signed-off-by: David Sterba <dsterba(a)suse.com>
---
The commit in the Fixes tag was backported to 5.15 stable releases, so
this patch is meant for 5.15.x and was tested on top of 5.15.77.
fs/btrfs/file.c | 39 ++++++++++++++++-----------------------
1 file changed, 16 insertions(+), 23 deletions(-)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 1c597cd6c024..90934711dcf0 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1906,7 +1906,6 @@ static ssize_t check_direct_IO(struct btrfs_fs_info *fs_info,
static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
{
- const bool is_sync_write = (iocb->ki_flags & IOCB_DSYNC);
struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file);
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -1917,6 +1916,7 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
loff_t endbyte;
ssize_t err;
unsigned int ilock_flags = 0;
+ struct iomap_dio *dio;
if (iocb->ki_flags & IOCB_NOWAIT)
ilock_flags |= BTRFS_ILOCK_TRY;
@@ -1959,15 +1959,6 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
goto buffered;
}
- /*
- * We remove IOCB_DSYNC so that we don't deadlock when iomap_dio_rw()
- * calls generic_write_sync() (through iomap_dio_complete()), because
- * that results in calling fsync (btrfs_sync_file()) which will try to
- * lock the inode in exclusive/write mode.
- */
- if (is_sync_write)
- iocb->ki_flags &= ~IOCB_DSYNC;
-
/*
* The iov_iter can be mapped to the same file range we are writing to.
* If that's the case, then we will deadlock in the iomap code, because
@@ -1986,12 +1977,23 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
* So here we disable page faults in the iov_iter and then retry if we
* got -EFAULT, faulting in the pages before the retry.
*/
-again:
from->nofault = true;
- err = iomap_dio_rw(iocb, from, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
- IOMAP_DIO_PARTIAL, written);
+ dio = __iomap_dio_rw(iocb, from, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
+ IOMAP_DIO_PARTIAL, written);
from->nofault = false;
+ /*
+ * iomap_dio_complete() will call btrfs_sync_file() if we have a dsync
+ * iocb, and that needs to lock the inode. So unlock it before calling
+ * iomap_dio_complete() to avoid a deadlock.
+ */
+ btrfs_inode_unlock(inode, ilock_flags);
+
+ if (IS_ERR_OR_NULL(dio))
+ err = PTR_ERR_OR_ZERO(dio);
+ else
+ err = iomap_dio_complete(dio);
+
/* No increment (+=) because iomap returns a cumulative value. */
if (err > 0)
written = err;
@@ -2017,19 +2019,10 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
} else {
fault_in_iov_iter_readable(from, left);
prev_left = left;
- goto again;
+ goto relock;
}
}
- btrfs_inode_unlock(inode, ilock_flags);
-
- /*
- * Add back IOCB_DSYNC. Our caller, btrfs_file_write_iter(), will do
- * the fsync (call generic_write_sync()).
- */
- if (is_sync_write)
- iocb->ki_flags |= IOCB_DSYNC;
-
/* If 'err' is -ENOTBLK then it means we must fallback to buffered IO. */
if ((err < 0 && err != -ENOTBLK) || !iov_iter_count(from))
goto out;
--
2.34.1
Returning true from handle_rx_dma() without flushing DMA first creates
a data ordering hazard. If DMA Rx has handled any character at the
point when RLSI occurs, the non-DMA path handles any pending characters
jumping them ahead of those characters that are pending under DMA.
Fixes: 75df022b5f89 ("serial: 8250_dma: Fix RX handling")
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen(a)linux.intel.com>
---
Cc: Gilles BULOZ <gilles.buloz(a)kontron.com>
drivers/tty/serial/8250/8250_port.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 92dd18716169..388172289627 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1901,10 +1901,9 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
if (!up->dma->rx_running)
break;
fallthrough;
+ case UART_IIR_RLSI:
case UART_IIR_RX_TIMEOUT:
serial8250_rx_dma_flush(up);
- fallthrough;
- case UART_IIR_RLSI:
return true;
}
return up->dma->rx_dma(up);
--
2.30.2
Configure DMA to use 16B burst size with Elkhart Lake. This makes the
bus use more efficient and works around an issue which occurs with the
previously used 1B.
Fixes: 0a9410b981e9 ("serial: 8250_lpss: Enable DMA on Intel Elkhart Lake")
Cc: <stable(a)vger.kernel.org> # serial: 8250_lpss: Configure DMA also w/o DMA filter
Reported-by: Wentong Wu <wentong.wu(a)intel.com>
Co-developed-by: Srikanth Thokala <srikanth.thokala(a)intel.com>
Signed-off-by: Srikanth Thokala <srikanth.thokala(a)intel.com>
Co-developed-by: Aman Kumar <aman.kumar(a)intel.com>
Signed-off-by: Aman Kumar <aman.kumar(a)intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen(a)linux.intel.com>
---
I know the list of Co-dev-bys & Sob seems a bit odd for a oneliner.
The reason is that I cleaned up this from a more complex patch using
the earlier change that I authored myself so only this oneliner
remained in this patch.
---
drivers/tty/serial/8250/8250_lpss.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c
index ed281445a97d..e0b4e1446eac 100644
--- a/drivers/tty/serial/8250/8250_lpss.c
+++ b/drivers/tty/serial/8250/8250_lpss.c
@@ -174,6 +174,8 @@ static int ehl_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
*/
up->dma = dma;
+ lpss->dma_maxburst = 16;
+
port->set_termios = dw8250_do_set_termios;
return 0;
--
2.30.2
DW UART sometimes triggers IIR_RDI during DMA Rx when IIR_RX_TIMEOUT
should have been triggered instead. Since IIR_RDI has higher priority
than IIR_RX_TIMEOUT, this causes the Rx to hang into interrupt loop.
The problem seems to occur at least with some combinations of
small-sized transfers (I've reproduced the problem on Elkhart Lake PSE
UARTs).
If there's already an on-going Rx DMA and IIR_RDI triggers, fall
graciously back to non-DMA Rx. That is, behave as if IIR_RX_TIMEOUT had
occurred.
8250_omap already considers IIR_RDI similar to this change so its
nothing unheard of.
Fixes: 75df022b5f89 ("serial: 8250_dma: Fix RX handling")
Cc: <stable(a)vger.kernel.org>
Co-developed-by: Srikanth Thokala <srikanth.thokala(a)intel.com>
Signed-off-by: Srikanth Thokala <srikanth.thokala(a)intel.com>
Co-developed-by: Aman Kumar <aman.kumar(a)intel.com>
Signed-off-by: Aman Kumar <aman.kumar(a)intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen(a)linux.intel.com>
---
drivers/tty/serial/8250/8250_port.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index fe8662cd9402..92dd18716169 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1897,6 +1897,10 @@ EXPORT_SYMBOL_GPL(serial8250_modem_status);
static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
{
switch (iir & 0x3f) {
+ case UART_IIR_RDI:
+ if (!up->dma->rx_running)
+ break;
+ fallthrough;
case UART_IIR_RX_TIMEOUT:
serial8250_rx_dma_flush(up);
fallthrough;
--
2.30.2
On Tue, 01 Nov 2022, Rob Herring wrote:
> It's been a while since the last sync and Lee needs commit 73590342fc85
> ("libfdt: prevent integer overflow in fdt_next_tag").
>
> This adds the following commits from upstream:
>
> 55778a03df61 libfdt: tests: add get_next_tag_invalid_prop_len
> 73590342fc85 libfdt: prevent integer overflow in fdt_next_tag
> 035fb90d5375 libfdt: add fdt_get_property_by_offset_w helper
> 98a07006c48d Makefile: fix infinite recursion by dropping non-existent `%.output`
> a036cc7b0c10 Makefile: limit make re-execution to avoid infinite spin
> c6e92108bcd9 libdtc: remove duplicate judgments
> e37c25677dc9 Don't generate erroneous fixups from reference to path
> 50454658f2b5 libfdt: Don't mask fdt_get_name() returned error
> e64a204196c9 manual.txt: Follow README.md and remove Jon
> f508c83fe6f0 Update README in MANIFEST.in and setup.py to README.md
> c2ccf8a77dd2 Add description of Signed-off-by lines
> 90b9d9de42ca Split out information for contributors to CONTRIBUTING.md
> 0ee1d479b23a Remove Jon Loeliger from maintainers list
> b33a73c62c1c Convert README to README.md
> 7ad60734b1c1 Allow static building with meson
> fd9b8c96c780 Allow static building with make
> fda71da26e7f libfdt: Handle failed get_name() on BEGIN_NODE
> c7c7f17a83d5 Fix test script to run also on dash shell
> 01f23ffe1679 Add missing relref_merge test to meson test list
> ed310803ea89 pylibfdt: add FdtRo.get_path()
> c001fc01a43e pylibfdt: fix swig build in install
> 26c54f840d23 tests: add test cases for label-relative path references
> ec7986e682cf dtc: introduce label relative path references
> 651410e54cb9 util: introduce xstrndup helper
> 4048aed12b81 setup.py: fix out of tree build
> ff5afb96d0c0 Handle integer overflow in check_property_phandle_args()
> ca7294434309 README: Explain how to add a new API function
> c0c2e115f82e Fix a UB when fdt_get_string return null
> cd5f69cbc0d4 tests: setprop_inplace: use xstrdup instead of unchecked strdup
> a04f69025003 pylibfdt: add Property.as_*int*_array()
> 83102717d7c4 pylibfdt: add Property.as_stringlist()
> d152126bb029 Fix Python crash on getprop deallocation
> 17739b7ef510 Support 'r' format for printing raw bytes with fdtget
> 45f3d1a095dd libfdt: overlay: make overlay_get_target() public
> c19a4bafa514 libfdt: fix an incorrect integer promotion
> 1cc41b1c969f pylibfdt: Add packaging metadata
> db72398cd437 README: Update pylibfdt install instructions
> 383e148b70a4 pylibfdt: fix with Python 3.10
> 23b56cb7e189 pylibfdt: Move setup.py to the top level
> 69a760747d8d pylibfdt: Split setup.py author name and email
> 0b106a77dbdc pylibfdt: Use setuptools_scm for the version
> c691776ddb26 pylibfdt: Use setuptools instead of distutils
> 5216f3f1bbb7 libfdt: Add static lib to meson build
> 4eda2590f481 CI: Cirrus: bump used FreeBSD from 12.1 to 13.0
At least one of these patches fixes security concerns.
Could we also have this in Stable please?
> Signed-off-by: Rob Herring <robh(a)kernel.org>
> ---
> scripts/dtc/checks.c | 15 +++++++-----
> scripts/dtc/dtc-lexer.l | 2 +-
> scripts/dtc/dtc-parser.y | 13 ++++++++++
> scripts/dtc/libfdt/fdt.c | 20 +++++++++------
> scripts/dtc/libfdt/fdt.h | 4 +--
> scripts/dtc/libfdt/fdt_addresses.c | 2 +-
> scripts/dtc/libfdt/fdt_overlay.c | 29 ++++++----------------
> scripts/dtc/libfdt/fdt_ro.c | 2 +-
> scripts/dtc/libfdt/libfdt.h | 25 +++++++++++++++++++
> scripts/dtc/livetree.c | 39 +++++++++++++++++++++++++++---
> scripts/dtc/util.c | 15 ++++++++++--
> scripts/dtc/util.h | 4 ++-
> scripts/dtc/version_gen.h | 2 +-
> 13 files changed, 124 insertions(+), 48 deletions(-)
--
Lee Jones [李琼斯]
Hei ja miten voit?
Nimeni on rouva Evereen, lähetän tämän viestin suurella toivolla
välitön vastaus, koska minun on tehtävä uusi sydänleikkaus
tällä hetkellä huonokuntoinen ja vähäiset mahdollisuudet selviytyä.
Mutta ennen kuin minä
Tee toinen vaarallinen operaatio, annan sen sinulle
Minulla on 6 550 000 dollaria yhdysvaltalaisella pankkitilillä
sijoittamista, hallinnointia ja käyttöä varten
voittoa hyväntekeväisyysprojektin toteuttamiseen. Tarkoitan sairaiden auttamista
ja köyhät ovat viimeinen haluni maan päällä, sillä minulla ei ole niitä
keneltä perii rahaa.
Vastaa minulle nopeasti
terveisiä
Rouva Monika Evereen
Florida, Amerikan Yhdysvallat
=======================================================
Hi and how are you?
My name is Mrs. Evereen, I am sending this message with great hope for
an immediate response, as I have to undergo heart reoperation in my
current poor health with little chance of survival. But before I
undertake the second dangerous operation, I will give you the
$6,550,000 I have in my US bank account to invest well, manage and use
the profits to run a charity project for me. I count helping the sick
and the poor as my last wish on earth, because I have no one to
inherit money from.
Please give me a quick reply
regards
Mrs. Monika Evereen
Florida, United States of America
This bug is marked as fixed by commit:
net: core: netlink: add helper refcount dec and lock function
net: sched: add helper function to take reference to Qdisc
net: sched: extend Qdisc with rcu
net: sched: rename qdisc_destroy() to qdisc_put()
net: sched: use Qdisc rcu API instead of relying on rtnl lock
But I can't find it in any tested tree for more than 90 days.
Is it a correct commit? Please update it by replying:
#syz fix: exact-commit-title
Until then the bug is still considered open and
new crashes with the same signature are ignored.