Commit 16fa6431 authored by Kan Liang's avatar Kan Liang Committed by Peter Zijlstra
Browse files

perf/x86/intel/uncore: Factor out uncore_pci_pmu_register()



The PMU registration in the uncore PCI sub driver is similar as the
normal PMU registration for a PCI device. The codes to register a PCI
PMU can be shared.

Factor out uncore_pci_pmu_register(), which will be used later.

The pci_set_drvdata() is not included in uncore_pci_pmu_register(). The
uncore PCI sub driver doesn't own the PCI device. It will not touch the
private driver data pointer for the device.

Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/1600094060-82746-4-git-send-email-kan.liang@linux.intel.com
parent 8ed2ccaa
Loading
Loading
Loading
Loading
+51 −31
Original line number Diff line number Diff line
@@ -1039,6 +1039,55 @@ uncore_pci_find_dev_pmu(struct pci_dev *pdev, const struct pci_device_id *ids)
	return pmu;
}

/*
 * Register the PMU for a PCI device
 * @pdev: The PCI device.
 * @type: The corresponding PMU type of the device.
 * @pmu: The corresponding PMU of the device.
 * @phys_id: The physical socket id which the device maps to.
 * @die: The die id which the device maps to.
 */
static int uncore_pci_pmu_register(struct pci_dev *pdev,
				   struct intel_uncore_type *type,
				   struct intel_uncore_pmu *pmu,
				   int phys_id, int die)
{
	struct intel_uncore_box *box;
	int ret;

	if (WARN_ON_ONCE(pmu->boxes[die] != NULL))
		return -EINVAL;

	box = uncore_alloc_box(type, NUMA_NO_NODE);
	if (!box)
		return -ENOMEM;

	if (pmu->func_id < 0)
		pmu->func_id = pdev->devfn;
	else
		WARN_ON_ONCE(pmu->func_id != pdev->devfn);

	atomic_inc(&box->refcnt);
	box->pci_phys_id = phys_id;
	box->dieid = die;
	box->pci_dev = pdev;
	box->pmu = pmu;
	uncore_box_init(box);

	pmu->boxes[die] = box;
	if (atomic_inc_return(&pmu->activeboxes) > 1)
		return 0;

	/* First active box registers the pmu */
	ret = uncore_pmu_register(pmu);
	if (ret) {
		pmu->boxes[die] = NULL;
		uncore_box_exit(box);
		kfree(box);
	}
	return ret;
}

/*
 * add a pci uncore device
 */
@@ -1046,7 +1095,6 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
{
	struct intel_uncore_type *type;
	struct intel_uncore_pmu *pmu = NULL;
	struct intel_uncore_box *box;
	int phys_id, die, ret;

	ret = uncore_pci_get_dev_die_info(pdev, &phys_id, &die);
@@ -1082,38 +1130,10 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
		pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
	}

	if (WARN_ON_ONCE(pmu->boxes[die] != NULL))
		return -EINVAL;

	box = uncore_alloc_box(type, NUMA_NO_NODE);
	if (!box)
		return -ENOMEM;

	if (pmu->func_id < 0)
		pmu->func_id = pdev->devfn;
	else
		WARN_ON_ONCE(pmu->func_id != pdev->devfn);

	atomic_inc(&box->refcnt);
	box->pci_phys_id = phys_id;
	box->dieid = die;
	box->pci_dev = pdev;
	box->pmu = pmu;
	uncore_box_init(box);
	pci_set_drvdata(pdev, box);
	ret = uncore_pci_pmu_register(pdev, type, pmu, phys_id, die);

	pmu->boxes[die] = box;
	if (atomic_inc_return(&pmu->activeboxes) > 1)
		return 0;
	pci_set_drvdata(pdev, pmu->boxes[die]);

	/* First active box registers the pmu */
	ret = uncore_pmu_register(pmu);
	if (ret) {
		pci_set_drvdata(pdev, NULL);
		pmu->boxes[die] = NULL;
		uncore_box_exit(box);
		kfree(box);
	}
	return ret;
}