Em 10/07/2017 06:49, Konstantin Belousov escreveu:
On Mon, Jul 10, 2017 at 06:45:28PM +0900, Tomoaki AOKI wrote:
Hm, for example, sysutils/lsof (userspace app) depends on kernel
source, and I thought the one Otacilio mentioned is something like it.
lsof purpose is to dig into a kernel memory to gather information about
the process state and opened files.  To do this, lsof authors have to use
internal kernel data structures.

The library which is discussed in the thread uses public interfaces,
but then tries to pack the returned data into internal kernel structure.
If this is true, then the breakage is on the library side.


This following simple program behaves in the same manner that xosview. It shows corrects answers for pages_in and pages_out on FreeBSD 11 amd64 and FreeBSD10.3 i386. On FreeBSD 12 r320730 it shows the error answer that I related previously. If the lines

pageinfo[0] = (uint64_t)vm.v_vnodepgsin + (uint64_t)vm.v_swappgsin;
pageinfo[1] = (uint64_t)vm.v_vnodepgsout + (uint64_t)vm.v_swappgsout;

are patched to

pageinfo[0] = (uint32_t)((uint64_t)vm.v_vnodepgsin + (uint64_t)vm.v_swappgsin); pageinfo[1] = (uint32_t)((uint64_t)vm.v_vnodepgsout + (uint64_t)vm.v_swappgsout);

The program works on all FreeBSD version. My doubt is why now this type cast (uint32_t) is necessary?



#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>


#include <sys/vmmeter.h>

/* meminfo[5]  = { active, inactive, wired, cached, free } */
/* pageinfo[2] = { pages_in, pages_out }                   */
void BSDGetPageStats(uint64_t *meminfo, uint64_t *pageinfo) {
    struct vmmeter vm;
    size_t size = sizeof(unsigned int);
#define GET_VM_STATS(name) sysctlbyname("vm.stats.vm." #name, &vm.name, &size, NULL, 0)

    if (meminfo) {
        meminfo[0] = (uint64_t)vm.v_active_count * vm.v_page_size;
        meminfo[1] = (uint64_t)vm.v_inactive_count * vm.v_page_size;
        meminfo[2] = (uint64_t)vm.v_wire_count * vm.v_page_size;
        meminfo[4] = (uint64_t)vm.v_free_count * vm.v_page_size;
    if (pageinfo) {
        pageinfo[0] = (uint64_t)vm.v_vnodepgsin + (uint64_t)vm.v_swappgsin;
pageinfo[1] = (uint64_t)vm.v_vnodepgsout + (uint64_t)vm.v_swappgsout;

int main(int argc, char **argv){
    uint64_t meminfo[5];
    uint64_t pageinfo[2];

    BSDGetPageStats(meminfo, pageinfo);

    printf("active memory     = %lu bytes\n", meminfo[0]);
    printf("inactive memory = %lu bytes\n", meminfo[1]);
    printf("wired memory     = %lu bytes\n", meminfo[2]);
    printf("cached memory     = %lu bytes\n", meminfo[3]);
    printf("free memory     = %lu bytes\n", meminfo[4]);

    printf("\npages_in    = %lu bytes\n", pageinfo[0]);
    printf("pages_out    = %lu bytes\n", pageinfo[1]);
    return 0;

freebsd-current@freebsd.org mailing list
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to