Page MenuHomeFreeBSD

D5210.diff
No OneTemporary

D5210.diff

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

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)

Event Timeline