Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131561772
D20390.id58333.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D20390.id58333.diff
View Options
Index: sys/kern/kern_proc.c
===================================================================
--- sys/kern/kern_proc.c
+++ sys/kern/kern_proc.c
@@ -62,6 +62,7 @@
#include <sys/sbuf.h>
#include <sys/sysent.h>
#include <sys/sched.h>
+#include <sys/shm.h>
#include <sys/smp.h>
#include <sys/stack.h>
#include <sys/stat.h>
@@ -2444,6 +2445,27 @@
PA_UNLOCK_COND(locked_pa);
}
+/*
+ * Build the pseudo-path for SysV and POSIX shm, if appropriate.
+ */
+static void
+get_fullpath(char *path, size_t size, vm_object_t object)
+{
+ void *data;
+
+ switch (vm_object_path_info(object, &data)) {
+ case OBJPATH_NONE:
+ case OBJPATH_VNODE:
+ break;
+ case OBJPATH_SHMP:
+ shm_fullpath(path, size, data);
+ break;
+ case OBJPATH_SHMS:
+ sysvshm_fullpath(path, size, data);
+ break;
+ }
+}
+
/*
* Must be called with the process locked and will return unlocked.
*/
@@ -2536,12 +2558,14 @@
last_timestamp = map->timestamp;
vm_map_unlock_read(map);
- freepath = NULL;
- fullpath = "";
+ kve->kve_path[0] = '\0';
if (lobj != NULL) {
kve->kve_type = vm_object_kvme_type(lobj, &vp);
if (vp != NULL)
vref(vp);
+ else get_fullpath(kve->kve_path,
+ sizeof(kve->kve_path),
+ lobj);
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
@@ -2549,6 +2573,8 @@
kve->kve_shadow_count = obj->shadow_count;
VM_OBJECT_RUNLOCK(obj);
if (vp != NULL) {
+ freepath = NULL;
+ fullpath = "";
vn_fullpath(curthread, vp, &fullpath,
&freepath);
kve->kve_vn_type = vntype_to_kinfo(vp->v_type);
@@ -2568,6 +2594,9 @@
kve->kve_status = KF_ATTR_VALID;
}
vput(vp);
+ strlcpy(kve->kve_path, fullpath, sizeof(kve->kve_path));
+ if (freepath != NULL)
+ free(freepath, M_TEMP);
}
} else {
kve->kve_type = KVME_TYPE_NONE;
@@ -2575,10 +2604,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 =
Index: sys/kern/sysv_shm.c
===================================================================
--- sys/kern/sysv_shm.c
+++ sys/kern/sysv_shm.c
@@ -755,6 +755,7 @@
VM_OBJECT_WLOCK(shm_object);
vm_object_clear_flag(shm_object, OBJ_ONEMAPPING);
vm_object_set_flag(shm_object, OBJ_COLORED | OBJ_NOSPLIT);
+ vm_object_set_path_info(shm_object, OBJPATH_SHMS, shmseg);
VM_OBJECT_WUNLOCK(shm_object);
shmseg->object = shm_object;
@@ -779,6 +780,17 @@
return (0);
}
+void
+sysvshm_fullpath(char *path, size_t size, void *data)
+{
+ struct shmid_kernel *shmseg;
+
+ shmseg = (struct shmid_kernel *) data;
+
+ if (shmseg != NULL && shmseg->u.shm_perm.key != IPC_PRIVATE)
+ snprintf(path, size, "%ld", shmseg->u.shm_perm.key);
+}
+
#ifndef _SYS_SYSPROTO_H_
struct shmget_args {
key_t key;
Index: sys/kern/uipc_shm.c
===================================================================
--- sys/kern/uipc_shm.c
+++ sys/kern/uipc_shm.c
@@ -558,6 +558,7 @@
KASSERT(shmfd->shm_object != NULL, ("shm_create: vm_pager_allocate"));
shmfd->shm_object->pg_color = 0;
VM_OBJECT_WLOCK(shmfd->shm_object);
+ vm_object_set_path_info(shmfd->shm_object, OBJPATH_SHMP, shmfd);
vm_object_clear_flag(shmfd->shm_object, OBJ_ONEMAPPING);
vm_object_set_flag(shmfd->shm_object, OBJ_COLORED | OBJ_NOSPLIT);
VM_OBJECT_WUNLOCK(shmfd->shm_object);
@@ -686,6 +687,10 @@
FREAD | FWRITE);
if (error)
return (error);
+ VM_OBJECT_WLOCK(map->sm_shmfd->shm_object);
+ vm_object_set_path_info(map->sm_shmfd->shm_object,
+ OBJPATH_NONE, NULL);
+ VM_OBJECT_WUNLOCK(map->sm_shmfd->shm_object);
map->sm_shmfd->shm_path = NULL;
LIST_REMOVE(map, sm_link);
shm_drop(map->sm_shmfd);
@@ -1095,6 +1100,17 @@
return (0);
}
+void
+shm_fullpath(char *path, size_t size, void *data)
+{
+ struct shmfd *shmfd = (struct shmfd *) data;
+
+ if (shmfd->shm_path == NULL)
+ strlcpy(path, "", size);
+ else
+ strlcpy(path, shmfd->shm_path, size);
+}
+
static int
shm_fill_kinfo_locked(struct shmfd *shmfd, struct kinfo_file *kif, bool list)
{
Index: sys/sys/mman.h
===================================================================
--- sys/sys/mman.h
+++ sys/sys/mman.h
@@ -242,6 +242,7 @@
struct shmfd *shm_hold(struct shmfd *shmfd);
void shm_drop(struct shmfd *shmfd);
int shm_dotruncate(struct shmfd *shmfd, off_t length);
+void shm_fullpath(char *path, size_t size, void *data);
extern struct fileops shm_ops;
#else /* !_KERNEL */
Index: sys/sys/shm.h
===================================================================
--- sys/sys/shm.h
+++ sys/sys/shm.h
@@ -155,6 +155,7 @@
void shmexit(struct vmspace *);
void shmfork(struct proc *, struct proc *);
+void sysvshm_fullpath(char *path, size_t size, void *data);
#else /* !_KERNEL */
Index: sys/vm/vm_object.h
===================================================================
--- sys/vm/vm_object.h
+++ sys/vm/vm_object.h
@@ -168,6 +168,15 @@
void *swp_tmpfs;
struct pctrie swp_blks;
} swp;
+
+ /*
+ * For OBJT_PHYS (no pager), OBJT_DEFAULT and OBJT_SWAP if
+ * not OBJ_TMPFS, we can store a back pointer that can be
+ * used to genenrate a path for procstat.
+ */
+ struct {
+ void *data;
+ } path_info;
} un_pager;
struct ucred *cred;
vm_ooffset_t charge;
@@ -193,6 +202,18 @@
#define OBJ_DISCONNECTWNT 0x4000 /* disconnect from vnode wanted */
#define OBJ_TMPFS 0x8000 /* has tmpfs vnode allocated */
+/*
+ * If the OBJ_TMPFS flag is not set, we overload the OBJ_TMPS_DIRTY flag to
+ * select between SysV and POSIX shm path_info.
+ */
+#define OBJ_SYSV_SHM OBJ_TMPFS_DIRTY
+
+/* Values returned by vm_object_path_info. */
+#define OBJPATH_NONE 0x0 /* no path info available */
+#define OBJPATH_VNODE 0x1 /* use vn_fullpath on vnode */
+#define OBJPATH_SHMS 0x2 /* use sysvshm_fullpath */
+#define OBJPATH_SHMP 0x3 /* use shm_fullpath */
+
/*
* Helpers to perform conversion between vm_object page indexes and offsets.
* IDX_TO_OFF() converts an index into an offset.
@@ -324,6 +345,9 @@
void vm_object_set_writeable_dirty (vm_object_t);
void vm_object_init (void);
int vm_object_kvme_type(vm_object_t object, struct vnode **vpp);
+int vm_object_path_info(vm_object_t object, void **data);
+void vm_object_set_path_info(vm_object_t object, int path_info_type,
+ void *data);
void vm_object_madvise(vm_object_t, vm_pindex_t, vm_pindex_t, int);
boolean_t vm_object_page_clean(vm_object_t object, vm_ooffset_t start,
vm_ooffset_t end, int flags);
Index: sys/vm/vm_object.c
===================================================================
--- sys/vm/vm_object.c
+++ sys/vm/vm_object.c
@@ -256,6 +256,7 @@
case OBJT_DEFAULT:
case OBJT_SWAP:
object->flags = OBJ_ONEMAPPING;
+ object->un_pager.path_info.data = NULL;
break;
case OBJT_DEVICE:
case OBJT_SG:
@@ -266,6 +267,7 @@
break;
case OBJT_PHYS:
object->flags = OBJ_UNMANAGED;
+ object->un_pager.path_info.data = NULL;
break;
case OBJT_VNODE:
object->flags = 0;
@@ -2343,6 +2345,54 @@
}
}
+/*
+ * Return the type of the path info pointer. If data is not NULL,
+ * set it to the path info pointer or NULL. The return value
+ * indicates which function can be used to convert the path info
+ * pointer to a path.
+ */
+int
+vm_object_path_info(vm_object_t object, void **data)
+{
+ VM_OBJECT_ASSERT_LOCKED(object);
+ if (data != NULL)
+ *data = object->un_pager.path_info.data;
+ if (object->type != OBJT_DEFAULT &&
+ object->type != OBJT_SWAP &&
+ object->type != OBJT_PHYS)
+ return (OBJPATH_NONE);
+ if (object->un_pager.path_info.data == NULL)
+ return (OBJPATH_NONE);
+ if ((object->flags & OBJ_TMPFS) != 0)
+ return (OBJPATH_NONE);
+ if ((object->flags & OBJ_SYSV_SHM) != 0)
+ return (OBJPATH_SHMS);
+ else
+ return (OBJPATH_SHMP);
+}
+
+void
+vm_object_set_path_info(vm_object_t object, int path_info_type,
+ void *data)
+{
+ VM_OBJECT_ASSERT_LOCKED(object);
+ KASSERT(object->type == OBJT_DEFAULT ||
+ object->type == OBJT_SWAP ||
+ object->type == OBJT_PHYS,
+ ("cannot set path info for object type %d", object->type));
+ KASSERT((object->flags & OBJ_TMPFS) == 0,
+ ("cannot set path info for tmpfs object"));
+ KASSERT(path_info_type == OBJPATH_SHMS ||
+ path_info_type == OBJPATH_SHMP ||
+ path_info_type == OBJPATH_NONE,
+ ("unknown path info type"));
+ object->un_pager.path_info.data = data;
+ if (path_info_type == OBJPATH_SHMS)
+ vm_object_set_flag(object, OBJ_SYSV_SHM);
+ else
+ vm_object_clear_flag(object, OBJ_SYSV_SHM);
+}
+
static int
sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 10, 6:58 AM (21 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23518954
Default Alt Text
D20390.id58333.diff (8 KB)
Attached To
Mode
D20390: Show shm_open() and shmget() path/key in procstat -v.
Attached
Detach File
Event Timeline
Log In to Comment