Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109789020
D5210.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D5210.diff
View Options
Index: sys/amd64/include/intr_machdep.h
===================================================================
--- sys/amd64/include/intr_machdep.h
+++ sys/amd64/include/intr_machdep.h
@@ -143,6 +143,9 @@
register_t __padding; /* pad to 16 bytes */
};
+#ifdef SMP
+extern cpuset_t intr_cpus;
+#endif
extern struct mtx icu_lock;
extern int elcr_found;
Index: sys/dev/acpica/acpi.c
===================================================================
--- sys/dev/acpica/acpi.c
+++ sys/dev/acpica/acpi.c
@@ -209,6 +209,7 @@
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_hint_device_unit, acpi_hint_device_unit),
+ DEVMETHOD(bus_get_cpus, acpi_get_cpus),
DEVMETHOD(bus_get_domain, acpi_get_domain),
/* ACPI bus */
@@ -1072,6 +1073,28 @@
}
}
+int
+acpi_get_cpus(device_t dev, device_t child, enum cpu_sets op, cpuset_t *cpuset, int size)
+{
+ int rc, d, error;
+
+ if ((rc = acpi_get_domain(dev, child, &d)) != 0)
+ return (rc);
+
+ switch (op) {
+ case LOCAL_CPUS:
+ *cpuset = cpuset_domain[d];
+ return (0);
+ case INTR_CPUS:
+ if ((error = bus_generic_get_cpus(dev, child, op, cpuset, size)))
+ return (error);
+ CPU_AND(cpuset, &cpuset_domain[d]);
+ return (0);
+ default:
+ return (bus_generic_get_cpus(dev, child, op, cpuset, size));
+ }
+}
+
/*
* Fetch the VM domain for the given device 'dev'.
*
@@ -1085,9 +1108,10 @@
ACPI_HANDLE h;
int d, pxm;
- h = acpi_get_handle(dev);
- if ((h != NULL) &&
- ACPI_SUCCESS(acpi_GetInteger(h, "_PXM", &pxm))) {
+ if ((h = acpi_get_handle(dev)) == NULL)
+ return (ENOENT);
+
+ if (ACPI_SUCCESS(acpi_GetInteger(h, "_PXM", &pxm))) {
d = acpi_map_pxm_to_vm_domainid(pxm);
if (d < 0)
return (-1);
@@ -1095,7 +1119,6 @@
return (1);
}
#endif
-
return (0);
}
Index: sys/dev/acpica/acpi_pci.c
===================================================================
--- sys/dev/acpica/acpi_pci.c
+++ sys/dev/acpica/acpi_pci.c
@@ -98,6 +98,7 @@
DEVMETHOD(bus_read_ivar, acpi_pci_read_ivar),
DEVMETHOD(bus_write_ivar, acpi_pci_write_ivar),
DEVMETHOD(bus_child_location_str, acpi_pci_child_location_str_method),
+ DEVMETHOD(bus_get_cpus, acpi_get_cpus),
DEVMETHOD(bus_get_dma_tag, acpi_pci_get_dma_tag),
DEVMETHOD(bus_get_domain, acpi_get_domain),
Index: sys/dev/acpica/acpivar.h
===================================================================
--- sys/dev/acpica/acpivar.h
+++ sys/dev/acpica/acpivar.h
@@ -503,6 +503,9 @@
#if MAXMEMDOM > 1
extern int acpi_map_pxm_to_vm_domainid(int pxm);
#endif
+
+extern int acpi_get_cpus(device_t dev, device_t child, enum cpu_sets op,
+ cpuset_t *cpuset, int size);
extern int acpi_get_domain(device_t dev, device_t child, int *domain);
extern int acpi_parse_pxm(device_t dev, int *domain);
Index: sys/kern/bus_if.m
===================================================================
--- sys/kern/bus_if.m
+++ sys/kern/bus_if.m
@@ -707,3 +707,21 @@
device_t _child;
int *_domain;
} DEFAULT bus_generic_get_domain;
+
+/**
+ * @brief Request a set of CPUs
+ *
+ * @param _dev the bus device
+ * @param _child the child device
+ * @param _op type of CPUs to request
+ * @param _cpuset a pointer to a cpuset to receive the requested set of CPUs
+ * @param _size size of cpuset
+ *
+ */
+METHOD int get_cpus {
+ device_t _dev;
+ device_t _child;
+ enum cpu_sets _op;
+ cpuset_t *_cpuset;
+ int _size;
+} DEFAULT bus_generic_get_cpus;
Index: sys/kern/subr_bus.c
===================================================================
--- sys/kern/subr_bus.c
+++ sys/kern/subr_bus.c
@@ -49,6 +49,7 @@
#include <sys/rman.h>
#include <sys/selinfo.h>
#include <sys/signalvar.h>
+#include <sys/smp.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/uio.h>
@@ -4079,6 +4080,23 @@
}
/**
+ * @brief Helper function for implementing BUS_GET_CPUS().
+ *
+ * This simple implementation of BUS_GET_CPUS() simply calls the
+ * BUS_GET_CPUS() method of the parent of @p dev.
+ */
+int
+bus_generic_get_cpus(device_t dev, device_t child, enum cpu_sets op,
+ cpuset_t *cpuset, int size)
+{
+
+ /* Propagate up the bus hierarchy until someone handles it. */
+ if (dev->parent != NULL)
+ return (BUS_GET_CPUS(dev->parent, child, op, cpuset, size));
+ return (EINVAL);
+}
+
+/**
* @brief Helper function for implementing BUS_GET_DMA_TAG().
*
* This simple implementation of BUS_GET_DMA_TAG() simply calls the
@@ -4559,6 +4577,28 @@
}
/**
+ * @brief Wrapper function for BUS_GET_CPUS().
+ *
+ * This function simply calls the BUS_GET_CPUS() method of the
+ * parent of @p dev.
+ */
+int
+bus_get_cpus(device_t dev, enum cpu_sets op, cpuset_t *cpuset, int size)
+{
+ device_t parent;
+
+ /*
+ * How should we handle size mismatch?
+ */
+ if (size < sizeof(cpuset_t))
+ return (ENXIO);
+ parent = device_get_parent(dev);
+ if (parent == NULL)
+ return (EINVAL);
+ return (BUS_GET_CPUS(parent, dev, op, cpuset, size));
+}
+
+/**
* @brief Wrapper function for BUS_GET_DMA_TAG().
*
* This function simply calls the BUS_GET_DMA_TAG() method of the
@@ -4633,6 +4673,20 @@
return (-1);
}
+static int
+root_get_cpus(device_t dev, device_t child, enum cpu_sets op, cpuset_t *cpuset, int size)
+{
+
+ switch (op) {
+ case INTR_CPUS:
+ /* Default to returning the set of all CPUs. */
+ *cpuset = all_cpus;
+ return (0);
+ default:
+ return (EINVAL);
+ }
+}
+
static kobj_method_t root_methods[] = {
/* Device interface */
KOBJMETHOD(device_shutdown, bus_generic_shutdown),
@@ -4645,6 +4699,7 @@
KOBJMETHOD(bus_write_ivar, bus_generic_write_ivar),
KOBJMETHOD(bus_setup_intr, root_setup_intr),
KOBJMETHOD(bus_child_present, root_child_present),
+ KOBJMETHOD(bus_get_cpus, root_get_cpus),
KOBJMETHOD_END
};
Index: sys/sys/_cpuset.h
===================================================================
--- sys/sys/_cpuset.h
+++ sys/sys/_cpuset.h
@@ -32,6 +32,7 @@
#ifndef _SYS__CPUSET_H_
#define _SYS__CPUSET_H_
+#include <sys/param.h>
#include <sys/_bitset.h>
#ifdef _KERNEL
Index: sys/sys/bus.h
===================================================================
--- sys/sys/bus.h
+++ sys/sys/bus.h
@@ -31,6 +31,7 @@
#include <machine/_limits.h>
#include <sys/_bus_dma.h>
+#include <sys/_cpuset.h>
#include <sys/ioccom.h>
/**
@@ -265,6 +266,16 @@
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);
/**
@@ -381,6 +392,8 @@
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,
+ cpuset_t *cpuset, int size);
bus_dma_tag_t
bus_generic_get_dma_tag(device_t dev, device_t child);
int bus_generic_get_domain(device_t dev, device_t child, int *domain);
@@ -447,6 +460,7 @@
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, cpuset_t *cpuset, int size);
bus_dma_tag_t bus_get_dma_tag(device_t dev);
int bus_get_domain(device_t dev, int *domain);
int bus_release_resource(device_t dev, int type, int rid,
Index: sys/x86/x86/intr_machdep.c
===================================================================
--- sys/x86/x86/intr_machdep.c
+++ sys/x86/x86/intr_machdep.c
@@ -475,7 +475,7 @@
* allocate CPUs round-robin.
*/
-static cpuset_t intr_cpus = CPUSET_T_INITIALIZER(0x1);
+cpuset_t intr_cpus = CPUSET_T_INITIALIZER(0x1);
static int current_cpu;
/*
Index: sys/x86/x86/nexus.c
===================================================================
--- sys/x86/x86/nexus.c
+++ sys/x86/x86/nexus.c
@@ -128,6 +128,7 @@
static int nexus_get_resource(device_t, device_t, int, int,
rman_res_t *, rman_res_t *);
static void nexus_delete_resource(device_t, device_t, int, int);
+static int nexus_get_cpus(device_t, device_t, enum cpu_sets, cpuset_t *, int size);
#ifdef DEV_APIC
static int nexus_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs);
static int nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs);
@@ -164,6 +165,7 @@
DEVMETHOD(bus_set_resource, nexus_set_resource),
DEVMETHOD(bus_get_resource, nexus_get_resource),
DEVMETHOD(bus_delete_resource, nexus_delete_resource),
+ DEVMETHOD(bus_get_cpus, nexus_get_cpus),
/* pcib interface */
#ifdef DEV_APIC
@@ -616,6 +618,21 @@
resource_list_delete(rl, type, rid);
}
+static int
+nexus_get_cpus(device_t dev, device_t child, enum cpu_sets op, cpuset_t *cpuset, int size)
+{
+
+ switch (op) {
+#ifdef SMP
+ case INTR_CPUS:
+ *cpuset = intr_cpus;
+ return (0);
+#endif
+ default:
+ return (bus_generic_get_cpus(dev, child, op, cpuset, size));
+ }
+}
+
/* Called from the MSI code to add new IRQs to the IRQ rman. */
void
nexus_add_irq(u_long irq)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 10, 1:19 PM (6 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16578009
Default Alt Text
D5210.diff (8 KB)
Attached To
Mode
D5210: add get_cpus interface
Attached
Detach File
Event Timeline
Log In to Comment