/* Clear it, incase given cpu is set in nd_pmu->arch_cpumask */
cpumask_test_and_clear_cpu(cpu, &nd_pmu->arch_cpumask);
/* * If given cpu is not same as current designated cpu for * counter access, just return.
*/ if (cpu != nd_pmu->cpu) return 0;
/* Check for any active cpu in nd_pmu->arch_cpumask */
target = cpumask_any(&nd_pmu->arch_cpumask);
/* * Incase we don't have any active cpu in nd_pmu->arch_cpumask, * check in given cpu's numa node list.
*/ if (target >= nr_cpu_ids) {
nodeid = cpu_to_node(cpu);
cpumask = cpumask_of_node(nodeid);
target = cpumask_any_but(cpumask, cpu);
}
nd_pmu->cpu = target;
/* Migrate nvdimm pmu events to the new target cpu if valid */ if (target >= 0 && target < nr_cpu_ids)
perf_pmu_migrate_context(&nd_pmu->pmu, cpu, target);
/* * Incase of cpu hotplug feature, arch specific code * can provide required cpumask which can be used * to get designatd cpu for counter access. * Check for any active cpu in nd_pmu->arch_cpumask.
*/ if (!cpumask_empty(&nd_pmu->arch_cpumask)) {
nd_pmu->cpu = cpumask_any(&nd_pmu->arch_cpumask);
} else { /* pick active cpu from the cpumask of device numa node. */
nodeid = dev_to_node(nd_pmu->dev);
cpumask = cpumask_of_node(nodeid);
nd_pmu->cpu = cpumask_any(cpumask);
}
/* Register the pmu instance for cpu hotplug */
rc = cpuhp_state_add_instance_nocalls(nd_pmu->cpuhp_state, &nd_pmu->node); if (rc) {
cpuhp_remove_multi_state(nd_pmu->cpuhp_state); return rc;
}
/* Create cpumask attribute group */
rc = create_cpumask_attr_group(nd_pmu); if (rc) {
cpuhp_state_remove_instance_nocalls(nd_pmu->cpuhp_state, &nd_pmu->node);
cpuhp_remove_multi_state(nd_pmu->cpuhp_state); return rc;
}
if (nd_pmu->pmu.attr_groups[NVDIMM_PMU_CPUMASK_ATTR])
kfree(nd_pmu->pmu.attr_groups[NVDIMM_PMU_CPUMASK_ATTR]->attrs);
kfree(nd_pmu->pmu.attr_groups[NVDIMM_PMU_CPUMASK_ATTR]);
}
int register_nvdimm_pmu(struct nvdimm_pmu *nd_pmu, struct platform_device *pdev)
{ int rc;
if (!nd_pmu || !pdev) return -EINVAL;
/* event functions like add/del/read/event_init and pmu name should not be NULL */ if (WARN_ON_ONCE(!(nd_pmu->pmu.event_init && nd_pmu->pmu.add &&
nd_pmu->pmu.del && nd_pmu->pmu.read && nd_pmu->pmu.name))) return -EINVAL;
/* * Add platform_device->dev pointer to nvdimm_pmu to access * device data in events functions.
*/
nd_pmu->dev = &pdev->dev;
/* Fill attribute groups for the nvdimm pmu device */
nd_pmu->pmu.attr_groups[NVDIMM_PMU_FORMAT_ATTR] = &nvdimm_pmu_format_group;
nd_pmu->pmu.attr_groups[NVDIMM_PMU_EVENT_ATTR] = &nvdimm_pmu_events_group;
nd_pmu->pmu.attr_groups[NVDIMM_PMU_NULL_ATTR] = NULL;
/* Fill attribute group for cpumask */
rc = nvdimm_pmu_cpu_hotplug_init(nd_pmu); if (rc) {
pr_info("cpu hotplug feature failed for device: %s\n", nd_pmu->pmu.name);
kfree(nd_pmu->pmu.attr_groups); return rc;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.