aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_linker.c
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2018-10-20 18:08:43 +0000
committerConrad Meyer <cem@FreeBSD.org>2018-10-20 18:08:43 +0000
commitd158fa4ade3eb6f4b7ac2945f00a733438707adb (patch)
treefc260efb6f0c3cda9f476c5fbd7d251e363e8e07 /sys/kern/kern_linker.c
parent3c36368a1567eb76ba5dfaec26b1fb0c6c7f7fe9 (diff)
downloadsrc-d158fa4ade3eb6f4b7ac2945f00a733438707adb.tar.gz
src-d158fa4ade3eb6f4b7ac2945f00a733438707adb.zip
Add flags variants to linker_files / stack(9) symbol resolution
Some best-effort consumers may find trylock behavior for stack(9) symbol resolution acceptable. Expose that behavior to such consumers. This API is ugly. If in the future the modules and linker file list locking is cleaned up such that the linker_files list can be iterated safely without acquiring a sleepable lock, this API should be removed. However, most of the time nothing will be holding the linker files lock exclusive and the acquisition can proceed. Reviewed by: markj Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D17620
Notes
Notes: svn path=/head/; revision=339463
Diffstat (limited to 'sys/kern/kern_linker.c')
-rw-r--r--sys/kern/kern_linker.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index 0c861783cef8..6dc218860662 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -1021,17 +1021,35 @@ linker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen,
* obey locking protocols, and offer a significantly less complex interface.
*/
int
-linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
- long *offset)
+linker_search_symbol_name_flags(caddr_t value, char *buf, u_int buflen,
+ long *offset, int flags)
{
int error;
- sx_slock(&kld_sx);
+ KASSERT((flags & (M_NOWAIT | M_WAITOK)) != 0 &&
+ (flags & (M_NOWAIT | M_WAITOK)) != (M_NOWAIT | M_WAITOK),
+ ("%s: bad flags: 0x%x", __func__, flags));
+
+ if (flags & M_NOWAIT) {
+ if (!sx_try_slock(&kld_sx))
+ return (EWOULDBLOCK);
+ } else
+ sx_slock(&kld_sx);
+
error = linker_debug_search_symbol_name(value, buf, buflen, offset);
sx_sunlock(&kld_sx);
return (error);
}
+int
+linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
+ long *offset)
+{
+
+ return (linker_search_symbol_name_flags(value, buf, buflen, offset,
+ M_WAITOK));
+}
+
/*
* Syscalls.
*/