diff options
author | John Levon <john.levon@joyent.com> | 2018-08-17 12:57:01 +0000 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2019-09-04 02:22:58 -0700 |
commit | a8ea0c9dd566453d9b69eab5f863930da9d0c4ae (patch) | |
tree | 877187685b58e8cecf3397e20447193296d1ad0a | |
parent | cd4bec9bcc617ecbc586bb4c2feb7096df189b13 (diff) | |
download | illumos-joyent-a8ea0c9dd566453d9b69eab5f863930da9d0c4ae.tar.gz |
11584 ::xcall would be useful
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
-rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_ctf.c | 28 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_ctf.h | 3 | ||||
-rw-r--r-- | usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile | 4 | ||||
-rw-r--r-- | usr/src/cmd/mdb/i86pc/modules/unix/unix.c | 12 | ||||
-rw-r--r-- | usr/src/cmd/mdb/i86pc/modules/unix/xcall.c | 237 | ||||
-rw-r--r-- | usr/src/cmd/mdb/i86xpv/modules/unix/amd64/Makefile | 4 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/x_call.c | 70 | ||||
-rw-r--r-- | usr/src/uts/i86pc/sys/machcpuvar.h | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/sys/x_call.h | 14 |
9 files changed, 314 insertions, 61 deletions
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c index 9af52917b4..1be7357f05 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c @@ -24,7 +24,7 @@ */ /* * Copyright (c) 2013, 2016 by Delphix. All rights reserved. - * Copyright (c) 2015, Joyent, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. */ #include <mdb/mdb_ctf.h> @@ -1236,8 +1236,9 @@ member_cb(const char *name, mdb_ctf_id_t modmid, ulong_t modoff, void *data) "member %s of type %s", name, mp->m_tgtname); if (mdb_ctf_member_info(mp->m_tgtid, name, &tgtoff, &tgtmid) != 0) { - mdb_ctf_warn(mp->m_flags, - "could not find %s\n", tgtname); + if (mp->m_flags & MDB_CTF_VREAD_IGNORE_ABSENT) + return (0); + mdb_ctf_warn(mp->m_flags, "could not find %s\n", tgtname); return (set_errno(EMDB_CTFNOMEMB)); } @@ -1612,12 +1613,11 @@ vread_helper(mdb_ctf_id_t modid, char *modbuf, * Warning: it will therefore only work with enums are only used to store * legitimate enum values (not several values or-ed together). * - * By default, if mdb_ctf_vread() can not find any members or enum values, - * it will print a descriptive message (with mdb_warn()) and fail. - * Passing MDB_CTF_VREAD_QUIET in 'flags' will suppress the warning message. - * Additional flags can be used to ignore specific types of translation - * failure, but should be used with caution, because they will silently leave - * the caller's buffer uninitialized. + * Flags values: + * + * MDB_CTF_VREAD_QUIET: keep quiet about failures + * MDB_CTF_VREAD_IGNORE_ABSENT: ignore any member that couldn't be found in the + * target struct; be careful not to use an uninitialized result. */ int mdb_ctf_vread(void *modbuf, const char *target_typename, @@ -1630,6 +1630,7 @@ mdb_ctf_vread(void *modbuf, const char *target_typename, mdb_ctf_id_t tgtid; mdb_ctf_id_t modid; mdb_module_t *mod; + int ret; if ((mod = mdb_get_module()) == NULL || (mfp = mod->mod_ctfp) == NULL) { mdb_ctf_warn(flags, "no ctf data found for mdb module %s\n", @@ -1662,15 +1663,20 @@ mdb_ctf_vread(void *modbuf, const char *target_typename, return (-1); /* errno is set for us */ } - tgtbuf = mdb_alloc(size, UM_SLEEP | UM_GC); + tgtbuf = mdb_alloc(size, UM_SLEEP); if (mdb_vread(tgtbuf, size, addr) < 0) { mdb_ctf_warn(flags, "couldn't read %s from %p\n", target_typename, addr); + mdb_free(tgtbuf, size); return (-1); /* errno is set for us */ } - return (vread_helper(modid, modbuf, tgtid, tgtbuf, NULL, flags)); + ret = vread_helper(modid, modbuf, tgtid, tgtbuf, NULL, flags); + + mdb_free(tgtbuf, size); + + return (ret); } /* diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.h b/usr/src/cmd/mdb/common/mdb/mdb_ctf.h index 21f27d782b..74bc8e95da 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.h @@ -24,7 +24,7 @@ */ /* * Copyright (c) 2013, 2015 by Delphix. All rights reserved. - * Copyright (c) 2015, Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ #ifndef _MDB_CTF_H @@ -142,6 +142,7 @@ extern ssize_t mdb_ctf_offset_to_name(mdb_ctf_id_t, ulong_t, char *, size_t, int, mdb_ctf_id_t *, ulong_t *); #define MDB_CTF_VREAD_QUIET 0x100 +#define MDB_CTF_VREAD_IGNORE_ABSENT 0x200 extern int mdb_ctf_vread(void *, const char *, const char *, uintptr_t, uint_t); diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile b/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile index 23984a8f08..efcfad5375 100644 --- a/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile +++ b/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile @@ -22,12 +22,12 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright 2016 Joyent, Inc. +# Copyright 2018 Joyent, Inc. MODULE = unix.so MDBTGT = kvm -MODSRCS = unix.c i86mmu.c +MODSRCS = unix.c i86mmu.c xcall.c MODASMSRCS = unix_sup.s include ../../../../../Makefile.cmd diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/unix.c b/usr/src/cmd/mdb/i86pc/modules/unix/unix.c index 24267e6190..e91321b235 100644 --- a/usr/src/cmd/mdb/i86pc/modules/unix/unix.c +++ b/usr/src/cmd/mdb/i86pc/modules/unix/unix.c @@ -802,7 +802,7 @@ scalehrtime_help(void) /*ARGSUSED*/ static int -scalehrtime_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +scalehrtime_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint32_t nsec_scale; hrtime_t tsc = addr, hrt, tsc_last, base, mult = 1; @@ -904,7 +904,7 @@ scalehrtime_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) */ /*ARGSUSED*/ static int -x86_featureset_cmd(uintptr_t addr, uint_t flags, int argc, +x86_featureset_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { void *fset; @@ -1035,6 +1035,9 @@ sysregs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) } #endif +extern void xcall_help(void); +extern int xcall_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *); + static const mdb_dcmd_t dcmds[] = { { "gate_desc", ":", "dump a gate descriptor", gate_desc }, { "idt", ":[-v]", "dump an IDT", idt }, @@ -1058,9 +1061,10 @@ static const mdb_dcmd_t dcmds[] = { mfntopfn_dcmd }, { "memseg_list", ":", "show memseg list", memseg_list }, { "scalehrtime", ":[-a|-r]", "scale an unscaled high-res time", - scalehrtime_cmd, scalehrtime_help }, + scalehrtime_dcmd, scalehrtime_help }, { "x86_featureset", NULL, "dump the x86_featureset vector", - x86_featureset_cmd }, + x86_featureset_dcmd }, + { "xcall", ":", "print CPU cross-call state", xcall_dcmd, xcall_help }, #ifdef _KMDB { "sysregs", NULL, "dump system registers", sysregs_dcmd }, #endif diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/xcall.c b/usr/src/cmd/mdb/i86pc/modules/unix/xcall.c new file mode 100644 index 0000000000..a3057daff1 --- /dev/null +++ b/usr/src/cmd/mdb/i86pc/modules/unix/xcall.c @@ -0,0 +1,237 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ +/* + * Copyright 2019 Joyent, Inc. + */ + +#include <mdb/mdb_modapi.h> +#include <mdb/mdb_ctf.h> +#include <sys/cpuvar.h> +#include <sys/x_call.h> + +typedef struct { + uint32_t xc_work_cnt; + struct xc_msg *xc_curmsg; + struct xc_msg *xc_msgbox; + xc_data_t xc_data; +} mdb_xcall_machcpu_t; + +typedef struct { + processorid_t cpu_id; + mdb_xcall_machcpu_t cpu_m; +} mdb_xcall_cpu_t; + +typedef struct { + uint_t xd_flags; + processorid_t xd_cpu_id; + size_t xd_msg_index; + struct xc_msg xd_msgs[NCPU]; +} xcall_data_t; + +void +xcall_help(void) +{ + mdb_printf( + "Print all active cross-calls where the given CPU is the master.\n" + "The PEND column is ->xc_work_cnt, the pending message count -\n" + "this includes both master and slave messages. For each\n" + "cross call, the message type and the slave CPU ID are shown.\n"); +} + +static int +cpu_id_to_addr(processorid_t cpun, uintptr_t *addrp) +{ + uintptr_t addr; + GElf_Sym sym; + + if (mdb_lookup_by_name("cpu", &sym) == -1) { + mdb_warn("failed to find symbol for 'cpu'"); + return (-1); + } + + if (cpun * sizeof (uintptr_t) > sym.st_size) + return (-1); + + addr = (uintptr_t)sym.st_value + cpun * sizeof (uintptr_t); + + if (mdb_vread(&addr, sizeof (addr), addr) == -1) { + mdb_warn("failed to read cpu[%lu]", cpun); + return (-1); + } + + if (addr != (uintptr_t)NULL) { + *addrp = addr; + return (0); + } + + return (-1); +} + +static int +xcall_copy_msg(struct xc_msg *msg, xcall_data_t *data, boolean_t current) +{ + if (data->xd_msg_index >= NCPU) { + mdb_warn("ran out of msg space: %lu >= %lu\n", + data->xd_msg_index, NCPU); + return (-1); + } + + bcopy(msg, &data->xd_msgs[data->xd_msg_index], sizeof (*msg)); + + /* + * As we don't use .xc_next, store 'current' there. + */ + data->xd_msgs[data->xd_msg_index].xc_next = (void *)(uintptr_t)current; + data->xd_msg_index++; + return (0); +} + +static int +xcall_get_msgs(uintptr_t addr, const void *wdata, void *priv) +{ + _NOTE(ARGUNUSED(wdata)); + xcall_data_t *data = priv; + mdb_xcall_cpu_t xcpu = { 0, }; + struct xc_msg msg; + uintptr_t msgaddr; + + if (mdb_ctf_vread(&xcpu, "unix`cpu_t", "mdb_xcall_cpu_t", + addr, MDB_CTF_VREAD_IGNORE_ABSENT) == -1) + return (WALK_ERR); + + if (xcpu.cpu_m.xc_curmsg != NULL) { + msgaddr = (uintptr_t)xcpu.cpu_m.xc_curmsg; + + if (mdb_vread(&msg, sizeof (msg), msgaddr) != sizeof (msg)) + return (WALK_ERR); + + if (msg.xc_master == data->xd_cpu_id) { + if (data->xd_flags & DCMD_PIPE_OUT) + mdb_printf("%p\n", msgaddr); + else if (xcall_copy_msg(&msg, data, B_TRUE) != 0) + return (WALK_ERR); + } + } + + for (msgaddr = (uintptr_t)xcpu.cpu_m.xc_msgbox; + msgaddr != (uintptr_t)NULL; msgaddr = (uintptr_t)msg.xc_next) { + if (mdb_vread(&msg, sizeof (msg), msgaddr) != sizeof (msg)) + return (WALK_ERR); + + if (msg.xc_master != data->xd_cpu_id) + continue; + + if (data->xd_flags & DCMD_PIPE_OUT) + mdb_printf("%p\n", msgaddr); + else if (xcall_copy_msg(&msg, data, B_FALSE) != 0) + return (WALK_ERR); + } + + return (WALK_NEXT); +} + +static int +print_xcall_msg(struct xc_msg *msg) +{ + boolean_t current = (boolean_t)msg->xc_next; + char indent[] = " "; + const char *cmd; + + switch (msg->xc_command) { + case XC_MSG_ASYNC: cmd = "ASYNC"; break; + case XC_MSG_CALL: cmd = "CALL"; break; + case XC_MSG_SYNC: cmd = "SYNC"; break; + case XC_MSG_FREE:cmd = "FREE"; break; + case XC_MSG_WAITING: cmd = "WAITING"; break; + case XC_MSG_RELEASED: cmd = "RELEASED"; break; + case XC_MSG_DONE: cmd = "DONE"; break; + default: cmd = "?"; break; + } + + mdb_printf("%s %s%-*s %-6u\n", indent, current ? "*" : "", + 9 - current, cmd, msg->xc_slave); + return (0); +} + +/* + * Show all xcall messages where the master is the given CPU. + * + * As non-free messages can be on the slave's ->xc_msgbox or ->xc_curmsg, we + * need to walk across all of them to find each message where ->xc_master + * is our CPU ID. + */ +int +xcall_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + mdb_xcall_cpu_t xcpu = { 0, }; + xcall_data_t data = { 0, }; + + if (mdb_getopts(argc, argv, NULL) != argc) + return (DCMD_USAGE); + + /* + * Yep, this will re-collect all the messages each time. Shrug. + */ + if (!(flags & DCMD_ADDRSPEC)) { + if (mdb_pwalk_dcmd("cpu", "xcall", argc, argv, 0) == -1) { + mdb_warn("can't walk CPUs"); + return (DCMD_ERR); + } + + return (DCMD_OK); + } + + if (addr < NCPU && cpu_id_to_addr((processorid_t)addr, &addr) != 0) { + mdb_warn("invalid CPU ID %lu\n", addr); + return (DCMD_ERR); + } + + if (mdb_ctf_vread(&xcpu, "unix`cpu_t", "mdb_xcall_cpu_t", + addr, MDB_CTF_VREAD_IGNORE_ABSENT) == -1) { + mdb_warn("couldn't read cpu 0x%lx", addr); + return (DCMD_ERR); + } + + data.xd_cpu_id = xcpu.cpu_id; + data.xd_flags = flags; + + if (mdb_pwalk("cpu", xcall_get_msgs, &data, (uintptr_t)NULL) == -1) { + mdb_warn("can't walk CPUs"); + return (DCMD_ERR); + } + + if (flags & DCMD_PIPE_OUT) + return (DCMD_OK); + + if (DCMD_HDRSPEC(flags)) + mdb_printf("%<u>%3s %4s %s%</u>\n", "CPU", "PEND", "HANDLER"); + + if (data.xd_msg_index == 0) { + mdb_printf("%3d %4d -\n", + xcpu.cpu_id, xcpu.cpu_m.xc_work_cnt); + return (DCMD_OK); + } + + mdb_printf("%3d %4d %a(%a, %a, %a)\n", + xcpu.cpu_id, xcpu.cpu_m.xc_work_cnt, + xcpu.cpu_m.xc_data.xc_func, xcpu.cpu_m.xc_data.xc_a1, + xcpu.cpu_m.xc_data.xc_a2, xcpu.cpu_m.xc_data.xc_a3); + + if (!(flags & DCMD_PIPE_OUT)) + mdb_printf(" %<u>%-9s %-6s%</u>\n", "COMMAND", "SLAVE"); + + for (size_t i = 0; i < data.xd_msg_index; i++) { + if (print_xcall_msg(&data.xd_msgs[i]) != 0) + return (DCMD_ERR); + } + + return (DCMD_OK); +} diff --git a/usr/src/cmd/mdb/i86xpv/modules/unix/amd64/Makefile b/usr/src/cmd/mdb/i86xpv/modules/unix/amd64/Makefile index 190631bbf0..32c1fe33fd 100644 --- a/usr/src/cmd/mdb/i86xpv/modules/unix/amd64/Makefile +++ b/usr/src/cmd/mdb/i86xpv/modules/unix/amd64/Makefile @@ -22,12 +22,12 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright 2016 Joyent, Inc. +# Copyright 2018 Joyent, Inc. MODULE = unix.so MDBTGT = kvm -MODSRCS = unix.c i86mmu.c +MODSRCS = unix.c i86mmu.c xcall.c MODASMSRCS = unix_sup.s include ../../../../../Makefile.cmd diff --git a/usr/src/uts/i86pc/os/x_call.c b/usr/src/uts/i86pc/os/x_call.c index 814e7a0026..4eeb5aaa08 100644 --- a/usr/src/uts/i86pc/os/x_call.c +++ b/usr/src/uts/i86pc/os/x_call.c @@ -25,6 +25,7 @@ /* * Copyright (c) 2010, Intel Corporation. * All rights reserved. + * Copyright 2018 Joyent, Inc. */ #include <sys/types.h> @@ -79,38 +80,29 @@ * on a different Virtual Address at the same time. The old code required * N squared IPIs. With this method, depending on timing, it could happen * with just N IPIs. - */ - -/* - * The default is to not enable collecting counts of IPI information, since - * the updating of shared cachelines could cause excess bus traffic. - */ -uint_t xc_collect_enable = 0; -uint64_t xc_total_cnt = 0; /* total #IPIs sent for cross calls */ -uint64_t xc_multi_cnt = 0; /* # times we piggy backed on another IPI */ - -/* - * Values for message states. Here are the normal transitions. A transition - * of "->" happens in the slave cpu and "=>" happens in the master cpu as - * the messages are passed back and forth. + * + * Here are the normal transitions for XC_MSG_* values in ->xc_command. A + * transition of "->" happens in the slave cpu and "=>" happens in the master + * cpu as the messages are passed back and forth. * * FREE => ASYNC -> DONE => FREE * FREE => CALL -> DONE => FREE * FREE => SYNC -> WAITING => RELEASED -> DONE => FREE * - * The interesing one above is ASYNC. You might ask, why not go directly - * to FREE, instead of DONE. If it did that, it might be possible to exhaust + * The interesting one above is ASYNC. You might ask, why not go directly + * to FREE, instead of DONE? If it did that, it might be possible to exhaust * the master's xc_free list if a master can generate ASYNC messages faster * then the slave can process them. That could be handled with more complicated * handling. However since nothing important uses ASYNC, I've not bothered. */ -#define XC_MSG_FREE (0) /* msg in xc_free queue */ -#define XC_MSG_ASYNC (1) /* msg in slave xc_msgbox */ -#define XC_MSG_CALL (2) /* msg in slave xc_msgbox */ -#define XC_MSG_SYNC (3) /* msg in slave xc_msgbox */ -#define XC_MSG_WAITING (4) /* msg in master xc_msgbox or xc_waiters */ -#define XC_MSG_RELEASED (5) /* msg in slave xc_msgbox */ -#define XC_MSG_DONE (6) /* msg in master xc_msgbox */ + +/* + * The default is to not enable collecting counts of IPI information, since + * the updating of shared cachelines could cause excess bus traffic. + */ +uint_t xc_collect_enable = 0; +uint64_t xc_total_cnt = 0; /* total #IPIs sent for cross calls */ +uint64_t xc_multi_cnt = 0; /* # times we piggy backed on another IPI */ /* * We allow for one high priority message at a time to happen in the system. @@ -121,13 +113,6 @@ static volatile ulong_t *xc_priority_set = CPUSET2BV(xc_priority_set_store); static xc_data_t xc_priority_data; /* - * Wrappers to avoid C compiler warnings due to volatile. The atomic bit - * operations don't accept volatile bit vectors - which is a bit silly. - */ -#define XC_BT_SET(vector, b) BT_ATOMIC_SET((ulong_t *)(vector), (b)) -#define XC_BT_CLEAR(vector, b) BT_ATOMIC_CLEAR((ulong_t *)(vector), (b)) - -/* * Decrement a CPU's work count */ static void @@ -193,6 +178,20 @@ xc_extract(xc_msg_t **queue) } /* + * Extract the next message from the CPU's queue, and place the message in + * .xc_curmsg. The latter is solely to make debugging (and ::xcall) more + * useful. + */ +static xc_msg_t * +xc_get(void) +{ + struct machcpu *mcpup = &CPU->cpu_m; + xc_msg_t *msg = xc_extract(&mcpup->xc_msgbox); + mcpup->xc_curmsg = msg; + return (msg); +} + +/* * Initialize the machcpu fields used for cross calls */ static uint_t xc_initialized = 0; @@ -328,8 +327,7 @@ xc_serv(caddr_t arg1, caddr_t arg2) /* * We may have to wait for a message to arrive. */ - for (msg = NULL; msg == NULL; - msg = xc_extract(&mcpup->xc_msgbox)) { + for (msg = NULL; msg == NULL; msg = xc_get()) { /* * Alway check for and handle a priority message. @@ -339,7 +337,7 @@ xc_serv(caddr_t arg1, caddr_t arg2) a1 = xc_priority_data.xc_a1; a2 = xc_priority_data.xc_a2; a3 = xc_priority_data.xc_a3; - XC_BT_CLEAR(xc_priority_set, CPU->cpu_id); + BT_ATOMIC_CLEAR(xc_priority_set, CPU->cpu_id); xc_decrement(mcpup); func(a1, a2, a3); if (mcpup->xc_work_cnt == 0) @@ -443,6 +441,8 @@ xc_serv(caddr_t arg1, caddr_t arg2) panic("bad message 0x%p in msgbox", (void *)msg); break; } + + CPU->cpu_m.xc_curmsg = NULL; } return (rc); } @@ -581,7 +581,7 @@ xc_priority_common( * ahead. */ if (BT_TEST(xc_priority_set, c)) { - XC_BT_CLEAR(xc_priority_set, c); + BT_ATOMIC_CLEAR(xc_priority_set, c); if (cpup->cpu_m.xc_work_cnt > 0) xc_decrement(&cpup->cpu_m); } @@ -607,7 +607,7 @@ xc_priority_common( cpup == CPU) continue; (void) xc_increment(&cpup->cpu_m); - XC_BT_SET(xc_priority_set, c); + BT_ATOMIC_SET(xc_priority_set, c); send_dirint(c, XC_HI_PIL); for (i = 0; i < 10; ++i) { (void) atomic_cas_ptr(&cpup->cpu_m.xc_msgbox, diff --git a/usr/src/uts/i86pc/sys/machcpuvar.h b/usr/src/uts/i86pc/sys/machcpuvar.h index 3eb5ef76f2..f4e38dec98 100644 --- a/usr/src/uts/i86pc/sys/machcpuvar.h +++ b/usr/src/uts/i86pc/sys/machcpuvar.h @@ -152,7 +152,7 @@ typedef struct cpu_smt { * * There are CTASSERTs in os/intr.c that verify this all works out. */ -#define MACHCPU_SIZE (1568 + 688) +#define MACHCPU_SIZE (1568 + 696) #define MACHCPU_PAD (MMU_PAGESIZE - MACHCPU_SIZE) #define MACHCPU_PAD2 (MMU_PAGESIZE - 16 - 3 * sizeof (struct kpti_frame)) @@ -161,6 +161,7 @@ struct machcpu { * x_call fields - used for interprocessor cross calls */ struct xc_msg *xc_msgbox; + struct xc_msg *xc_curmsg; struct xc_msg *xc_free; xc_data_t xc_data; uint32_t xc_wait_cnt; diff --git a/usr/src/uts/i86pc/sys/x_call.h b/usr/src/uts/i86pc/sys/x_call.h index 65b5813b95..c1e55495b0 100644 --- a/usr/src/uts/i86pc/sys/x_call.h +++ b/usr/src/uts/i86pc/sys/x_call.h @@ -22,6 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2018 Joyent, Inc. */ #ifndef _SYS_X_CALL_H @@ -33,6 +34,14 @@ extern "C" { #ifndef _ASM +#define XC_MSG_FREE (0) /* msg in xc_free queue */ +#define XC_MSG_ASYNC (1) /* msg in slave xc_msgbox */ +#define XC_MSG_CALL (2) /* msg in slave xc_msgbox */ +#define XC_MSG_SYNC (3) /* msg in slave xc_msgbox */ +#define XC_MSG_WAITING (4) /* msg in master xc_msgbox or xc_waiters */ +#define XC_MSG_RELEASED (5) /* msg in slave xc_msgbox */ +#define XC_MSG_DONE (6) /* msg in master xc_msgbox */ + typedef uintptr_t xc_arg_t; typedef int (*xc_func_t)(xc_arg_t, xc_arg_t, xc_arg_t); @@ -52,13 +61,8 @@ typedef struct xc_data { */ typedef struct xc_msg { uint8_t xc_command; -#ifdef __amd64 uint16_t xc_master; uint16_t xc_slave; -#else - uint8_t xc_master; - uint8_t xc_slave; -#endif struct xc_msg *xc_next; } xc_msg_t; |