From nobody Fri Jun 19 07:45:03 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7FF16345738 for ; Fri, 24 Apr 2026 07:02:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777014180; cv=none; b=ZVZt4y2bgGxUZJJqJQKWtXaOSxhVR3fmAXYdYSsyo/8RZg1VWF9xq4YUrjf5ywDutUHJi9PwsbYz48LqomTv05iwPyP3oe8RuLea9cljtT7BIDUD2iZJWfMcBj8S8/kRtWEojZ4trZqYrA+V5cFjDKKtcmt05lN1Ef8sLR5vbVc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777014180; c=relaxed/simple; bh=VYuIwte0GfDMmR5ih5xkZBZaUjo9V52pbxc5tYFhD28=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mH5aeUUQcoGV9K8iWpBBykXEDznTMk+ZHAU/zF+77Lmkzpe+Jiv0UMHvGcPwUoTpt74gKSYOTAf2Ttc0oKsYaKzw1eeFMTuM0Vp6xpLehlhIrjsN3/9pJ1x7MW8WcQubP0QKuK+Fk0F3NEok3LQtr/PjJfn5CVTsxCXd7jxx0jw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--surenb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=OTs0B25W; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--surenb.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="OTs0B25W" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2d8a677cdfaso7988180eec.1 for ; Fri, 24 Apr 2026 00:02:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777014178; x=1777618978; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=PKagbOC73AJ/9NwYWLL6SuYKvFB16xXT/WyLTw4llzo=; b=OTs0B25WN5dhiBkh4dGHNdYMCBuVpBr+gVC4qAfyVaxb0A4G266hwFpcnxSrHldD9p Bmg5c1rUQONR+M/7ULpykNXIH7a91Z253lEfDEOIBP+fd0OgdKLL+M1g6Lt6R49roDwy VqqC92f47WodY0vU8YOAvR22X2brML1Gca8XVgptHHOIurmJCoufgYR9+73ArPfqsq7c 1u+MtMgeDbc/rgN8kH8GGx0Fwu5H+2loDVzpLhVH/PkPJe1M2frX9f2I+pD11OQ6y3zp AfKbxw+hu6/iw+k/nvLyLS643wJP/S0+JlU1gvUp45uBKHEaml1jnAuw7dw9wt5Sfh/o nzIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777014178; x=1777618978; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=PKagbOC73AJ/9NwYWLL6SuYKvFB16xXT/WyLTw4llzo=; b=tOYzwryIMCs8Hx8QXHQ/fQAD+abqzqbQ4dOhax6TiSh3g2e0bRXm2FpVs7jcQRVSj3 dKNlQrMeurcWIqjr7scWvWawtLI2VD0kONqDyfPmNZ0p8Mct8L8ZRAuIhfasFZO2mbw5 DXiZcKtjAxBUUQjbqVr29LmGDsxK11SbFWln9oCDsujcgxIAI0e7kZSKSfEmq9CHueQd y51WKclk8ngsoAV47hwmJQYZq5kHNWYeVKCKoOf4vC59YenQPozm94Esy+OyPMR06EJi MDapyI1ovIn4U3rSR/8aYLwcyaZOfZ9fjBFWKOAk++pTMY0tAeWb3zUleqPI4NWlc8lx Fylw== X-Forwarded-Encrypted: i=1; AFNElJ9xKYat2BJrfbZzrOvI7vOgmCTDfNBZ2f4WKPRxypXmmvMVbRR6FWycoA4/r9RRMMPIAebadJWM4CV1Vcw=@vger.kernel.org X-Gm-Message-State: AOJu0YxKS9JEAQzmQ0HZDhbfbOn7FGPdOY2tIJzyvAon8Lik30KLdzha VnNggMxrKS8w8q5bN5iEYGT55RFF8svVXJbk5cZqpqEsgffehOoRxNH5otq2cg/jNgGj8FG94zM P16VVNA== X-Received: from dlah23.prod.google.com ([2002:a05:701b:2617:b0:12b:f569:153f]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:1282:b0:127:366f:8bb7 with SMTP id a92af1059eb24-12c73f976a5mr12956509c88.25.1777014177368; Fri, 24 Apr 2026 00:02:57 -0700 (PDT) Date: Fri, 24 Apr 2026 00:02:32 -0700 In-Reply-To: <20260424070234.190145-1-surenb@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260424070234.190145-1-surenb@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260424070234.190145-2-surenb@google.com> Subject: [PATCH 1/3] fs/proc/task_mmu: read proc/pid/{smaps|numa_maps} under per-vma lock From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: liam@infradead.org, ljs@kernel.org, vbabka@kernel.org, david@redhat.com, willy@infradead.org, jannh@google.com, paulmck@kernel.org, pfalcato@suse.de, shuah@kernel.org, hsukrut3@gmail.com, richard.weiyang@gmail.com, reddybalavignesh9979@gmail.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kselftest@vger.kernel.org, surenb@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" proc/pid/{smaps|numa_maps} can be read using the combination of RCU and VMA read locks, similar to proc/pid/maps. RCU is required to safely traverse the VMA tree and VMA lock stabilizes the VMA being processed and the pagetable walk. Signed-off-by: Suren Baghdasaryan Reviewed-by: Liam R. Howlett --- fs/proc/task_mmu.c | 193 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 154 insertions(+), 39 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 751b9ba160fb..96cfea252db6 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -132,6 +132,22 @@ static void release_task_mempolicy(struct proc_maps_pr= ivate *priv) =20 #ifdef CONFIG_PER_VMA_LOCK =20 +static inline int lock_ctx_mm(struct proc_maps_locking_ctx *lock_ctx) +{ + int ret =3D mmap_read_lock_killable(lock_ctx->mm); + + if (!ret) + lock_ctx->mmap_locked =3D true; + + return ret; +} + +static inline void unlock_ctx_mm(struct proc_maps_locking_ctx *lock_ctx) +{ + mmap_read_unlock(lock_ctx->mm); + lock_ctx->mmap_locked =3D false; +} + static void reset_lock_ctx(struct proc_maps_locking_ctx *lock_ctx) { lock_ctx->locked_vma =3D NULL; @@ -146,25 +162,11 @@ static void unlock_ctx_vma(struct proc_maps_locking_c= tx *lock_ctx) } } =20 -static const struct seq_operations proc_pid_maps_op; - static inline bool lock_vma_range(struct seq_file *m, struct proc_maps_locking_ctx *lock_ctx) { - /* - * smaps and numa_maps perform page table walk, therefore require - * mmap_lock but maps can be read with locking just the vma and - * walking the vma tree under rcu read protection. - */ - if (m->op !=3D &proc_pid_maps_op) { - if (mmap_read_lock_killable(lock_ctx->mm)) - return false; - - lock_ctx->mmap_locked =3D true; - } else { - rcu_read_lock(); - reset_lock_ctx(lock_ctx); - } + rcu_read_lock(); + reset_lock_ctx(lock_ctx); =20 return true; } @@ -172,7 +174,7 @@ static inline bool lock_vma_range(struct seq_file *m, static inline void unlock_vma_range(struct proc_maps_locking_ctx *lock_ctx) { if (lock_ctx->mmap_locked) { - mmap_read_unlock(lock_ctx->mm); + unlock_ctx_mm(lock_ctx); } else { unlock_ctx_vma(lock_ctx); rcu_read_unlock(); @@ -213,17 +215,45 @@ static inline bool fallback_to_mmap_lock(struct proc_= maps_private *priv, return true; } =20 +static inline void drop_rcu(struct proc_maps_private *priv) +{ + if (priv->lock_ctx.mmap_locked) + return; + + rcu_read_unlock(); +} + +static inline void reacquire_rcu(struct proc_maps_private *priv) +{ + if (priv->lock_ctx.mmap_locked) + return; + + rcu_read_lock(); + /* Reinitialize the iterator. */ + vma_iter_set(&priv->iter, priv->lock_ctx.locked_vma->vm_end); +} + #else /* CONFIG_PER_VMA_LOCK */ =20 +static inline int lock_ctx_mm(struct proc_maps_locking_ctx *lock_ctx) +{ + return mmap_read_lock_killable(lock_ctx->mm); +} + +static inline void unlock_ctx_mm(struct proc_maps_locking_ctx *lock_ctx) +{ + mmap_read_unlock(lock_ctx->mm); +} + static inline bool lock_vma_range(struct seq_file *m, struct proc_maps_locking_ctx *lock_ctx) { - return mmap_read_lock_killable(lock_ctx->mm) =3D=3D 0; + return lock_ctx_mm(lock_ctx) =3D=3D 0; } =20 static inline void unlock_vma_range(struct proc_maps_locking_ctx *lock_ctx) { - mmap_read_unlock(lock_ctx->mm); + unlock_ctx_mm(lock_ctx); } =20 static struct vm_area_struct *get_next_vma(struct proc_maps_private *priv, @@ -238,6 +268,9 @@ static inline bool fallback_to_mmap_lock(struct proc_ma= ps_private *priv, return false; } =20 +static inline void drop_rcu(struct proc_maps_private *priv) {} +static inline void reacquire_rcu(struct proc_maps_private *priv) {} + #endif /* CONFIG_PER_VMA_LOCK */ =20 static struct vm_area_struct *proc_get_vma(struct seq_file *m, loff_t *ppo= s) @@ -538,12 +571,10 @@ static int query_vma_setup(struct proc_maps_locking_c= tx *lock_ctx) =20 static void query_vma_teardown(struct proc_maps_locking_ctx *lock_ctx) { - if (lock_ctx->mmap_locked) { - mmap_read_unlock(lock_ctx->mm); - lock_ctx->mmap_locked =3D false; - } else { + if (lock_ctx->mmap_locked) + unlock_ctx_mm(lock_ctx); + else unlock_ctx_vma(lock_ctx); - } } =20 static struct vm_area_struct *query_vma_find_by_addr(struct proc_maps_lock= ing_ctx *lock_ctx, @@ -1280,16 +1311,64 @@ static const struct mm_walk_ops smaps_shmem_walk_op= s =3D { .walk_lock =3D PGWALK_RDLOCK, }; =20 +#ifdef CONFIG_PER_VMA_LOCK + +static const struct mm_walk_ops smaps_walk_vma_lock_ops =3D { + .pmd_entry =3D smaps_pte_range, + .hugetlb_entry =3D smaps_hugetlb_range, + .walk_lock =3D PGWALK_VMA_RDLOCK_VERIFY, +}; + +static const struct mm_walk_ops smaps_shmem_walk_vma_lock_ops =3D { + .pmd_entry =3D smaps_pte_range, + .hugetlb_entry =3D smaps_hugetlb_range, + .pte_hole =3D smaps_pte_hole, + .walk_lock =3D PGWALK_VMA_RDLOCK_VERIFY, +}; + +static inline const struct mm_walk_ops * +get_smaps_walk_ops(struct proc_maps_private *priv) +{ + if (priv->lock_ctx.mmap_locked) + return &smaps_walk_ops; + return &smaps_walk_vma_lock_ops; +} + +static inline const struct mm_walk_ops * +get_smaps_shmem_walk_ops(struct proc_maps_private *priv) +{ + if (priv->lock_ctx.mmap_locked) + return &smaps_shmem_walk_ops; + return &smaps_shmem_walk_vma_lock_ops; +} + +#else /* CONFIG_PER_VMA_LOCK */ + +static inline const struct mm_walk_ops * +get_smaps_walk_ops(struct proc_maps_private *priv) +{ + return &smaps_walk_ops; +} + +static inline const struct mm_walk_ops * +get_smaps_shmem_walk_ops(struct proc_maps_private *priv) +{ + return &smaps_shmem_walk_ops; +} + +#endif /* CONFIG_PER_VMA_LOCK */ + /* * Gather mem stats from @vma with the indicated beginning * address @start, and keep them in @mss. * * Use vm_start of @vma as the beginning address if @start is 0. */ -static void smap_gather_stats(struct vm_area_struct *vma, - struct mem_size_stats *mss, unsigned long start) +static void smap_gather_stats(struct proc_maps_private *priv, + struct vm_area_struct *vma, + struct mem_size_stats *mss, unsigned long start) { - const struct mm_walk_ops *ops =3D &smaps_walk_ops; + const struct mm_walk_ops *ops =3D get_smaps_walk_ops(priv); =20 /* Invalid start */ if (start >=3D vma->vm_end) @@ -1312,15 +1391,24 @@ static void smap_gather_stats(struct vm_area_struct= *vma, !(vma->vm_flags & VM_WRITE))) { mss->swap +=3D shmem_swapped; } else { - ops =3D &smaps_shmem_walk_ops; + ops =3D get_smaps_shmem_walk_ops(priv); } } =20 - /* mmap_lock is held in m_start */ + /* Skip walking pages if gate VMA */ + if (vma =3D=3D get_gate_vma(priv->lock_ctx.mm)) + return; + + /* + * Need to drop RCU read lock before the walk due to possibility of sleep. + * Note that the VMA is still locked. + */ + drop_rcu(priv); if (!start) walk_page_vma(vma, ops, mss); else walk_page_range(vma->vm_mm, start, vma->vm_end, ops, mss); + reacquire_rcu(priv); } =20 #define SEQ_PUT_DEC(str, val) \ @@ -1369,10 +1457,11 @@ static void __show_smap(struct seq_file *m, const s= truct mem_size_stats *mss, =20 static int show_smap(struct seq_file *m, void *v) { + struct proc_maps_private *priv =3D m->private; struct vm_area_struct *vma =3D v; struct mem_size_stats mss =3D {}; =20 - smap_gather_stats(vma, &mss, 0); + smap_gather_stats(priv, vma, &mss, 0); =20 show_map_vma(m, vma); =20 @@ -1413,7 +1502,7 @@ static int show_smaps_rollup(struct seq_file *m, void= *v) goto out_put_task; } =20 - ret =3D mmap_read_lock_killable(mm); + ret =3D lock_ctx_mm(&priv->lock_ctx); if (ret) goto out_put_mm; =20 @@ -1425,7 +1514,7 @@ static int show_smaps_rollup(struct seq_file *m, void= *v) =20 vma_start =3D vma->vm_start; do { - smap_gather_stats(vma, &mss, 0); + smap_gather_stats(priv, vma, &mss, 0); last_vma_end =3D vma->vm_end; =20 /* @@ -1434,8 +1523,8 @@ static int show_smaps_rollup(struct seq_file *m, void= *v) */ if (mmap_lock_is_contended(mm)) { vma_iter_invalidate(&vmi); - mmap_read_unlock(mm); - ret =3D mmap_read_lock_killable(mm); + unlock_ctx_mm(&priv->lock_ctx); + ret =3D lock_ctx_mm(&priv->lock_ctx); if (ret) { release_task_mempolicy(priv); goto out_put_mm; @@ -1484,14 +1573,14 @@ static int show_smaps_rollup(struct seq_file *m, vo= id *v) =20 /* Case 1 and 2 above */ if (vma->vm_start >=3D last_vma_end) { - smap_gather_stats(vma, &mss, 0); + smap_gather_stats(priv, vma, &mss, 0); last_vma_end =3D vma->vm_end; continue; } =20 /* Case 4 above */ if (vma->vm_end > last_vma_end) { - smap_gather_stats(vma, &mss, last_vma_end); + smap_gather_stats(priv, vma, &mss, last_vma_end); last_vma_end =3D vma->vm_end; } } @@ -1505,7 +1594,7 @@ static int show_smaps_rollup(struct seq_file *m, void= *v) __show_smap(m, &mss, true); =20 release_task_mempolicy(priv); - mmap_read_unlock(mm); + unlock_ctx_mm(&priv->lock_ctx); =20 out_put_mm: mmput(mm); @@ -3291,6 +3380,31 @@ static const struct mm_walk_ops show_numa_ops =3D { .walk_lock =3D PGWALK_RDLOCK, }; =20 +#ifdef CONFIG_PER_VMA_LOCK +static const struct mm_walk_ops show_numa_vma_lock_ops =3D { + .hugetlb_entry =3D gather_hugetlb_stats, + .pmd_entry =3D gather_pte_stats, + .walk_lock =3D PGWALK_VMA_RDLOCK_VERIFY, +}; + +static inline const struct mm_walk_ops * +get_show_numa_ops(struct proc_maps_private *priv) +{ + if (priv->lock_ctx.mmap_locked) + return &show_numa_ops; + return &show_numa_vma_lock_ops; +} + +#else /* CONFIG_PER_VMA_LOCK */ + +static inline const struct mm_walk_ops * +get_show_numa_ops(struct proc_maps_private *priv) +{ + return &show_numa_ops; +} + +#endif /* CONFIG_PER_VMA_LOCK */ + /* * Display pages allocated per node and memory policy via /proc. */ @@ -3335,8 +3449,9 @@ static int show_numa_map(struct seq_file *m, void *v) if (is_vm_hugetlb_page(vma)) seq_puts(m, " huge"); =20 - /* mmap_lock is held by m_start */ - walk_page_vma(vma, &show_numa_ops, md); + drop_rcu(proc_priv); + walk_page_vma(vma, get_show_numa_ops(proc_priv), md); + reacquire_rcu(proc_priv); =20 if (!md->pages) goto out; --=20 2.54.0.545.g6539524ca2-goog From nobody Fri Jun 19 07:45:03 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A9A3345CA3 for ; Fri, 24 Apr 2026 07:03:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777014182; cv=none; b=ZAv+48X+AfMQTam1SGqlzSIEeCPipIP5E0j2nbnheGDhmya++YiKn2/ognOMbISXP3glowb6WI+FcRg53B6ZhdWyaM8XAeqBIWUapV7ldwzMrICiyxEazaqi+fLJU+vH3OIYXgCvFS3yMuOOc4mMjZTYOtReQzWuuAQvj3Oa80Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777014182; c=relaxed/simple; bh=WAZtIz9DRaTLMD/Vn5XCDvQ2W8Sy7wUfm/O5/IsoqAQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=GfDVO84jRYqKu/9nJzab+QDl3v2y+uAZ9BO8MffqDC8CFnGJOrpOSGfekRrYuUllom9ILpd2PP64KiB7VdzevLq8bBxk08hdSNm2TJHSy4UPU6MhPxs0thjGyVopGGZ/AVzyejSmGu9V9uDBrktycJjtnB8GLUAljrJM2mQhg4s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--surenb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ZAoamA3a; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--surenb.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ZAoamA3a" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2c0f6593ef5so9251008eec.1 for ; Fri, 24 Apr 2026 00:03:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777014180; x=1777618980; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=QROYaYs151R/blxNlpky7uyYcAQOpuOKLNbRD4r5/hI=; b=ZAoamA3a5zm17ZcEaQoT86bE2BZ/pAD1NwnFJJM+vOIItd+644Hatwc1O0x2vv87ZJ a9GCDgURVb4bQ3wloUoGgcGM3ZaCm3JLeF9PBAFkbYBaZxqF6MXebF4sV5HQwP7mvY20 vstqhWEmlLxP7Ct4FI/rPZhLkSOTRomQnyohmCA0s+/oxiKhYFVHSpc3ryGmBdvWiYCl +WjgEvnezpWgGFd8vij8gWivdFovvLNDOJHKVxSKDqob6PZXmPbG91G5XU7pwDn5JGLE 5tTWe1qCpwpvA5RbGYW5zHaNHe8SLAa/+tHZUqFMwS8/IhqsrFFN2a8rnZSQmcpSskm1 1x2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777014180; x=1777618980; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=QROYaYs151R/blxNlpky7uyYcAQOpuOKLNbRD4r5/hI=; b=dyokSeMp2iEyli9gGzhD3E4FEz4Zw4Fc2PiXTXrj8P/laupWMWyBy7bFtHf78h0y34 O5WOT3vodOubgCWsbgUmelNPPz3omawyiORlY8Zx+/Fo5LSeZRwR79dOnBwDsFkXzWCp B0TGbt3jVVPVL7btbPCoaNm8FBBAv6EdXu6AGs4+9oQ95goJHKh9e8d4AtjEbW1Hqqc3 vKjXTmXoJouRRPZl+tNWVH7V/iX7vSIe6/JfNZZvANVHYtuzonBzc0oLadAofM/yv5bU ax+QIxG+PcTVfPTKFgYbK5oyipArGonHU4RR70UDmbI1vtAhy7x4cS5nCxRgDhGAx6h8 +Mhg== X-Forwarded-Encrypted: i=1; AFNElJ8mCnM/a8ik2dM9oUIiFVWlAF4T2jeCFtR64iFryIzBqfIYp4WRAsZ6qBy8hStjDJXj4SpwcmtaQ7/P/2I=@vger.kernel.org X-Gm-Message-State: AOJu0YwS9O5h154/NeA2ySbUBbCuOjT1RQLosTNriLXRuL/DBtK6PjES fEQULkaVPMWFisylEIN40TQSA8H94MQENF2rZf5VFKIfDoKkXq+vjPUyPrDaO4HNUc3p7W/7ONR BXFDe3A== X-Received: from dybqf21.prod.google.com ([2002:a05:7301:6495:b0:2d8:b1cf:5d12]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:3252:b0:2dd:2ad3:f799 with SMTP id 5a478bee46e88-2e46ca438admr16552962eec.9.1777014179625; Fri, 24 Apr 2026 00:02:59 -0700 (PDT) Date: Fri, 24 Apr 2026 00:02:33 -0700 In-Reply-To: <20260424070234.190145-1-surenb@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260424070234.190145-1-surenb@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260424070234.190145-3-surenb@google.com> Subject: [PATCH 2/3] selftests/proc: ensure the test is performed at the right page boundary From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: liam@infradead.org, ljs@kernel.org, vbabka@kernel.org, david@redhat.com, willy@infradead.org, jannh@google.com, paulmck@kernel.org, pfalcato@suse.de, shuah@kernel.org, hsukrut3@gmail.com, richard.weiyang@gmail.com, reddybalavignesh9979@gmail.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kselftest@vger.kernel.org, surenb@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When running tearing tests we need to ensure the pages we use include VMAs that were mapped by the child process for this test. Currently we always use the first two pages, checking VMAs at their boundaries and this works, however once we add tests for /proc/pid/smaps, the first two pages might not contain the VMAs that child modifies. Locate the page that contains the first VMA mapped by the child and use that and the next page for the test. Signed-off-by: Suren Baghdasaryan Reviewed-by: Liam R. Howlett --- tools/testing/selftests/proc/proc-maps-race.c | 78 ++++++++++++++++--- 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/proc/proc-maps-race.c b/tools/testing/= selftests/proc/proc-maps-race.c index a734553718da..c5031b0593b7 100644 --- a/tools/testing/selftests/proc/proc-maps-race.c +++ b/tools/testing/selftests/proc/proc-maps-race.c @@ -39,6 +39,13 @@ #include #include =20 +#define min(a, b) \ + ({ \ + typeof(a) _a =3D (a); \ + typeof(b) _b =3D (b); \ + _a < _b ? _a : _b; \ + }) + /* /proc/pid/maps parsing routines */ struct page_content { char *data; @@ -77,6 +84,7 @@ FIXTURE(proc_maps_race) struct line_content first_line; unsigned long duration_sec; int shared_mem_size; + int skip_pages; int page_size; int vma_count; bool verbose; @@ -105,27 +113,68 @@ struct vma_modifier_info { void *child_mapped_addr[]; }; =20 - -static bool read_two_pages(FIXTURE_DATA(proc_maps_race) *self) +static bool read_page(FIXTURE_DATA(proc_maps_race) *self, + struct page_content *page) { ssize_t bytes_read; =20 - if (lseek(self->maps_fd, 0, SEEK_SET) < 0) + bytes_read =3D read(self->maps_fd, page->data, self->page_size); + if (bytes_read <=3D 0) return false; =20 - bytes_read =3D read(self->maps_fd, self->page1.data, self->page_size); - if (bytes_read <=3D 0) + /* Make sure data always ends with a newline character. */ + if (page->data[bytes_read - 1] !=3D '\n') return false; =20 - self->page1.size =3D bytes_read; + page->size =3D bytes_read; =20 - bytes_read =3D read(self->maps_fd, self->page2.data, self->page_size); - if (bytes_read <=3D 0) + return true; +} + +static int locate_containing_page(FIXTURE_DATA(proc_maps_race) *self, + unsigned long addr, unsigned long size) +{ + unsigned long start, end; + int page =3D 0; + + if (lseek(self->maps_fd, 0, SEEK_SET) < 0) + return -1; + + while (true) { + char *curr_pos; + char *end_pos; + + if (!read_page(self, &self->page1)) + return -1; + + curr_pos =3D self->page1.data; + end_pos =3D self->page1.data + self->page1.size; + while (curr_pos < end_pos) { + if (sscanf(curr_pos, "%lx-%lx", &start, &end) =3D=3D 2 && + start =3D=3D addr && end =3D=3D addr + size) + return page; + + curr_pos =3D strchr(curr_pos, '\n'); + if (!curr_pos) + break; + curr_pos++; + } + page++; + } + + return 0; +} + +static bool read_two_pages(FIXTURE_DATA(proc_maps_race) *self) +{ + if (lseek(self->maps_fd, 0, SEEK_SET) < 0) return false; =20 - self->page2.size =3D bytes_read; + for (int i =3D 0; i < self->skip_pages; i++) + if (!read_page(self, &self->page1)) + return false; =20 - return true; + return read_page(self, &self->page1) && read_page(self, &self->page2); } =20 static void copy_first_line(struct page_content *page, char *first_line) @@ -418,6 +467,8 @@ FIXTURE_SETUP(proc_maps_race) struct vma_modifier_info *mod_info; pthread_mutexattr_t mutex_attr; pthread_condattr_t cond_attr; + unsigned long first_map_addr; + unsigned long last_map_addr; unsigned long duration_sec; char fname[32]; =20 @@ -502,6 +553,13 @@ FIXTURE_SETUP(proc_maps_race) self->page2.data =3D malloc(self->page_size); ASSERT_NE(self->page2.data, NULL); =20 + first_map_addr =3D (unsigned long)mod_info->child_mapped_addr[0]; + last_map_addr =3D (unsigned long)mod_info->child_mapped_addr[mod_info->vm= a_count - 1]; + + self->skip_pages =3D locate_containing_page(self, + min(first_map_addr, last_map_addr), + self->page_size * 3); + ASSERT_NE(self->skip_pages, -1); ASSERT_TRUE(read_boundary_lines(self, &self->last_line, &self->first_line= )); =20 /* --=20 2.54.0.545.g6539524ca2-goog From nobody Fri Jun 19 07:45:03 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CAF333246EF for ; Fri, 24 Apr 2026 07:03:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777014188; cv=none; b=Fz0F6mi/nhyQBgM78nR+6PwIVXmkbi2LySkqcc4Bpbh8OelQ5b9ckm+z4+pPs43NeCsFAW6Ow4enG9PhFoF4TJT+kKEjm7ddX6kVgLYc6m7u+8xKyTP38BBo9L/bBUMbZsRpO9GVPmGZ7mVRbgOkbSAC8L4t6kLV+wqLIbEytyE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777014188; c=relaxed/simple; bh=JtFAv6G2caNWJMReAzgreJ08mLrVeU8lSOVMG1xDGNY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=rpWdK9U2m261XE1icS+BrZKzjKnVlXBNutI27eqoHrTPu1V7zj3ydri6qJYu2upP0gYXy9tQBm9wVsXJdoFARtXckDaJEqgX1JGJB75jcb0CwzTi7445uLTO3exOU9Wj1Wd3FWISch6/DHzZn3FIcibJ8ZyYs0QaJOW+K7Kxmqc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--surenb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=uIPIb6Q7; arc=none smtp.client-ip=74.125.82.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--surenb.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="uIPIb6Q7" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-12c66fdd4aeso11237668c88.0 for ; Fri, 24 Apr 2026 00:03:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777014182; x=1777618982; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=0swTopRwFXSNiJeH+dx7Oyuq8zIyt+95DwEnqw+0GOE=; b=uIPIb6Q7/l7WOfElUpvAkC6SnaR2yGU358M77Ejb+qQIWrH5iqeUre89GBGZDIg1La 2A/aM5F/dRoPNAl8yttx0bi84ycZFiV3V6FEyxnlFLMqNSXS6kEMIUeEz/LEYl69rfbT mNufNzhYHxfDZgFYBfueZhmIyBcG4iKbInHIjg/QUQyTdDRU5xtxHkGMHZkzYpddMBMb 8F159s2D4wXlHa3oxEFl2SgQP7jHLN0PVm3z+huXqYdi29FwbCgRYPGtx3iVLjxJz9u+ zUIdETeO2wzlESob4jsAqrV1YZ9qNBL0dFWYeNX/RSThwhXAz9wVtejato/XTjKPZBxL 8okA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777014182; x=1777618982; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=0swTopRwFXSNiJeH+dx7Oyuq8zIyt+95DwEnqw+0GOE=; b=JFydVivPZRksml9BYoEanDxRUdiq6RhMiy/xTuUGPc5tMlum4ojgSFiTDXq1xIaGTd ZBzqpXTMhfe1ExI9WuNaCQM186uY/wkcbqU0A5oj/x18wKaUbaU9/2AgSgH2PejyzA2j 6XwjAm/U/lrA+Z1XoXgVVNvW1bQDwDbEgV7EKYf0NbkTXngNXO+CiplvtPQaQnd5mB21 FI59g+jPOjceIcApIGy0HPYIC+y9WMhuZi4SR/HSJEuoi7TObbQW8kFe7vVmZWNrO5l2 IFjM2JTMuRzHmiSL2WEjvr56zFEX7xHY7MecuI1DmHMVceP3TTZfKgjJkW5Ac1nKAIfH Fu0w== X-Forwarded-Encrypted: i=1; AFNElJ93yvAURZF8wOvGrc0wTU9I1okamhid5Arp5/faM+eGk63/zJZTXywsB5TwKH9DC6NrU1NZbzugcus5lfU=@vger.kernel.org X-Gm-Message-State: AOJu0YwKn/l0ndyhGlz/x/V0RYftBMWHMiL20Y9ON1qtSAkTjJ4a0uQ7 nuHBgrSbRLJHw6u+73Zq+xpWXuJkkLWsykWTGvh9YWgwVeReheVl3HNdqBWjf7ilyHOz7HOlNrH JTN+rRA== X-Received: from dlea14-n1.prod.google.com ([2002:a05:701b:420e:10b0:12c:49a5:e4a4]) (user=surenb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:6b8d:b0:128:ca90:3301 with SMTP id a92af1059eb24-12c73f71963mr16316333c88.11.1777014181789; Fri, 24 Apr 2026 00:03:01 -0700 (PDT) Date: Fri, 24 Apr 2026 00:02:34 -0700 In-Reply-To: <20260424070234.190145-1-surenb@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260424070234.190145-1-surenb@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260424070234.190145-4-surenb@google.com> Subject: [PATCH 3/3] selftests/proc: add /proc/pid/smaps tearing tests From: Suren Baghdasaryan To: akpm@linux-foundation.org Cc: liam@infradead.org, ljs@kernel.org, vbabka@kernel.org, david@redhat.com, willy@infradead.org, jannh@google.com, paulmck@kernel.org, pfalcato@suse.de, shuah@kernel.org, hsukrut3@gmail.com, richard.weiyang@gmail.com, reddybalavignesh9979@gmail.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kselftest@vger.kernel.org, surenb@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add MAPS_FILE environment variable to select whether the tests to be run for /proc/pid/maps or /proc/pid/smaps. Add support for testing smaps file by reusing the same logic as with maps file but skipping all the data except for the VMA addresses, which are the only part relevant for the tearing tests. Skip PROCMAP_QUERY parts of the tests because smaps does not implement that ioctl. Signed-off-by: Suren Baghdasaryan Reviewed-by: Liam R. Howlett --- tools/testing/selftests/proc/proc-maps-race.c | 176 +++++++++++++----- 1 file changed, 132 insertions(+), 44 deletions(-) diff --git a/tools/testing/selftests/proc/proc-maps-race.c b/tools/testing/= selftests/proc/proc-maps-race.c index c5031b0593b7..b677bc23cab9 100644 --- a/tools/testing/selftests/proc/proc-maps-race.c +++ b/tools/testing/selftests/proc/proc-maps-race.c @@ -17,8 +17,8 @@ */ /* * Fork a child that concurrently modifies address space while the main - * process is reading /proc/$PID/maps and verifying the results. Address - * space modifications include: + * process is reading /proc/$PID/maps and /proc/$PID/smaps, verifying the + * results. Address space modifications include: * VMA splitting and merging * */ @@ -73,6 +73,11 @@ enum test_state { TEST_DONE, }; =20 +enum maps_file { + MAPS, + SMAPS, +}; + struct vma_modifier_info; =20 FIXTURE(proc_maps_race) @@ -83,6 +88,7 @@ FIXTURE(proc_maps_race) struct line_content last_line; struct line_content first_line; unsigned long duration_sec; + enum maps_file maps_file; int shared_mem_size; int skip_pages; int page_size; @@ -199,6 +205,57 @@ static void copy_last_line(struct page_content *page, = char *last_line) last_line[end - pos] =3D '\0'; } =20 +static bool copy_first_entry(struct page_content *page, char *first_line) +{ + const char *start_pos =3D page->data; + + while (start_pos < page->data + page->size) { + unsigned long start_addr; + unsigned long end_addr; + char *end_pos; + + end_pos =3D strchr(start_pos, '\n'); + if (!end_pos) + break; + + if (sscanf(start_pos, "%lx-%lx", &start_addr, &end_addr) =3D=3D 2) { + strncpy(first_line, start_pos, end_pos - start_pos); + first_line[end_pos - start_pos] =3D '\0'; + return true; + } + + start_pos =3D end_pos + 1; + } + + return false; +} + +static bool copy_last_entry(struct page_content *page, char *last_line) +{ + const char *end_pos =3D page->data + page->size - 1; + const char *start_pos; + + while (end_pos > page->data) { + unsigned long start_addr; + unsigned long end_addr; + + /* skip last newline */ + start_pos =3D end_pos - 1; + /* search previous newline */ + while (start_pos > page->data && start_pos[-1] !=3D '\n') + start_pos--; + if (sscanf(start_pos, "%lx-%lx", &start_addr, &end_addr) =3D=3D 2) { + strncpy(last_line, start_pos, end_pos - start_pos); + last_line[end_pos - start_pos] =3D '\0'; + return true; + } + + end_pos =3D start_pos - 1; + } + + return false; +} + /* Read the last line of the first page and the first line of the second p= age */ static bool read_boundary_lines(FIXTURE_DATA(proc_maps_race) *self, struct line_content *last_line, @@ -207,8 +264,16 @@ static bool read_boundary_lines(FIXTURE_DATA(proc_maps= _race) *self, if (!read_two_pages(self)) return false; =20 - copy_last_line(&self->page1, last_line->text); - copy_first_line(&self->page2, first_line->text); + if (self->maps_file =3D=3D MAPS) { + copy_last_line(&self->page1, last_line->text); + copy_first_line(&self->page2, first_line->text); + } else if (self->maps_file =3D=3D SMAPS) { + if (!copy_last_entry(&self->page1, last_line->text) || + !copy_first_entry(&self->page2, first_line->text)) + return false; + } else { + return false; + } =20 return sscanf(last_line->text, "%lx-%lx", &last_line->start_addr, &last_line->end_addr) =3D=3D 2 && @@ -464,6 +529,7 @@ FIXTURE_SETUP(proc_maps_race) { const char *verbose =3D getenv("VERBOSE"); const char *duration =3D getenv("DURATION"); + const char *maps_file =3D getenv("MAPS_FILE"); struct vma_modifier_info *mod_info; pthread_mutexattr_t mutex_attr; pthread_condattr_t cond_attr; @@ -474,6 +540,18 @@ FIXTURE_SETUP(proc_maps_race) =20 self->page_size =3D (unsigned long)sysconf(_SC_PAGESIZE); self->verbose =3D verbose && !strncmp(verbose, "1", 1); + if (maps_file) { + if (!strcmp(maps_file, "maps")) { + self->maps_file =3D MAPS; + } else if (!strcmp(maps_file, "smaps")) { + self->maps_file =3D SMAPS; + } else { + ksft_print_msg("Unknown maps file %s\n", maps_file); + ksft_exit_fail(); + } + } else { + self->maps_file =3D MAPS; + } duration_sec =3D duration ? atol(duration) : 0; self->duration_sec =3D duration_sec ? duration_sec : 5UL; =20 @@ -540,7 +618,16 @@ FIXTURE_SETUP(proc_maps_race) exit(0); } =20 - sprintf(fname, "/proc/%d/maps", self->pid); + switch (self->maps_file) { + case MAPS: + sprintf(fname, "/proc/%d/maps", self->pid); + break; + case SMAPS: + sprintf(fname, "/proc/%d/smaps", self->pid); + break; + default: + ksft_exit_fail(); + } self->maps_fd =3D open(fname, O_RDONLY); ASSERT_NE(self->maps_fd, -1); =20 @@ -675,20 +762,20 @@ TEST_F(proc_maps_race, test_maps_tearing_from_split) last_line_changed =3D strcmp(new_last_line.text, self->last_line.text) != =3D 0; first_line_changed =3D strcmp(new_first_line.text, self->first_line.text= ) !=3D 0; ASSERT_EQ(last_line_changed, first_line_changed); - - /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ - ASSERT_TRUE(query_addr_at(self->maps_fd, mod_info->addr + self->page_siz= e, - &vma_start, &vma_end)); - /* - * The vma at the split address can be either the same as - * original one (if read before the split) or the same as the - * first line in the second page (if read after the split). - */ - ASSERT_TRUE((vma_start =3D=3D self->last_line.start_addr && - vma_end =3D=3D self->last_line.end_addr) || - (vma_start =3D=3D split_first_line.start_addr && - vma_end =3D=3D split_first_line.end_addr)); - + if (self->maps_file =3D=3D MAPS) { + /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ + ASSERT_TRUE(query_addr_at(self->maps_fd, mod_info->addr + self->page_si= ze, + &vma_start, &vma_end)); + /* + * The vma at the split address can be either the same as + * original one (if read before the split) or the same as the + * first line in the second page (if read after the split). + */ + ASSERT_TRUE((vma_start =3D=3D self->last_line.start_addr && + vma_end =3D=3D self->last_line.end_addr) || + (vma_start =3D=3D split_first_line.start_addr && + vma_end =3D=3D split_first_line.end_addr)); + } clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); end_test_iteration(&end_ts, self->verbose); } while (end_ts.tv_sec - start_ts.tv_sec < self->duration_sec); @@ -758,17 +845,18 @@ TEST_F(proc_maps_race, test_maps_tearing_from_resize) strcmp(new_first_line.text, restored_first_line.text), "Expand result invalid", self)); } - - /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ - ASSERT_TRUE(query_addr_at(self->maps_fd, mod_info->addr, &vma_start, &vm= a_end)); - /* - * The vma should stay at the same address and have either the - * original size of 3 pages or 1 page if read after shrinking. - */ - ASSERT_TRUE(vma_start =3D=3D self->last_line.start_addr && - (vma_end - vma_start =3D=3D self->page_size * 3 || - vma_end - vma_start =3D=3D self->page_size)); - + if (self->maps_file =3D=3D MAPS) { + /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ + ASSERT_TRUE(query_addr_at(self->maps_fd, mod_info->addr, + &vma_start, &vma_end)); + /* + * The vma should stay at the same address and have either the + * original size of 3 pages or 1 page if read after shrinking. + */ + ASSERT_TRUE(vma_start =3D=3D self->last_line.start_addr && + (vma_end - vma_start =3D=3D self->page_size * 3 || + vma_end - vma_start =3D=3D self->page_size)); + } clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); end_test_iteration(&end_ts, self->verbose); } while (end_ts.tv_sec - start_ts.tv_sec < self->duration_sec); @@ -838,20 +926,20 @@ TEST_F(proc_maps_race, test_maps_tearing_from_remap) strcmp(new_first_line.text, restored_first_line.text), "Remap restore result invalid", self)); } - - /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ - ASSERT_TRUE(query_addr_at(self->maps_fd, mod_info->addr + self->page_siz= e, - &vma_start, &vma_end)); - /* - * The vma should either stay at the same address and have the - * original size of 3 pages or we should find the remapped vma - * at the remap destination address with size of 1 page. - */ - ASSERT_TRUE((vma_start =3D=3D self->last_line.start_addr && - vma_end - vma_start =3D=3D self->page_size * 3) || - (vma_start =3D=3D self->last_line.start_addr + self->page_size && - vma_end - vma_start =3D=3D self->page_size)); - + if (self->maps_file =3D=3D MAPS) { + /* Check if PROCMAP_QUERY ioclt() finds the right VMA */ + ASSERT_TRUE(query_addr_at(self->maps_fd, mod_info->addr + self->page_si= ze, + &vma_start, &vma_end)); + /* + * The vma should either stay at the same address and have the + * original size of 3 pages or we should find the remapped vma + * at the remap destination address with size of 1 page. + */ + ASSERT_TRUE((vma_start =3D=3D self->last_line.start_addr && + vma_end - vma_start =3D=3D self->page_size * 3) || + (vma_start =3D=3D self->last_line.start_addr + self->page_size && + vma_end - vma_start =3D=3D self->page_size)); + } clock_gettime(CLOCK_MONOTONIC_COARSE, &end_ts); end_test_iteration(&end_ts, self->verbose); } while (end_ts.tv_sec - start_ts.tv_sec < self->duration_sec); --=20 2.54.0.545.g6539524ca2-goog