Re: [PATCH v4 07/11] KVM: guest_memfd: Add support for freezing mappings

From: tarunsahu

Date: Mon Aug 10 2026 - 09:41:17 EST


Ackerley Tng <ackerleytng@xxxxxxxxxx> writes:

> Tarun Sahu <tarunsahu@xxxxxxxxxx> writes:
>
>>
>> [...snip...]
>>
>> @@ -273,16 +284,30 @@ static long kvm_gmem_allocate(struct inode *inode, loff_t offset, loff_t len)
>> static long kvm_gmem_fallocate(struct file *file, int mode, loff_t offset,
>> loff_t len)
>> {
>> + struct inode *inode = file_inode(file);
>> int ret;
>> + int idx;
>>
>> - if (!(mode & FALLOC_FL_KEEP_SIZE))
>> - return -EOPNOTSUPP;
>> + idx = srcu_read_lock(&kvm_gmem_freeze_srcu);
>> + if (kvm_gmem_is_frozen(inode)) {
>> + srcu_read_unlock(&kvm_gmem_freeze_srcu, idx);
>> + return -EPERM;
>> + }
>>
>> - if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
>> - return -EOPNOTSUPP;
>> + if (!(mode & FALLOC_FL_KEEP_SIZE)) {
>> + ret = -EOPNOTSUPP;
>> + goto out;
>> + }
>>
>> - if (!PAGE_ALIGNED(offset) || !PAGE_ALIGNED(len))
>> - return -EINVAL;
>> + if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) {
>> + ret = -EOPNOTSUPP;
>> + goto out;
>> + }
>> +
>> + if (!PAGE_ALIGNED(offset) || !PAGE_ALIGNED(len)) {
>> + ret = -EINVAL;
>> + goto out;
>> + }
>>
>
> Continuing from [1], this guard is actually meant for PUNCH_HOLE... I
> wonder if there could be a deeper refactoring to check when actually
> punching a hole, basically the equivalent place as kvm_gmem_get_folio()
> in the flow of fallocating.
>
> Will srcu_read_lock() be taken in a nested way for the fallocate case?
> It can be taken in a nested way with some intricacies, but maybe if the
> freeze check can be done just as the folio is about to be removed (as
> described in the above paragraph), it would avoid this nested locking
> here.
>
> [1] https://lore.kernel.org/all/2vxzzf0kl3dt.fsf@xxxxxxxxxx/

Instead of avoiding on remove folio, We can just add the freeze check
across the PUNCH_HOLE, So there will be no nested lock anymore. Nested
lock is just with fallocate populate -> kvm_gmem_get_pfn. So this nested
ness will be removed with this update.

~Tarun

>
>> if (mode & FALLOC_FL_PUNCH_HOLE)
>> ret = kvm_gmem_punch_hole(file_inode(file), offset, len);
>> @@ -291,6 +316,9 @@ static long kvm_gmem_fallocate(struct file *file, int mode, loff_t offset,
>>
>> if (!ret)
>> file_modified(file);
>> +
>> +out:
>> + srcu_read_unlock(&kvm_gmem_freeze_srcu, idx);
>> return ret;
>> }
>>
>>
>> [...snip...]
>>