summaryrefslogtreecommitdiffstats
path: root/scripts/atomic/fallbacks
diff options
context:
space:
mode:
authorNiklas Cassel <cassel@kernel.org>2026-09-18 16:06:42 +0200
committerJens Axboe <axboe@kernel.dk>2026-09-29 12:54:47 -0600
commit684b413b5483f57c890c171b9400076a0143b918 (patch)
treef167daddad3dce9af44773541373eafbccc9ac61 /scripts/atomic/fallbacks
downloadlinux-stable-684b413b5483f57c890c171b9400076a0143b918.tar.gz
linux-stable-684b413b5483f57c890c171b9400076a0143b918.zip
virtio_blk: set the zone write granularitygrafted
virtblk_read_zoned_limits() reads the write granularity that the device reports in virtio_blk_zoned_characteristics and assigns it to the physical block size and to io_min, but never to the limit that is named after it. queue_limits.zone_write_granularity is left at zero, so blk_validate_zoned_limits() raises it to the logical block size: if (lim->zone_write_granularity < lim->logical_block_size) lim->zone_write_granularity = lim->logical_block_size; A device that reports a granularity coarser than its logical block size, which is what the field exists to express, therefore has it silently reduced. A 512e host managed disk passed through to a guest reports a logical block size of 512 and a write granularity of 4096, and the guest ends up with a zone write granularity of 512. bio_split_alignment() returns lim->zone_write_granularity if it is non-zero and bio_split_io_at() may split a bio with as per bio_split_alignment(). This can real to the write getting rejected by the host drive, as the write is not aligned to the physical block size. zonefs also takes its block size from bdev_zone_write_granularity(), so it would incorrectly use 512 on a disk that requires 4096. sd_zbc_read_zones() sets the limit from the physical block size for the same reason. NVMe ZNS and null_blk leave it unset, but the fallback gives the right answer for them, as their write granularity is the logical block size. virtio carries a separate value that may exceed it. Set the zone write granularity from the value that the device reports. Fixes: 95bfec41bd3d ("virtio-blk: add support for zoned block devices") Signed-off-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Link: https://patch.msgid.link/20260918140641.2031075-2-cassel@kernel.org Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'scripts/atomic/fallbacks')
-rwxr-xr-xscripts/atomic/fallbacks/acquire5
-rwxr-xr-xscripts/atomic/fallbacks/add_negative3
-rwxr-xr-xscripts/atomic/fallbacks/add_unless3
-rwxr-xr-xscripts/atomic/fallbacks/andnot3
-rw-r--r--scripts/atomic/fallbacks/cmpxchg3
-rwxr-xr-xscripts/atomic/fallbacks/dec3
-rwxr-xr-xscripts/atomic/fallbacks/dec_and_test3
-rwxr-xr-xscripts/atomic/fallbacks/dec_if_positive11
-rwxr-xr-xscripts/atomic/fallbacks/dec_unless_positive10
-rwxr-xr-xscripts/atomic/fallbacks/fence7
-rwxr-xr-xscripts/atomic/fallbacks/fetch_add_unless10
-rwxr-xr-xscripts/atomic/fallbacks/inc3
-rwxr-xr-xscripts/atomic/fallbacks/inc_and_test3
-rwxr-xr-xscripts/atomic/fallbacks/inc_not_zero3
-rwxr-xr-xscripts/atomic/fallbacks/inc_unless_negative10
-rwxr-xr-xscripts/atomic/fallbacks/read_acquire12
-rwxr-xr-xscripts/atomic/fallbacks/release4
-rwxr-xr-xscripts/atomic/fallbacks/set_release8
-rwxr-xr-xscripts/atomic/fallbacks/sub_and_test3
-rwxr-xr-xscripts/atomic/fallbacks/try_cmpxchg7
-rw-r--r--scripts/atomic/fallbacks/xchg3
21 files changed, 117 insertions, 0 deletions
diff --git a/scripts/atomic/fallbacks/acquire b/scripts/atomic/fallbacks/acquire
new file mode 100755
index 000000000..4da0cab36
--- /dev/null
+++ b/scripts/atomic/fallbacks/acquire
@@ -0,0 +1,5 @@
+cat <<EOF
+ ${ret} ret = arch_${atomic}_${pfx}${name}${sfx}_relaxed(${args});
+ __atomic_acquire_fence();
+ return ret;
+EOF
diff --git a/scripts/atomic/fallbacks/add_negative b/scripts/atomic/fallbacks/add_negative
new file mode 100755
index 000000000..1d3d4ab3a
--- /dev/null
+++ b/scripts/atomic/fallbacks/add_negative
@@ -0,0 +1,3 @@
+cat <<EOF
+ return raw_${atomic}_add_return${order}(i, v) < 0;
+EOF
diff --git a/scripts/atomic/fallbacks/add_unless b/scripts/atomic/fallbacks/add_unless
new file mode 100755
index 000000000..95ecb2b74
--- /dev/null
+++ b/scripts/atomic/fallbacks/add_unless
@@ -0,0 +1,3 @@
+cat << EOF
+ return raw_${atomic}_fetch_add_unless(v, a, u) != u;
+EOF
diff --git a/scripts/atomic/fallbacks/andnot b/scripts/atomic/fallbacks/andnot
new file mode 100755
index 000000000..66760457e
--- /dev/null
+++ b/scripts/atomic/fallbacks/andnot
@@ -0,0 +1,3 @@
+cat <<EOF
+ ${retstmt}raw_${atomic}_${pfx}and${sfx}${order}(~i, v);
+EOF
diff --git a/scripts/atomic/fallbacks/cmpxchg b/scripts/atomic/fallbacks/cmpxchg
new file mode 100644
index 000000000..1c8507f62
--- /dev/null
+++ b/scripts/atomic/fallbacks/cmpxchg
@@ -0,0 +1,3 @@
+cat <<EOF
+ return raw_cmpxchg${order}(&v->counter, old, new);
+EOF
diff --git a/scripts/atomic/fallbacks/dec b/scripts/atomic/fallbacks/dec
new file mode 100755
index 000000000..60d286d40
--- /dev/null
+++ b/scripts/atomic/fallbacks/dec
@@ -0,0 +1,3 @@
+cat <<EOF
+ ${retstmt}raw_${atomic}_${pfx}sub${sfx}${order}(1, v);
+EOF
diff --git a/scripts/atomic/fallbacks/dec_and_test b/scripts/atomic/fallbacks/dec_and_test
new file mode 100755
index 000000000..3a0278e0d
--- /dev/null
+++ b/scripts/atomic/fallbacks/dec_and_test
@@ -0,0 +1,3 @@
+cat <<EOF
+ return raw_${atomic}_dec_return(v) == 0;
+EOF
diff --git a/scripts/atomic/fallbacks/dec_if_positive b/scripts/atomic/fallbacks/dec_if_positive
new file mode 100755
index 000000000..f65c11b4b
--- /dev/null
+++ b/scripts/atomic/fallbacks/dec_if_positive
@@ -0,0 +1,11 @@
+cat <<EOF
+ ${int} dec, c = raw_${atomic}_read(v);
+
+ do {
+ dec = c - 1;
+ if (unlikely(dec < 0))
+ break;
+ } while (!raw_${atomic}_try_cmpxchg(v, &c, dec));
+
+ return dec;
+EOF
diff --git a/scripts/atomic/fallbacks/dec_unless_positive b/scripts/atomic/fallbacks/dec_unless_positive
new file mode 100755
index 000000000..d025361d7
--- /dev/null
+++ b/scripts/atomic/fallbacks/dec_unless_positive
@@ -0,0 +1,10 @@
+cat <<EOF
+ ${int} c = raw_${atomic}_read(v);
+
+ do {
+ if (unlikely(c > 0))
+ return false;
+ } while (!raw_${atomic}_try_cmpxchg(v, &c, c - 1));
+
+ return true;
+EOF
diff --git a/scripts/atomic/fallbacks/fence b/scripts/atomic/fallbacks/fence
new file mode 100755
index 000000000..40d5b3976
--- /dev/null
+++ b/scripts/atomic/fallbacks/fence
@@ -0,0 +1,7 @@
+cat <<EOF
+ ${ret} ret;
+ __atomic_pre_full_fence();
+ ret = arch_${atomic}_${pfx}${name}${sfx}_relaxed(${args});
+ __atomic_post_full_fence();
+ return ret;
+EOF
diff --git a/scripts/atomic/fallbacks/fetch_add_unless b/scripts/atomic/fallbacks/fetch_add_unless
new file mode 100755
index 000000000..8db7e9e17
--- /dev/null
+++ b/scripts/atomic/fallbacks/fetch_add_unless
@@ -0,0 +1,10 @@
+cat << EOF
+ ${int} c = raw_${atomic}_read(v);
+
+ do {
+ if (unlikely(c == u))
+ break;
+ } while (!raw_${atomic}_try_cmpxchg(v, &c, c + a));
+
+ return c;
+EOF
diff --git a/scripts/atomic/fallbacks/inc b/scripts/atomic/fallbacks/inc
new file mode 100755
index 000000000..56c770f59
--- /dev/null
+++ b/scripts/atomic/fallbacks/inc
@@ -0,0 +1,3 @@
+cat <<EOF
+ ${retstmt}raw_${atomic}_${pfx}add${sfx}${order}(1, v);
+EOF
diff --git a/scripts/atomic/fallbacks/inc_and_test b/scripts/atomic/fallbacks/inc_and_test
new file mode 100755
index 000000000..7d16a10f2
--- /dev/null
+++ b/scripts/atomic/fallbacks/inc_and_test
@@ -0,0 +1,3 @@
+cat <<EOF
+ return raw_${atomic}_inc_return(v) == 0;
+EOF
diff --git a/scripts/atomic/fallbacks/inc_not_zero b/scripts/atomic/fallbacks/inc_not_zero
new file mode 100755
index 000000000..1fcef1e55
--- /dev/null
+++ b/scripts/atomic/fallbacks/inc_not_zero
@@ -0,0 +1,3 @@
+cat <<EOF
+ return raw_${atomic}_add_unless(v, 1, 0);
+EOF
diff --git a/scripts/atomic/fallbacks/inc_unless_negative b/scripts/atomic/fallbacks/inc_unless_negative
new file mode 100755
index 000000000..7b4b09868
--- /dev/null
+++ b/scripts/atomic/fallbacks/inc_unless_negative
@@ -0,0 +1,10 @@
+cat <<EOF
+ ${int} c = raw_${atomic}_read(v);
+
+ do {
+ if (unlikely(c < 0))
+ return false;
+ } while (!raw_${atomic}_try_cmpxchg(v, &c, c + 1));
+
+ return true;
+EOF
diff --git a/scripts/atomic/fallbacks/read_acquire b/scripts/atomic/fallbacks/read_acquire
new file mode 100755
index 000000000..e319862d2
--- /dev/null
+++ b/scripts/atomic/fallbacks/read_acquire
@@ -0,0 +1,12 @@
+cat <<EOF
+ ${int} ret;
+
+ if (__native_word(${atomic}_t)) {
+ ret = smp_load_acquire(&(v)->counter);
+ } else {
+ ret = raw_${atomic}_read(v);
+ __atomic_acquire_fence();
+ }
+
+ return ret;
+EOF
diff --git a/scripts/atomic/fallbacks/release b/scripts/atomic/fallbacks/release
new file mode 100755
index 000000000..1e6daf57b
--- /dev/null
+++ b/scripts/atomic/fallbacks/release
@@ -0,0 +1,4 @@
+cat <<EOF
+ __atomic_release_fence();
+ ${retstmt}arch_${atomic}_${pfx}${name}${sfx}_relaxed(${args});
+EOF
diff --git a/scripts/atomic/fallbacks/set_release b/scripts/atomic/fallbacks/set_release
new file mode 100755
index 000000000..16a374ae6
--- /dev/null
+++ b/scripts/atomic/fallbacks/set_release
@@ -0,0 +1,8 @@
+cat <<EOF
+ if (__native_word(${atomic}_t)) {
+ smp_store_release(&(v)->counter, i);
+ } else {
+ __atomic_release_fence();
+ raw_${atomic}_set(v, i);
+ }
+EOF
diff --git a/scripts/atomic/fallbacks/sub_and_test b/scripts/atomic/fallbacks/sub_and_test
new file mode 100755
index 000000000..d1f746fe0
--- /dev/null
+++ b/scripts/atomic/fallbacks/sub_and_test
@@ -0,0 +1,3 @@
+cat <<EOF
+ return raw_${atomic}_sub_return(i, v) == 0;
+EOF
diff --git a/scripts/atomic/fallbacks/try_cmpxchg b/scripts/atomic/fallbacks/try_cmpxchg
new file mode 100755
index 000000000..d4da82092
--- /dev/null
+++ b/scripts/atomic/fallbacks/try_cmpxchg
@@ -0,0 +1,7 @@
+cat <<EOF
+ ${int} r, o = *old;
+ r = raw_${atomic}_cmpxchg${order}(v, o, new);
+ if (unlikely(r != o))
+ *old = r;
+ return likely(r == o);
+EOF
diff --git a/scripts/atomic/fallbacks/xchg b/scripts/atomic/fallbacks/xchg
new file mode 100644
index 000000000..e4def1e0d
--- /dev/null
+++ b/scripts/atomic/fallbacks/xchg
@@ -0,0 +1,3 @@
+cat <<EOF
+ return raw_xchg${order}(&v->counter, new);
+EOF