diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -2715,6 +2715,11 @@ kve->kve_vn_fileid = key; kve->kve_vn_fsid_freebsd11 = seq; } + if ((lobj->flags & OBJ_POSIXSHM) != 0) { + kve->kve_flags |= KVME_FLAG_POSIXSHM; + shm_get_path(lobj, kve->kve_path, + sizeof(kve->kve_path)); + } if (vp != NULL) { vn_fullpath(vp, &fullpath, &freepath); kve->kve_vn_type = vntype_to_kinfo(vp->v_type); @@ -2734,6 +2739,9 @@ kve->kve_status = KF_ATTR_VALID; } vput(vp); + strlcpy(kve->kve_path, fullpath, sizeof( + kve->kve_path)); + free(freepath, M_TEMP); } } else { kve->kve_type = guard ? KVME_TYPE_GUARD : @@ -2742,10 +2750,6 @@ kve->kve_shadow_count = 0; } - strlcpy(kve->kve_path, fullpath, sizeof(kve->kve_path)); - if (freepath != NULL) - free(freepath, M_TEMP); - /* Pack record size down */ if ((flags & KERN_VMMAP_PACK_KINFO) != 0) kve->kve_structsize = diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c --- a/sys/kern/uipc_shm.c +++ b/sys/kern/uipc_shm.c @@ -945,15 +945,20 @@ shmfd->shm_gid = ucred->cr_gid; shmfd->shm_mode = mode; if (largepage) { - shmfd->shm_object = phys_pager_allocate(NULL, + obj = shmfd->shm_object = phys_pager_allocate(NULL, &shm_largepage_phys_ops, NULL, shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred); + VM_OBJECT_WLOCK(shmfd->shm_object); + obj->un_pager.phys.phys_priv = shmfd; + vm_object_set_flag(obj, OBJ_POSIXSHM); + VM_OBJECT_WUNLOCK(shmfd->shm_object); shmfd->shm_lp_alloc_policy = SHM_LARGEPAGE_ALLOC_DEFAULT; } else { obj = vm_pager_allocate(shmfd_pager_type, NULL, shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred); VM_OBJECT_WLOCK(obj); obj->un_pager.swp.swp_priv = shmfd; + vm_object_set_flag(obj, OBJ_POSIXSHM); VM_OBJECT_WUNLOCK(obj); shmfd->shm_object = obj; } @@ -993,11 +998,12 @@ rangelock_destroy(&shmfd->shm_rl); mtx_destroy(&shmfd->shm_mtx); obj = shmfd->shm_object; - if (!shm_largepage(shmfd)) { - VM_OBJECT_WLOCK(obj); + VM_OBJECT_WLOCK(obj); + if (shm_largepage(shmfd)) + obj->un_pager.phys.phys_priv = NULL; + else obj->un_pager.swp.swp_priv = NULL; - VM_OBJECT_WUNLOCK(obj); - } + VM_OBJECT_WUNLOCK(obj); vm_object_deallocate(obj); free(shmfd, M_SHMFD); } @@ -2202,3 +2208,35 @@ return (kern_shm_open2(td, uap->path, uap->flags, uap->mode, uap->shmflags, NULL, uap->name)); } + +int +shm_get_path(struct vm_object *obj, char *path, size_t sz) +{ + struct shmfd *shmfd; + int error; + + error = 0; + shmfd = NULL; + sx_slock(&shm_dict_lock); + VM_OBJECT_RLOCK(obj); + if ((obj->flags & OBJ_POSIXSHM) == 0) { + error = EINVAL; + } else { + if (obj->type == shmfd_pager_type) + shmfd = obj->un_pager.swp.swp_priv; + else if (obj->type == OBJT_PHYS) + shmfd = obj->un_pager.phys.phys_priv; + if (shmfd == NULL) { + error = ENXIO; + } else { + strlcpy(path, shmfd->shm_path == NULL ? "anon" : + shmfd->shm_path, sz); + } + } + if (error != 0) + path[0] = '\0'; + VM_OBJECT_RUNLOCK(obj); + sx_sunlock(&shm_dict_lock); + return (error); +} + diff --git a/sys/sys/mman.h b/sys/sys/mman.h --- a/sys/sys/mman.h +++ b/sys/sys/mman.h @@ -310,6 +310,7 @@ int shm_dotruncate(struct shmfd *shmfd, off_t length); bool shm_largepage(struct shmfd *shmfd); void shm_remove_prison(struct prison *pr); +int shm_get_path(struct vm_object *obj, char *path, size_t sz); extern struct fileops shm_ops; diff --git a/sys/sys/user.h b/sys/sys/user.h --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -515,6 +515,7 @@ #define KVME_FLAG_GROWS_DOWN 0x00000020 #define KVME_FLAG_USER_WIRED 0x00000040 #define KVME_FLAG_SYSVSHM 0x00000080 +#define KVME_FLAG_POSIXSHM 0x00000100 #if defined(__amd64__) #define KINFO_OVMENTRY_SIZE 1168 @@ -578,6 +579,7 @@ #define kve_obj kve_type_spec._kve_obj #define KVMO_FLAG_SYSVSHM 0x0001 +#define KVMO_FLAG_POSIXSHM 0x0002 /* * The "vm.objects" sysctl provides a list of all VM objects in the system diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -172,6 +172,7 @@ void *data_ptr; uintptr_t data_val; }; + void *phys_priv; } phys; } un_pager; struct ucred *cred; @@ -202,6 +203,7 @@ #define OBJ_PAGERPRIV1 0x00004000 /* Pager private */ #define OBJ_PAGERPRIV2 0x00008000 /* Pager private */ #define OBJ_SYSVSHM 0x00010000 /* SysV SHM */ +#define OBJ_POSIXSHM 0x00020000 /* Posix SHM */ /* * Helpers to perform conversion between vm_object page indexes and offsets. diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -2601,6 +2601,11 @@ kvo->kvo_vn_fileid = key; kvo->kvo_vn_fsid_freebsd11 = seq; } + if ((obj->flags & OBJ_POSIXSHM) != 0) { + kvo->kvo_flags |= KVMO_FLAG_POSIXSHM; + shm_get_path(obj, kvo->kvo_path, + sizeof(kvo->kvo_path)); + } if (vp != NULL) { vn_fullpath(vp, &fullpath, &freepath); vn_lock(vp, LK_SHARED | LK_RETRY); @@ -2611,11 +2616,10 @@ /* truncate */ } vput(vp); + strlcpy(kvo->kvo_path, fullpath, sizeof(kvo->kvo_path)); + free(freepath, M_TEMP); } - strlcpy(kvo->kvo_path, fullpath, sizeof(kvo->kvo_path)); - free(freepath, M_TEMP); - /* Pack record size down */ kvo->kvo_structsize = offsetof(struct kinfo_vmobject, kvo_path) + strlen(kvo->kvo_path) + 1; diff --git a/usr.bin/procstat/procstat_vm.c b/usr.bin/procstat/procstat_vm.c --- a/usr.bin/procstat/procstat_vm.c +++ b/usr.bin/procstat/procstat_vm.c @@ -170,6 +170,8 @@ xo_emit(" {:sysvipc:/sysvshm(%ju:%u)/%ju:%u}", (uintmax_t)kve->kve_vn_fileid, kve->kve_vn_fsid_freebsd11); + if ((kve->kve_flags & KVME_FLAG_POSIXSHM) != 0) + xo_emit(" {:posixshm:/posixshm@/posixshm}"); xo_emit("{:kve_path/%-s/%s}\n", kve->kve_path); xo_close_instance("vm"); } diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -1542,6 +1542,8 @@ if ((kvo->kvo_flags & KVMO_FLAG_SYSVSHM) != 0) xo_emit("{:sysvshm/sysvshm(%ju:%u)} ", (uintmax_t)kvo->kvo_vn_fileid, kvo->kvo_vn_fsid_freebsd11); + if ((kvo->kvo_flags & KVMO_FLAG_POSIXSHM) != 0) + xo_emit("{:posixshm/posixshm@/posixshm}"); xo_emit("{:path/%-s}\n", kvo->kvo_path); xo_close_instance("object"); }