FAILED: patch "[PATCH] RDMA/mlx5: Use different doorbell memory for different" failed to apply to 5.10-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From a0ffb4c12f7fa89163e228e6f27df09b46631db1 Mon Sep 17 00:00:00 2001
From: Mark Zhang <[email protected]>
Date: Thu, 3 Jun 2021 16:18:03 +0300
Subject: [PATCH] RDMA/mlx5: Use different doorbell memory for different
processes
In a fork scenario, the parent and child can have same virtual address and also share the uverbs fd. That causes to the list_for_each_entry search return same doorbell physical page for all processes, even though that page has been COW' or copied.
This patch takes the mm_struct into consideration during search, to make sure that VA's belonging to different processes are not intermixed.
Resolves the malfunction of uverbs after fork in some specific cases.
drivers/infiniband/hw/mlx5/doorbell.c +6 -1
@@ -41,6 +41,7 @@ struct mlx5_ib_user_db_page {struct ib_umem *umem;unsigned long user_virt;int refcnt; +struct mm_struct *mm; }; int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context,
@@ -53,7 +54,8 @@ int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context,mutex_lock (&context->db_page_mutex);list_for_each_entry (page, &context->db_page_list, list) -if (page->user_virt == (virt &PAGE_MASK )) +if ((current->mm == page->mm) && + (page->user_virt == (virt &PAGE_MASK ))) goto found; page =kmalloc (sizeof (*page),GFP_KERNEL );
@@ -71,6 +73,8 @@ int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context,kfree (page); goto out; } +mmgrab (current->mm); + page->mm = current->mm;list_add (&page->list, &context->db_page_list);
@@ -91,6 +95,7 @@ void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db)if (!--db->u.user_page->refcnt) {list_del (&db->u.user_page->list); +mmdrop (db->u.user_page->mm);ib_umem_release (db->u.user_page->umem);kfree (db->u.user_page); }