diff options
author | jhb <jhb@FreeBSD.org> | 2013-08-16 21:13:55 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2013-08-16 21:13:55 +0000 |
commit | 3bfcb89de4b7ac6c54e2affe99eccd1482eb4327 (patch) | |
tree | 7565121f7abca9570dd1e0d308a2dd838e3c735b /usr.bin | |
parent | efcf22ed8cf8c3e8d2e5fa37ae4c4a9935a3d597 (diff) | |
download | FreeBSD-src-3bfcb89de4b7ac6c54e2affe99eccd1482eb4327.zip FreeBSD-src-3bfcb89de4b7ac6c54e2affe99eccd1482eb4327.tar.gz |
Add new mmap(2) flags to permit applications to request specific virtual
address alignment of mappings.
- MAP_ALIGNED(n) requests a mapping aligned on a boundary of (1 << n).
Requests for n >= number of bits in a pointer or less than the size of
a page fail with EINVAL. This matches the API provided by NetBSD.
- MAP_ALIGNED_SUPER is a special case of MAP_ALIGNED. It can be used
to optimize the chances of using large pages. By default it will align
the mapping on a large page boundary (the system is free to choose any
large page size to align to that seems best for the mapping request).
However, if the object being mapped is already using large pages, then
it will align the virtual mapping to match the existing large pages in
the object instead.
- Internally, VMFS_ALIGNED_SPACE is now renamed to VMFS_SUPER_SPACE, and
VMFS_ALIGNED_SPACE(n) is repurposed for specifying a specific alignment.
MAP_ALIGNED(n) maps to using VMFS_ALIGNED_SPACE(n), while
MAP_ALIGNED_SUPER maps to VMFS_SUPER_SPACE.
- mmap() of a device object now uses VMFS_OPTIMAL_SPACE rather than
explicitly using VMFS_SUPER_SPACE. All device objects are forced to
use a specific color on creation, so VMFS_OPTIMAL_SPACE is effectively
equivalent.
Reviewed by: alc
MFC after: 1 month
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/kdump/mksubr | 35 | ||||
-rw-r--r-- | usr.bin/truss/syscalls.c | 38 |
2 files changed, 69 insertions, 4 deletions
diff --git a/usr.bin/kdump/mksubr b/usr.bin/kdump/mksubr index bb70d13..5c82f30 100644 --- a/usr.bin/kdump/mksubr +++ b/usr.bin/kdump/mksubr @@ -385,7 +385,6 @@ auto_switch_type "lio_listioname" "LIO_(NO)?WAIT[[:space:]]+[0-9]+" auto_switch_type "madvisebehavname" "_?MADV_[A-Z]+[[:space:]]+[0-9]+" "sys/mman.h" auto_switch_type "minheritname" "INHERIT_[A-Z]+[[:space:]]+[0-9]+" "sys/mman.h" auto_or_type "mlockallname" "MCL_[A-Z]+[[:space:]]+0x[0-9]+" "sys/mman.h" -auto_or_type "mmapflagsname" "MAP_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/mman.h" auto_or_type "mmapprotname" "PROT_[A-Z]+[[:space:]]+0x[0-9A-Fa-f]+" "sys/mman.h" auto_or_type "modename" "S_[A-Z]+[[:space:]]+[0-6]{7}" "sys/stat.h" auto_or_type "mountflagsname" "MNT_[A-Z]+[[:space:]]+0x[0-9]+" "sys/mount.h" @@ -469,6 +468,40 @@ cat <<_EOF_ /* * AUTO - Special * + * The MAP_ALIGNED flag requires special handling. + */ +void +mmapflagsname(int flags) +{ + int align; + int or = 0; + printf("%#x<", flags); +_EOF_ +egrep "^#[[:space:]]*define[[:space:]]+MAP_[A-Z_]+[[:space:]]+0x[0-9A-Fa-f]+[[:space:]]*" \ + $include_dir/sys/mman.h | grep -v MAP_ALIGNED | \ + awk '{ for (i = 1; i <= NF; i++) \ + if ($i ~ /define/) \ + break; \ + ++i; \ + printf "\tif (!((flags > 0) ^ ((%s) > 0)))\n\t\tif_print_or(flags, %s, or);\n", $i, $i }' +cat <<_EOF_ + align = flags & MAP_ALIGNMENT_MASK; + if (align != 0) { + if (align == MAP_ALIGNED_SUPER) + print_or("MAP_ALIGNED_SUPER", or); + else { + print_or("MAP_ALIGNED", or); + printf("(%d)", align >> MAP_ALIGNMENT_SHIFT); + } + } + printf(">"); + if (or == 0) + printf("<invalid>%d", flags); +} + +/* + * AUTO - Special + * * The only reason this is not fully automated is due to the * grep -v RTP_PRIO statement. A better egrep line should * make this capable of being a auto_switch_type() function. diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 6668d7c..af4ed5e 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -296,7 +296,7 @@ static struct xlat mmap_flags[] = { X(MAP_SHARED) X(MAP_PRIVATE) X(MAP_FIXED) X(MAP_RENAME) X(MAP_NORESERVE) X(MAP_RESERVED0080) X(MAP_RESERVED0100) X(MAP_HASSEMAPHORE) X(MAP_STACK) X(MAP_NOSYNC) X(MAP_ANON) - X(MAP_NOCORE) XEND + X(MAP_NOCORE) X(MAP_PREFAULT_READ) XEND }; static struct xlat mprot_flags[] = { @@ -893,9 +893,41 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, case Mprot: tmp = strdup(xlookup_bits(mprot_flags, args[sc->offset])); break; - case Mmapflags: - tmp = strdup(xlookup_bits(mmap_flags, args[sc->offset])); + case Mmapflags: { + const char *base, *alignstr; + int align, flags; + + /* + * MAP_ALIGNED can't be handled by xlookup_bits(), so + * generate that string manually and prepend it to the + * string from xlookup_bits(). Have to be careful to + * avoid outputting MAP_ALIGNED|0 if MAP_ALIGNED is + * the only flag. + */ + flags = args[sc->offset] & ~MAP_ALIGNMENT_MASK; + align = args[sc->offset] & MAP_ALIGNMENT_MASK; + if (align != 0) { + if (align == MAP_ALIGNED_SUPER) + alignstr = strdup("MAP_ALIGNED_SUPER"); + else + asprintf(&alignstr, "MAP_ALIGNED(%d)", + align >> MAP_ALIGNMENT_SHIFT); + if (flags == 0) { + tmp = alignstr; + break; + } + } else + alignstr = NULL; + base = strdup(xlookup_bits(mmap_flags, flags)); + if (alignstr == NULL) { + tmp = base; + break; + } + asprintf(&tmp, "%s|%s", alignstr, base); + free(alignstr); + free(base); break; + } case Whence: tmp = strdup(xlookup(whence_arg, args[sc->offset])); break; |