Unverified Commit 03fe15a0 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!7912 RDMA/hns: Some bugfixes for openeuler 22.03 sp4

Merge Pull Request from: @ygf_123 
 
Some bugfixes for openeuler 22.03 sp4.

Chengchang Tang (3):
  RDMA/hns: Fix missing resetting notify
  RDMA/hns: Use mutex to protect uconctext
  RDMA/hns: Fix allocating POE channels after IB device registeration

wenglianfa (1):
  RDMA/hns : Fix scc delay_work to execute after sysfs shutdown

https://gitee.com/openeuler/kernel/issues/I9QO9C 
 
Link:https://gitee.com/openeuler/kernel/pulls/7912

 

Reviewed-by: default avatarChengchang Tang <tangchengchang@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 364777dc 1bb63063
Loading
Loading
Loading
Loading
+85 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 * Copyright 2019 Marvell. All rights reserved.
 */
#include <linux/xarray.h>
#include <linux/sched/mm.h>
#include "uverbs.h"
#include "core_priv.h"

@@ -365,3 +366,87 @@ int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext,
						 U32_MAX);
}
EXPORT_SYMBOL(rdma_user_mmap_entry_insert);

void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
{
	struct rdma_umap_priv *priv, *next_priv;

	lockdep_assert_held(&ufile->hw_destroy_rwsem);

	while (1) {
		struct mm_struct *mm = NULL;

		/* Get an arbitrary mm pointer that hasn't been cleaned yet */
		mutex_lock(&ufile->umap_lock);
		while (!list_empty(&ufile->umaps)) {
			int ret;

			priv = list_first_entry(&ufile->umaps,
						struct rdma_umap_priv, list);
			mm = priv->vma->vm_mm;
			ret = mmget_not_zero(mm);
			if (!ret) {
				list_del_init(&priv->list);
				if (priv->entry) {
					rdma_user_mmap_entry_put(priv->entry);
					priv->entry = NULL;
				}
				mm = NULL;
				continue;
			}
			break;
		}
		mutex_unlock(&ufile->umap_lock);
		if (!mm)
			return;

		/*
		 * The umap_lock is nested under mmap_lock since it used within
		 * the vma_ops callbacks, so we have to clean the list one mm
		 * at a time to get the lock ordering right. Typically there
		 * will only be one mm, so no big deal.
		 */
		mmap_read_lock(mm);
		mutex_lock(&ufile->umap_lock);
		list_for_each_entry_safe(priv, next_priv, &ufile->umaps, list) {
			struct vm_area_struct *vma = priv->vma;

			if (vma->vm_mm != mm)
				continue;
			list_del_init(&priv->list);

			zap_vma_ptes(vma, vma->vm_start,
				     vma->vm_end - vma->vm_start);

			if (priv->entry) {
				rdma_user_mmap_entry_put(priv->entry);
				priv->entry = NULL;
			}
		}
		mutex_unlock(&ufile->umap_lock);
		mmap_read_unlock(mm);
		mmput(mm);
	}
}
EXPORT_SYMBOL(uverbs_user_mmap_disassociate);

/**
 * rdma_user_mmap_disassociate() - disassociate the mmap from the ucontext.
 *
 * @ucontext: associated user context.
 *
 * This function should be called by drivers that need to disable mmap for
 * some ucontexts.
 */
void rdma_user_mmap_disassociate(struct ib_ucontext *ucontext)
{
	struct ib_uverbs_file *ufile = ucontext->ufile;

	/* Racing with uverbs_destroy_ufile_hw */
	if (!down_read_trylock(&ufile->hw_destroy_rwsem))
		return;

	uverbs_user_mmap_disassociate(ufile);
	up_read(&ufile->hw_destroy_rwsem);
}
EXPORT_SYMBOL(rdma_user_mmap_disassociate);
+0 −1
Original line number Diff line number Diff line
@@ -149,7 +149,6 @@ void uverbs_disassociate_api(struct uverbs_api *uapi);
void uverbs_destroy_api(struct uverbs_api *uapi);
void uapi_compute_bundle_size(struct uverbs_api_ioctl_method *method_elm,
			      unsigned int num_attrs);
void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile);

extern const struct uapi_definition uverbs_def_obj_async_fd[];
extern const struct uapi_definition uverbs_def_obj_counters[];
+0 −64
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@
#include <linux/cdev.h>
#include <linux/anon_inodes.h>
#include <linux/slab.h>
#include <linux/sched/mm.h>

#include <linux/uaccess.h>

@@ -806,69 +805,6 @@ static const struct vm_operations_struct rdma_umap_ops = {
	.fault = rdma_umap_fault,
};

void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
{
	struct rdma_umap_priv *priv, *next_priv;

	lockdep_assert_held(&ufile->hw_destroy_rwsem);

	while (1) {
		struct mm_struct *mm = NULL;

		/* Get an arbitrary mm pointer that hasn't been cleaned yet */
		mutex_lock(&ufile->umap_lock);
		while (!list_empty(&ufile->umaps)) {
			int ret;

			priv = list_first_entry(&ufile->umaps,
						struct rdma_umap_priv, list);
			mm = priv->vma->vm_mm;
			ret = mmget_not_zero(mm);
			if (!ret) {
				list_del_init(&priv->list);
				if (priv->entry) {
					rdma_user_mmap_entry_put(priv->entry);
					priv->entry = NULL;
				}
				mm = NULL;
				continue;
			}
			break;
		}
		mutex_unlock(&ufile->umap_lock);
		if (!mm)
			return;

		/*
		 * The umap_lock is nested under mmap_lock since it used within
		 * the vma_ops callbacks, so we have to clean the list one mm
		 * at a time to get the lock ordering right. Typically there
		 * will only be one mm, so no big deal.
		 */
		mmap_read_lock(mm);
		mutex_lock(&ufile->umap_lock);
		list_for_each_entry_safe (priv, next_priv, &ufile->umaps,
					  list) {
			struct vm_area_struct *vma = priv->vma;

			if (vma->vm_mm != mm)
				continue;
			list_del_init(&priv->list);

			zap_vma_ptes(vma, vma->vm_start,
				     vma->vm_end - vma->vm_start);

			if (priv->entry) {
				rdma_user_mmap_entry_put(priv->entry);
				priv->entry = NULL;
			}
		}
		mutex_unlock(&ufile->umap_lock);
		mmap_read_unlock(mm);
		mmput(mm);
	}
}

/*
 * ib_uverbs_open() does not need the BKL:
 *
+2 −4
Original line number Diff line number Diff line
@@ -287,13 +287,11 @@ static void dca_stats_dev_pool_in_seqfile(struct hns_roce_dev *hr_dev,
	/* Write kernel DCA pool stats */
	dca_print_pool_stats(&hr_dev->dca_ctx, 0, true, file);
	/* Write user DCA pool stats */
	spin_lock(&hr_dev->uctx_list_lock);
	mutex_lock(&hr_dev->uctx_list_mutex);
	list_for_each_entry_safe(uctx, tmp, &hr_dev->uctx_list, list) {
		spin_unlock(&hr_dev->uctx_list_lock);
		dca_print_pool_stats(&uctx->dca_ctx, uctx->pid, false, file);
		spin_lock(&hr_dev->uctx_list_lock);
	}
	spin_unlock(&hr_dev->uctx_list_lock);
	mutex_unlock(&hr_dev->uctx_list_mutex);
}

struct dca_qp_stats {
+1 −1
Original line number Diff line number Diff line
@@ -1126,7 +1126,7 @@ struct hns_roce_dev {
	struct hns_roce_dev_debugfs dbgfs; /* debugfs for this dev */

	struct list_head	uctx_list; /* list of all uctx on this dev */
	spinlock_t		uctx_list_lock; /* protect @uctx_list */
	struct mutex		uctx_list_mutex; /* protect @uctx_list */

	struct hns_roce_uar     priv_uar;
	const char		*irq_names[HNS_ROCE_MAX_IRQ_NUM];
Loading