aboutsummaryrefslogtreecommitdiff
path: root/sys/sys/bus.h
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2016-05-09 20:50:21 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2016-05-09 20:50:21 +0000
commit8d791e5af1e6773782656648cdef47bdc35002fb (patch)
treeaf412c855aeec6fd0582f885ff22d5e9bcb786e0 /sys/sys/bus.h
parent8dd5aa946f36d62f286eb56bdbc2767df0d7d17e (diff)
downloadsrc-8d791e5af1e6773782656648cdef47bdc35002fb.tar.gz
src-8d791e5af1e6773782656648cdef47bdc35002fb.zip
Add a new bus method to fetch device-specific CPU sets.
bus_get_cpus() returns a specified set of CPUs for a device. It accepts an enum for the second parameter that indicates the type of cpuset to request. Currently two valus are supported: - LOCAL_CPUS (on x86 this returns all the CPUs in the package closest to the device when DEVICE_NUMA is enabled) - INTR_CPUS (like LOCAL_CPUS but only returns 1 SMT thread for each core) For systems that do not support NUMA (or if it is not enabled in the kernel config), LOCAL_CPUS fails with EINVAL. INTR_CPUS is mapped to 'all_cpus' by default. The idea is that INTR_CPUS should always return a valid set. Device drivers which want to use per-CPU interrupts should start using INTR_CPUS instead of simply assigning interrupts to all available CPUs. In the future we may wish to add tunables to control the policy of INTR_CPUS (e.g. should it be local-only or global, should it ignore SMT threads or not). The x86 nexus driver exposes the internal set of interrupt CPUs from the the x86 interrupt code via INTR_CPUS. The ACPI bus driver and PCI bridge drivers use _PXM to return a suitable LOCAL_CPUS set when _PXM exists and DEVICE_NUMA is enabled. They also and the global INTR_CPUS set from the nexus driver with the per-domain set from _PXM to generate a local INTR_CPUS set for child devices. Compared to the r298933, this version uses 'struct _cpuset' in <sys/bus.h> instead of 'cpuset_t' to avoid requiring <sys/param.h> (<sys/_cpuset.h> still requires <sys/param.h> for MAXCPU even though <sys/_bitset.h> does not after recent changes).
Notes
Notes: svn path=/head/; revision=299286
Diffstat (limited to 'sys/sys/bus.h')
-rw-r--r--sys/sys/bus.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 4992cdb4847e..9b989af66031 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -272,6 +272,16 @@ enum intr_polarity {
INTR_POLARITY_LOW = 2
};
+/**
+ * CPU sets supported by bus_get_cpus(). Note that not all sets may be
+ * supported for a given device. If a request is not supported by a
+ * device (or its parents), then bus_get_cpus() will fail with EINVAL.
+ */
+enum cpu_sets {
+ LOCAL_CPUS = 0,
+ INTR_CPUS
+};
+
typedef int (*devop_t)(void);
/**
@@ -388,6 +398,8 @@ int bus_generic_deactivate_resource(device_t dev, device_t child, int type,
int rid, struct resource *r);
int bus_generic_detach(device_t dev);
void bus_generic_driver_added(device_t dev, driver_t *driver);
+int bus_generic_get_cpus(device_t dev, device_t child, enum cpu_sets op,
+ size_t setsize, struct _cpuset *cpuset);
bus_dma_tag_t
bus_generic_get_dma_tag(device_t dev, device_t child);
bus_space_tag_t
@@ -457,6 +469,8 @@ int bus_activate_resource(device_t dev, int type, int rid,
struct resource *r);
int bus_deactivate_resource(device_t dev, int type, int rid,
struct resource *r);
+int bus_get_cpus(device_t dev, enum cpu_sets op, size_t setsize,
+ struct _cpuset *cpuset);
bus_dma_tag_t bus_get_dma_tag(device_t dev);
bus_space_tag_t bus_get_bus_tag(device_t dev);
int bus_get_domain(device_t dev, int *domain);