On Thu, 11 Jan 2024, Xiao Ni wrote:
> On Wed, Nov 29, 2023 at 10:10 AM Eric Wheeler
> <[email protected]> wrote:
> >
> > Hi Joe,
> >
> > I'm not sure who else to CC on this issue, feel free to add others.
> >
> > Recently we tried putting dm-integrity on NVMe's under MD RAID1 with
> > dm-thin metadata (tmeta) on that raid1 mirror (Linux v6.5.7). It worked
> > fine for ~12 hours and then, at ~3:30 am in the morning when we do a
> > reserve_metadata_snap and thin_dump's, IO's began to hang.
> >
> > For reference, we have been using the same block device stack for years,
> > and it is quite stable. We've been running Linux v6.5.7 for about 6 weeks
> > without issue until we tried dm-integrity under dm-thin. The stack
> > _without_ dm-integrity looks like this:
> >
> > nvme{0,1} =>
> > raid mirror /dev/md0 =>
> > LVM PV for VG "data" =>
> > tmeta for dm-thin
> >
> > /dev/sda (LSI-based Hardware RAID)
> > bcache =>
> > LVM PV for VG "data" =>
> > tdata for dm-thin "pool0" =>
> > single thin volume from the pool =>
> > drbd to another host over the network
> >
> > After adding dm-integrity, the stack is the same as above except that
> > the RAID mirror is above dm-integrity:
> >
> > nvme{0,1} =>
> > dm-integrity =>
> > raid mirror /dev/md0 =>
> > LVM PV for VG "data" =>
> > tmeta for dm-thin
> >
> > The first time we had the thindump+IO hang problem we thought that an
> > underlying NVMe drive was bad, so we replaced both: We rebooted and did
> > a `pvmove` of the tmeta volume to different NVMe+md-raid1+dm-integrity
> > on disks that were brand new, but had the same issue that night during
> > reserve_metadata_snap+thin_dump.
> >
> > Since we had the same problem on a different set of new NVMe disks, we
> > rebooted, did a `pvmove` back to the original MD RAID1 mirror stack
> > _without_ dm-integrity, and everything was back to normal. Thus, I do not
> > think it is a disk or tmeta corruption issue, but an obscure race or
> > deadlock bug.
> >
> > We tried to reproduce this in a virtual environment, but so far it has not
> > triggered. In about a week when we get downtime for this system, I will
> > take a copy of its thin metadata to inspect further. For now, I have not
> > yet been enable to reproduce problem outside our semi-production testing
> > environment.
> >
> > So, this is what we see so far:
> >
> > We get _thousands_ of these lines in the kernel logs when IO hangs. The
> > `dm-175` device is one of the the dm-integrity targets being mirrored.
> > Note the "12924 callbacks suppressed" message:
> >
> > [ +0.584816] raid1_end_read_request: 12924 callbacks suppressed
> > [ +0.000006] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +0.020011] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +0.019462] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +0.018672] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +0.006242] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +0.002399] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +0.000934] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +0.000688] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +0.001161] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +0.006404] md/raid1:md0: dm-175: rescheduling sector 1979682216
> > [ +3.594380] integrity_metadata: 13095 callbacks suppressed
> > [ +0.000006] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.001410] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.000824] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.003587] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.011065] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.004176] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.000604] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.006153] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.008797] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.002350] device-mapper: integrity: dm-175: Checksum failed at
> > sector 0x760395b0
> > [ +0.668866] raid1_read_request: 12747 callbacks suppressed
> > [ +0.000005] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
> > [ +0.024708] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
> > [ +0.024441] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
> > [ +0.018321] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
> > [ +0.000850] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
> > [ +0.004479] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
> > [ +0.001225] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
> > [ +0.001024] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
> > [ +0.000741] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
> > [ +0.001094] md/raid1:md0: redirecting sector 1979682216 to other
> > mirror: dm-175
>
> Hi all
>
> The process is as follows and I add some logs
> 1. raid1_read_request submits bio to read data
> 2. raid1_end_read finds the read request fails and try to fix the read error
> 3. handle_read_error>fix_read_error tries to read data in 4K unit in
> another disk, write to the failed disk in 4K unit and read from the
> failed disk in 4K unit. fix_read_error finishes successfully.
> 4. handle_read_error re-read data from the failed disk. And the read
> request fails again.
> [ 1067.149829] device-mapper: integrity: dm-3: Checksum failed at sector
> 0x17d8
> [ 1067.149842] md/raid1:md9: dm-3: rescheduling sector 3912, sectors 248
> [ 1067.150437] md/raid1:md9: dm-3: fix read error 3912, sectors 248
> [ 1067.150439] md/raid1:md9: dm-3: re read 3912, sectors 248
>
> It looks like the bio size is suspicious. Because it reads
> successfully when bio size is 4K.
Hi Xiao, thanks for looking into this.
It looks like the problem can be reproduced using 4k blocks as well, but
I suppose its still possible that some 512-byte (4k-unaligned) IO is
happening somewhere in the device stack.
The script below changes the null_blk modprobe to set bs=4096 and uses
zram instead of brd because zram only supports 4k blocks:
# blockdev --getss /dev/mapper/pv /dev/zram[01]
4096
4096
4096
The script below has been added to the Jira ticket:
https://issues.redhat.com/browse/RHEL-20912
--
Eric Wheeler
Script to trigger the bug with 4k blocks:
# cat dm-integrity-thin-lvraid-zram-4k
#!/bin/bash
# Notice: /dev/zram0 and /dev/zram1 will be wiped unconditionally.
# Configure these if you need to:
VGNAME=testvg
LVNAME=thin
LVSIZE=$((10 * 1024*1024*1024/512))
echo "NOTICE: THIS MAY BE UNSAFE. ONLY RUN THIS IN A TEST ENVIRONMENT!"
echo "Press enter twice to continue or CTRL-C to abort."
read
read
set -x
# append disks into a linear target
linear_add()
{
name=$1
shift
prevsize=0
for vol in "$@"; do
size=`blockdev --getsize $vol`
echo "$prevsize $size linear $vol 0"
prevsize=$size
done \
| dmsetup create $name
echo /dev/mapper/$name
}
lvthin_add()
{
id=$1
lvcreate -An -V $LVSIZE -n $LVNAME$id --thinpool pool0 $VGNAME >&2
echo /dev/$VGNAME/$LVNAME$id
}
lvthin_snapshot()
{
origin=$1
id=$2
lvcreate -An -s $VGNAME/$LVNAME$origin -n $LVNAME$id >&2
echo /dev/$VGNAME/$LVNAME$id
}
fio()
{
dev=$1
/bin/fio --name=$dev --rw=randrw --direct=1 --bs=512 --numjobs=1
--filename=$dev --time_based --runtime=$FIOTIME --ioengine=libaio --iodepth=1
&> /dev/null
}
do_reset()
{
killall -9 fio
lvchange -an $VGNAME
rmdir /dev/$VGNAME
dmsetup remove pv
dmsetup remove zram0
dmsetup remove zram1
lvmdevices --deldev /dev/mapper/pv
losetup -d /dev/loop?
rmmod zram
rmmod null_blk
echo ==== reset done
sleep 1
}
do_init()
{
modprobe null_blk gb=30000 bs=4096
modprobe zram num_devices=2
echo 1g > /sys/block/zram0/disksize
echo 1g > /sys/block/zram1/disksize
# Create a writable header for the PV meta:
dd if=/dev/zero bs=1M count=16 oflag=direct of=/tmp/pvheader
loop=`losetup -f --show /tmp/pvheader`
linear_add pv $loop /dev/nullb0
# Create the VG
sleep 1
#linear_add zram0 /dev/zram0
#linear_add zram1 /dev/zram1
lvmdevices --adddev /dev/zram0
lvmdevices --adddev /dev/zram1
lvmdevices --adddev /dev/mapper/pv
vgcreate $VGNAME /dev/mapper/pv /dev/zram[01]
# Create the pool:
lvcreate -n pool0 -L 1T $VGNAME /dev/mapper/pv
lvcreate --type raid1 --raidintegrity y -m1 -L 512m -n meta0 $VGNAME
/dev/zram[01]
lvconvert -y --force --force --chunksize 64k --type thin-pool
--poolmetadata $VGNAME/meta0 $VGNAME/pool0
}
while true; do
do_reset
do_init
thin1=`lvthin_add 1`
fio $thin1 &
thin2=`lvthin_snapshot 1 2`
fio $thin2 &
wait
done