Skip to content

Commit a639e66

Browse files
committed
RDMA/mlx5: Zero out ODP related items in the mlx5_ib_mr
All of the ODP code assumes when it calls mlx5_mr_cache_alloc() the ODP related fields are zero'd. This is true if the MR was just allocated, but if the MR is recycled through the cache then the values are never zero'd. This causes a bug in the odp_stats, they don't reset when the MR is reallocated, also is_odp_implicit is never 0'd. So we can use memset on a block of the mlx5_ib_mr reorganize the structure to put all the data that can be zero'd by the cache at the end. It is organized as an anonymous struct because the next patch will make this a union. Delete the unused smr_info. Don't set the kernel only desc_size on the user path. No longer any need to zero mr->parent before freeing it, the memset() will get it now. Fixes: a3de94e ("IB/mlx5: Introduce ODP diagnostic counters") Link: https://lore.kernel.org/r/20210304120745.1090751-2-leon@kernel.org Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent 3254887 commit a639e66

File tree

3 files changed

+66
-52
lines changed

3 files changed

+66
-52
lines changed

drivers/infiniband/hw/mlx5/mlx5_ib.h

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -547,11 +547,6 @@ static inline const struct mlx5_umr_wr *umr_wr(const struct ib_send_wr *wr)
547547
return container_of(wr, struct mlx5_umr_wr, wr);
548548
}
549549

550-
struct mlx5_shared_mr_info {
551-
int mr_id;
552-
struct ib_umem *umem;
553-
};
554-
555550
enum mlx5_ib_cq_pr_flags {
556551
MLX5_IB_CQ_PR_FLAGS_CQE_128_PAD = 1 << 0,
557552
};
@@ -654,47 +649,69 @@ struct mlx5_ib_dm {
654649
atomic64_add(value, &((mr)->odp_stats.counter_name))
655650

656651
struct mlx5_ib_mr {
657-
struct ib_mr ibmr;
658-
void *descs;
659-
dma_addr_t desc_map;
660-
int ndescs;
661-
int data_length;
662-
int meta_ndescs;
663-
int meta_length;
664-
int max_descs;
665-
int desc_size;
666-
int access_mode;
667-
unsigned int page_shift;
668-
struct mlx5_core_mkey mmkey;
669-
struct ib_umem *umem;
670-
struct mlx5_shared_mr_info *smr_info;
671-
struct list_head list;
672-
struct mlx5_cache_ent *cache_ent;
673-
u32 out[MLX5_ST_SZ_DW(create_mkey_out)];
674-
struct mlx5_core_sig_ctx *sig;
675-
void *descs_alloc;
676-
int access_flags; /* Needed for rereg MR */
677-
678-
struct mlx5_ib_mr *parent;
679-
/* Needed for IB_MR_TYPE_INTEGRITY */
680-
struct mlx5_ib_mr *pi_mr;
681-
struct mlx5_ib_mr *klm_mr;
682-
struct mlx5_ib_mr *mtt_mr;
683-
u64 data_iova;
684-
u64 pi_iova;
685-
686-
/* For ODP and implicit */
687-
struct xarray implicit_children;
688-
union {
689-
struct list_head elm;
690-
struct work_struct work;
691-
} odp_destroy;
692-
struct ib_odp_counters odp_stats;
693-
bool is_odp_implicit;
652+
struct ib_mr ibmr;
653+
struct mlx5_core_mkey mmkey;
694654

695-
struct mlx5_async_work cb_work;
655+
/* User MR data */
656+
struct mlx5_cache_ent *cache_ent;
657+
struct ib_umem *umem;
658+
659+
/* This is zero'd when the MR is allocated */
660+
struct {
661+
/* Used only while the MR is in the cache */
662+
struct {
663+
u32 out[MLX5_ST_SZ_DW(create_mkey_out)];
664+
struct mlx5_async_work cb_work;
665+
/* Cache list element */
666+
struct list_head list;
667+
};
668+
669+
/* Used only by kernel MRs (umem == NULL) */
670+
struct {
671+
void *descs;
672+
void *descs_alloc;
673+
dma_addr_t desc_map;
674+
int max_descs;
675+
int ndescs;
676+
int desc_size;
677+
int access_mode;
678+
679+
/* For Kernel IB_MR_TYPE_INTEGRITY */
680+
struct mlx5_core_sig_ctx *sig;
681+
struct mlx5_ib_mr *pi_mr;
682+
struct mlx5_ib_mr *klm_mr;
683+
struct mlx5_ib_mr *mtt_mr;
684+
u64 data_iova;
685+
u64 pi_iova;
686+
int meta_ndescs;
687+
int meta_length;
688+
int data_length;
689+
};
690+
691+
/* Used only by User MRs (umem != NULL) */
692+
struct {
693+
unsigned int page_shift;
694+
/* Current access_flags */
695+
int access_flags;
696+
697+
/* For User ODP */
698+
struct mlx5_ib_mr *parent;
699+
struct xarray implicit_children;
700+
union {
701+
struct work_struct work;
702+
} odp_destroy;
703+
struct ib_odp_counters odp_stats;
704+
bool is_odp_implicit;
705+
};
706+
};
696707
};
697708

709+
/* Zero the fields in the mr that are variant depending on usage */
710+
static inline void mlx5_clear_mr(struct mlx5_ib_mr *mr)
711+
{
712+
memset(mr->out, 0, sizeof(*mr) - offsetof(struct mlx5_ib_mr, out));
713+
}
714+
698715
static inline bool is_odp_mr(struct mlx5_ib_mr *mr)
699716
{
700717
return IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING) && mr->umem &&

drivers/infiniband/hw/mlx5/mr.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,8 @@ struct mlx5_ib_mr *mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev,
590590
ent->available_mrs--;
591591
queue_adjust_cache_locked(ent);
592592
spin_unlock_irq(&ent->lock);
593+
594+
mlx5_clear_mr(mr);
593595
}
594596
mr->access_flags = access_flags;
595597
return mr;
@@ -615,16 +617,14 @@ static struct mlx5_ib_mr *get_cache_mr(struct mlx5_cache_ent *req_ent)
615617
ent->available_mrs--;
616618
queue_adjust_cache_locked(ent);
617619
spin_unlock_irq(&ent->lock);
618-
break;
620+
mlx5_clear_mr(mr);
621+
return mr;
619622
}
620623
queue_adjust_cache_locked(ent);
621624
spin_unlock_irq(&ent->lock);
622625
}
623-
624-
if (!mr)
625-
req_ent->miss++;
626-
627-
return mr;
626+
req_ent->miss++;
627+
return NULL;
628628
}
629629

630630
static void detach_mr_from_cache(struct mlx5_ib_mr *mr)
@@ -993,8 +993,6 @@ static struct mlx5_ib_mr *alloc_cacheable_mr(struct ib_pd *pd,
993993

994994
mr->ibmr.pd = pd;
995995
mr->umem = umem;
996-
mr->access_flags = access_flags;
997-
mr->desc_size = sizeof(struct mlx5_mtt);
998996
mr->mmkey.iova = iova;
999997
mr->mmkey.size = umem->length;
1000998
mr->mmkey.pd = to_mpd(pd)->pdn;

drivers/infiniband/hw/mlx5/odp.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ static void free_implicit_child_mr(struct mlx5_ib_mr *mr, bool need_imr_xlt)
227227

228228
dma_fence_odp_mr(mr);
229229

230-
mr->parent = NULL;
231230
mlx5_mr_cache_free(mr_to_mdev(mr), mr);
232231
ib_umem_odp_release(odp);
233232
}

0 commit comments

Comments
 (0)