On 5/10/24 02:22, Stefan Hajnoczi wrote:
On Wed, May 08, 2024 at 05:36:21PM +0800, Changqi Lu wrote:

[SNIP]

+
+    /**
+     * Persist Through Power Loss(PTPL) is considered as required in QEMU
+     * block layer, the block driver need always enable PTPL.
+     */

What is the reasoning behind this? Will applications that rely on PTPL=0
work?


Hi Stefan,

PTPL needs to be supported at QEMU block layer in theory, include reporting PTPL capability and PTPL flag in PR OUT command. However, in the real production environment, both SCSI driver and NVMe driver, even linux block layer always enable PTPL nnconditionally on a linux platform.

Ref the latest code:
1, SCSI:
https://github.com/torvalds/linux/blob/master/drivers/scsi/sd.c#L1978
static int sd_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,
                u32 flags)
{
        if (flags & ~PR_FL_IGNORE_KEY)
                return -EOPNOTSUPP;
        return sd_pr_out_command(bdev, (flags & PR_FL_IGNORE_KEY) ? 0x06 : 0x00,
                        old_key, new_key, 0,
                        (1 << 0) /* APTPL */);
}

2, NVMe:
https://github.com/torvalds/linux/blob/master/drivers/nvme/host/pr.c#L127
static int nvme_pr_register(struct block_device *bdev, u64 old,
                u64 new, unsigned flags)
{
        u32 cdw10;

        if (flags & ~PR_FL_IGNORE_KEY)
                return -EOPNOTSUPP;

        cdw10 = old ? 2 : 0;
        cdw10 |= (flags & PR_FL_IGNORE_KEY) ? 1 << 3 : 0;
        cdw10 |= (1 << 30) | (1 << 31); /* PTPL=1 */
        return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_register);
}

3, linux block layers also hides PTPL flag:
https://github.com/torvalds/linux/blob/master/block/ioctl.c#L283
static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode,
                struct pr_registration __user *arg)
{
        const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
        struct pr_registration reg;

        if (!blkdev_pr_allowed(bdev, mode))
                return -EPERM;
        if (!ops || !ops->pr_register)
                return -EOPNOTSUPP;
        if (copy_from_user(&reg, arg, sizeof(reg)))
                return -EFAULT;

        if (reg.flags & ~PR_FL_IGNORE_KEY)
                return -EOPNOTSUPP;
        return ops->pr_register(bdev, reg.old_key, reg.new_key, reg.flags);
}


So we(Changqi and me) wanted to keep PR a bit simple in QEMU block layer:
- consider PTPL is required in QEMU block, then we don't need an extra flag
- the block backend driver always request PR OUT with PTPL flag

Then: Will applications that rely on PTPL=0 work?
Yes, a guest PR out without PTPL will work, but the backend uses PTPL=1 instead.

Will this request succeed?
If the backend driver' supports PTPL capability, it will succeed. Otherwise it will fail.

--
zhenwei pi

Reply via email to