Index: sys/sys/param.h =================================================================== --- sys/sys/param.h +++ sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1200053 /* Master, propagated to newvers */ +#define __FreeBSD_version 1200054 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, @@ -84,6 +84,7 @@ #define P_OSREL_SHUTDOWN_ENOTCONN 1100077 #define P_OSREL_MAP_GUARD 1200035 #define P_OSREL_WRFSBASE 1200041 +#define P_OSREL_VMTOTAL64 1200054 #define P_OSREL_MAJOR(x) ((x) / 100000) #endif Index: sys/sys/vmmeter.h =================================================================== --- sys/sys/vmmeter.h +++ sys/sys/vmmeter.h @@ -46,15 +46,15 @@ int16_t t_pw; /* jobs in page wait */ int16_t t_sl; /* jobs sleeping in core */ int16_t t_sw; /* swapped out runnable/short block jobs */ - int32_t t_vm; /* total virtual memory */ - int32_t t_avm; /* active virtual memory */ - int32_t t_rm; /* total real memory in use */ - int32_t t_arm; /* active real memory */ - int32_t t_vmshr; /* shared virtual memory */ - int32_t t_avmshr; /* active shared virtual memory */ - int32_t t_rmshr; /* shared real memory */ - int32_t t_armshr; /* active shared real memory */ - int32_t t_free; /* free memory pages */ + uint64_t t_vm; /* total virtual memory */ + uint64_t t_avm; /* active virtual memory */ + uint64_t t_rm; /* total real memory in use */ + uint64_t t_arm; /* active real memory */ + uint64_t t_vmshr; /* shared virtual memory */ + uint64_t t_avmshr; /* active shared virtual memory */ + uint64_t t_rmshr; /* shared real memory */ + uint64_t t_armshr; /* active shared real memory */ + uint64_t t_free; /* free memory pages */ }; #if defined(_KERNEL) || defined(_WANT_VMMETER) Index: sys/vm/vm_meter.c =================================================================== --- sys/vm/vm_meter.c +++ sys/vm/vm_meter.c @@ -152,14 +152,42 @@ return (obj->ref_count > obj->shadow_count); } +#if defined(COMPAT_FREEBSD11) +struct vmtotal11 { + int16_t t_rq; + int16_t t_dw; + int16_t t_pw; + int16_t t_sl; + int16_t t_sw; + int32_t t_vm; + int32_t t_avm; + int32_t t_rm; + int32_t t_arm; + int32_t t_vmshr; + int32_t t_avmshr; + int32_t t_rmshr; + int32_t t_armshr; + int32_t t_free; +}; +#endif + static int vmtotal(SYSCTL_HANDLER_ARGS) { struct vmtotal total; +#if defined(COMPAT_FREEBSD11) + struct vmtotal11 total11; +#endif vm_object_t object; struct proc *p; struct thread *td; +#if defined(COMPAT_FREEBSD11) + p = curproc; + if (p->p_osrel < P_OSREL_VMTOTAL64 && req->oldptr == NULL) + return (SYSCTL_OUT(req, NULL, sizeof(total11))); +#endif + bzero(&total, sizeof(total)); /* @@ -253,12 +281,41 @@ } mtx_unlock(&vm_object_list_mtx); total.t_free = vm_cnt.v_free_count; +#if defined(COMPAT_FREEBSD11) + /* sysctl(8) allocates twice as much memory as repoted by sysctl(3) */ + if (req->oldlen == sizeof(total11) || req->oldlen == + (2 * sizeof(total11))) { + bzero(&total11, sizeof(total11)); + + total11.t_rq = total.t_rq; + total11.t_dw = total.t_dw; + total11.t_pw = total.t_pw; + total11.t_sl = total.t_sl; + total11.t_sw = total.t_sw; + total11.t_vm = total.t_vm; /* truncate */ + total11.t_avm = total.t_avm; /* truncate */ + total11.t_rm = total.t_rm; /* truncate */ + total11.t_arm = total.t_arm; /* truncate */ + total11.t_vmshr = total.t_vmshr; /* truncate */ + total11.t_avmshr = total.t_avmshr; /* truncate */ + total11.t_rmshr = total.t_rmshr; /* truncate */ + total11.t_armshr = total.t_armshr; /* truncate */ + total11.t_free = total.t_free; /* truncate */ + + return (SYSCTL_OUT(req, &total11, sizeof(total11))); + } +#endif return (sysctl_handle_opaque(oidp, &total, sizeof(total), req)); } +#if defined(COMPAT_FREEBSD11) +SYSCTL_PROC(_vm, VM_TOTAL, vmtotal, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE, + NULL, 0, vmtotal, "S,vmtotal", "System virtual memory statistics"); +#else SYSCTL_PROC(_vm, VM_TOTAL, vmtotal, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE, 0, sizeof(struct vmtotal), vmtotal, "S,vmtotal", "System virtual memory statistics"); +#endif SYSCTL_NODE(_vm, OID_AUTO, stats, CTLFLAG_RW, 0, "VM meter stats"); static SYSCTL_NODE(_vm_stats, OID_AUTO, sys, CTLFLAG_RW, 0, "VM meter sys stats");