* Implemented a (private for now) get_system_info_etc() call, that can retrieve

various system information.
* Implemented retrieving some VM stats via this call.
* The VM now maintains a page fault counter, and sets system_info::page_faults
  accordingly.
* Added a (pretty simple) "vmstat" command line app.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27597 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-09-17 16:27:17 +00:00
parent b0a63e7a2a
commit ca7cb625b9
16 changed files with 282 additions and 48 deletions

View File

@ -50,7 +50,7 @@ BEOS_BIN = "[" addattr alert arp base64 basename bc beep bootman bzip2 cal cat
traceroute translate true tsort tty
uname unchop unexpand unmount uniq unrar unshar unzip unzipsfx <bin>updatedb
uptime urlwrapper usb_dev_info useradd uudecode uuencode
vdir version vim waitfor wc wget whoami xargs xres yes
vdir version vim vmstat waitfor wc wget whoami xargs xres yes
zdiff zforce zgrep zip zipcloak <bin>zipgrep zipnote zipsplit zmore znew
;
@ -138,7 +138,7 @@ BEOS_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com etherpci $(X86_ONLY)ipro1000
;
#BEOS_ADD_ONS_DRIVERS_ACPI = $(X86_ONLY)acpi_button ;
BEOS_ADD_ONS_BUS_MANAGERS = pci $(X86_ONLY)ps2 $(X86_ONLY)isa ide scsi
config_manager agp_gart usb firewire
config_manager agp_gart usb firewire #acpi
;
BEOS_ADD_ONS_FILE_SYSTEMS = bfs cdda ext2 fat iso9660 $(GPL_ONLY)reiserfs ;
#googlefs nfs $(GPL_ONLY)ntfs ;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_SYSTEM_INFO_H
@ -16,12 +16,14 @@ extern "C" {
#endif
extern status_t system_info_init(struct kernel_args *args);
extern uint32 get_haiku_revision(void);
extern uint32 get_haiku_revision(void);
extern status_t _user_get_system_info(system_info *userInfo, size_t size);
extern status_t _user_get_system_info_etc(int32 id, void *buffer,
size_t bufferSize);
#ifdef __cplusplus
}
#endif
#endif /* _KRENEL_SYSTEM_INFO_H */
#endif /* _KERNEL_SYSTEM_INFO_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
@ -16,6 +16,7 @@
struct kernel_args;
struct team;
struct system_memory_info;
struct vm_page;
struct VMCache;
struct vm_area;
@ -93,6 +94,8 @@ status_t vm_map_page(struct vm_area *area, struct vm_page *page, addr_t address,
status_t vm_get_physical_page(addr_t paddr, addr_t *vaddr, uint32 flags);
status_t vm_put_physical_page(addr_t vaddr);
void vm_get_info(struct system_memory_info *info);
uint32 vm_num_page_faults(void);
off_t vm_available_memory(void);
off_t vm_available_not_needed_memory(void);

View File

@ -406,6 +406,8 @@ extern int64 _kern_atomic_get64(vint64 *value);
/* System informations */
extern status_t _kern_get_system_info(system_info *info, size_t size);
extern status_t _kern_get_system_info_etc(int32 id, void *buffer,
size_t bufferSize);
extern status_t _kern_analyze_scheduling(bigtime_t from, bigtime_t until,
void* buffer, size_t size,
struct scheduling_analysis* analysis);

View File

@ -0,0 +1,37 @@
/*
* Copyright 2008 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _SYSTEM_INFO_H
#define _SYSTEM_INFO_H
#include <OS.h>
#define B_MEMORY_INFO 'memo'
struct system_memory_info {
uint64 max_memory;
uint64 free_memory;
uint64 needed_memory;
uint64 max_swap_space;
uint64 free_swap_space;
uint64 block_cache_memory;
uint32 page_faults;
// TODO: add active/inactive page counts, swap in/out, ...
};
#ifdef __cplusplus
extern "C" {
#endif
extern status_t get_system_info_etc(int32 id, void *buffer, size_t bufferSize);
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_INFO_H */

View File

@ -2,10 +2,7 @@ SubDir HAIKU_TOP src bin ;
SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders app ;
UsePrivateHeaders shared ;
UsePrivateHeaders storage ;
UseLibraryHeaders usb ;
UsePrivateHeaders app shared storage usb ;
UsePrivateSystemHeaders ;
SubDirHdrs $(HAIKU_TOP) src add-ons kernel file_cache ;
@ -46,6 +43,7 @@ StdBinCommands
sysinfo.c
unchop.c
uptime.cpp
vmstat.cpp
waitfor.c
# whoami.c
: : $(haiku-utils_rsrc) ;

109
src/bin/vmstat.cpp Normal file
View File

@ -0,0 +1,109 @@
/*
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <system_info.h>
static struct option const kLongOptions[] = {
{"periodic", no_argument, 0, 'p'},
{"rate", required_argument, 0, 'r'},
{"help", no_argument, 0, 'h'},
{NULL}
};
extern const char *__progname;
static const char *kProgramName = __progname;
void
usage(int status)
{
fprintf(stderr, "usage: %s [-p] [-r <time>]\n"
" -p,--periodic\tDumps changes periodically every second.\n",
" -r,--rate\tDumps changes periodically every <time> milli seconds.\n",
kProgramName);
exit(status);
}
int
main(int argc, char** argv)
{
bool periodically = false;
bigtime_t rate = 1000000LL;
int c;
while ((c = getopt_long(argc, argv, "pr:h", kLongOptions, NULL)) != -1) {
switch (c) {
case 0:
break;
case 'p':
periodically = true;
break;
case 'r':
rate = atoi(optarg) * 1000LL;
if (rate <= 0) {
fprintf(stderr, "%s: Invalid rate: %s\n",
kProgramName, optarg);
return 1;
}
periodically = true;
break;
case 'h':
usage(0);
break;
default:
usage(1);
break;
}
}
system_memory_info info;
status_t status = get_system_info_etc(B_MEMORY_INFO, &info,
sizeof(system_memory_info));
if (status != B_OK) {
fprintf(stderr, "%s: cannot get system info: %s\n", kProgramName,
strerror(status));
return 1;
}
printf("max memory:\t\t%Lu\n", info.max_memory);
printf("free memory:\t\t%Lu\n", info.free_memory);
printf("needed memory:\t\t%Lu\n", info.needed_memory);
printf("block cache memory:\t%Lu\n", info.block_cache_memory);
printf("max swap space:\t\t%Lu\n", info.max_swap_space);
printf("free swap space:\t%Lu\n", info.free_swap_space);
printf("page faults:\t\t%lu\n", info.page_faults);
if (periodically) {
puts("\npage faults used memory used swap block cache");
system_memory_info lastInfo = info;
while (true) {
snooze(rate);
get_system_info_etc(B_MEMORY_INFO, &info,
sizeof(system_memory_info));
printf("%11ld %11Ld %11Ld %11Ld\n",
(int32)info.page_faults - lastInfo.page_faults,
(info.max_memory - info.free_memory)
- (lastInfo.max_memory - lastInfo.free_memory),
(info.max_swap_space - info.free_swap_space)
- (lastInfo.max_swap_space - lastInfo.free_swap_space),
info.block_cache_memory - lastInfo.block_cache_memory);
lastInfo = info;
}
}
return 0;
}

View File

@ -16,8 +16,8 @@
#include <frame_buffer_console.h>
#include <int.h>
#include <kernel.h>
#include <ksystem_info.h>
#include <smp.h>
#include <system_info.h>
#include <thread.h>
#include <tracing.h>
#include <vm.h>

View File

@ -33,6 +33,7 @@
#include <kmodule.h>
#include <kscheduler.h>
#include <ksyscalls.h>
#include <ksystem_info.h>
#include <lock.h>
#include <low_resource_manager.h>
#include <messaging.h>
@ -44,7 +45,6 @@
#include <real_time_clock.h>
#include <sem.h>
#include <smp.h>
#include <system_info.h>
#include <team.h>
#include <timer.h>
#include <user_debugger.h>

View File

@ -4,45 +4,45 @@
* Distributed under the terms of the MIT License.
*/
/* Big case statement for dispatching syscalls */
/*! Big case statement for dispatching syscalls */
#include <kernel.h>
#include <ksyscalls.h>
#include <syscalls.h>
#include <generic_syscall.h>
#include <stdlib.h>
#include <string.h>
#include <arch_config.h>
#include <arch/system_info.h>
#include <cpu.h>
#include <debug.h>
#include <int.h>
#include <disk_device_manager/ddm_userland_interface.h>
#include <elf.h>
#include <vfs.h>
#include <vm.h>
#include <thread.h>
#include <frame_buffer_console.h>
#include <fs/fd.h>
#include <fs/node_monitor.h>
#include <generic_syscall.h>
#include <int.h>
#include <kernel.h>
#include <kimage.h>
#include <ksignal.h>
#include <ksyscalls.h>
#include <ksystem_info.h>
#include <messaging.h>
#include <port.h>
#include <posix/realtime_sem.h>
#include <posix/xsi_message_queue.h>
#include <posix/xsi_semaphore.h>
#include <sem.h>
#include <port.h>
#include <cpu.h>
#include <arch_config.h>
#include <disk_device_manager/ddm_userland_interface.h>
#include <sys/resource.h>
#include <fs/fd.h>
#include <fs/node_monitor.h>
#include <kimage.h>
#include <ksignal.h>
#include <real_time_clock.h>
#include <safemode.h>
#include <system_info.h>
#include <sem.h>
#include <sys/resource.h>
#include <syscalls.h>
#include <thread.h>
#include <tracing.h>
#include <user_atomic.h>
#include <arch/system_info.h>
#include <messaging.h>
#include <frame_buffer_console.h>
#include <usergroup.h>
#include <vfs.h>
#include <vm.h>
#include <wait_for_objects.h>
#include <malloc.h>
#include <string.h>
#include "syscall_numbers.h"

View File

@ -8,6 +8,7 @@
*/
#include <ksystem_info.h>
#include <system_info.h>
#include <arch/system_info.h>
@ -16,6 +17,7 @@
#include <OS.h>
#include <KernelExport.h>
#include <block_cache.h>
#include <cpu.h>
#include <debug.h>
#include <kernel.h>
@ -137,3 +139,29 @@ _user_get_system_info(system_info *userInfo, size_t size)
return status;
}
status_t
_user_get_system_info_etc(int32 id, void* userInfo, size_t size)
{
if (userInfo == NULL || !IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
switch (id) {
case B_MEMORY_INFO:
{
if (size < sizeof(system_memory_info))
return B_BAD_VALUE;
system_memory_info info;
vm_get_info(&info);
info.block_cache_memory = block_cache_used_memory();
return user_memcpy(userInfo, &info, sizeof(system_memory_info));
}
default:
return B_BAD_VALUE;
}
}

View File

@ -27,6 +27,7 @@
#include <kernel_daemon.h>
#include <slab/Slab.h>
#include <syscalls.h>
#include <system_info.h>
#include <tracing.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
@ -1248,3 +1249,16 @@ swap_total_swap_pages()
}
#endif // ENABLE_SWAP_SUPPORT
void
swap_get_info(struct system_memory_info *info)
{
#if ENABLE_SWAP_SUPPORT
info->max_swap_space = swap_total_swap_pages() * B_PAGE_SIZE;
info->free_swap_space = swap_available_pages() * B_PAGE_SIZE;
#else
info->max_swap_space = 0;
info->free_swap_space = 0;
#endif
}

View File

@ -16,6 +16,8 @@
typedef page_num_t swap_addr_t;
struct swap_block;
struct system_memory_info;
extern "C" {
void swap_init(void);
@ -23,6 +25,7 @@ extern "C" {
bool swap_free_page_swap_space(vm_page *page);
uint32 swap_available_pages(void);
uint32 swap_total_swap_pages(void);
void swap_get_info(struct system_memory_info *info);
}

View File

@ -34,6 +34,7 @@
#include <lock.h>
#include <low_resource_manager.h>
#include <smp.h>
#include <system_info.h>
#include <thread.h>
#include <team.h>
#include <util/AutoLock.h>
@ -43,6 +44,8 @@
#include <vm_page.h>
#include <vm_priv.h>
#include "VMAnonymousCache.h"
//#define TRACE_VM
//#define TRACE_FAULTS
@ -194,6 +197,7 @@ static mutex sAreaCacheLock = MUTEX_INITIALIZER("area->cache");
static off_t sAvailableMemory;
static off_t sNeededMemory;
static mutex sAvailableMemoryLock = MUTEX_INITIALIZER("available memory lock");
static uint32 sPageFaults;
#if DEBUG_CACHE_LIST
@ -4158,15 +4162,15 @@ status_t
vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser,
addr_t *newIP)
{
FTRACE(("vm_page_fault: page fault at 0x%lx, ip 0x%lx\n", address, faultAddress));
*newIP = 0;
FTRACE(("vm_page_fault: page fault at 0x%lx, ip 0x%lx\n", address,
faultAddress));
addr_t pageAddress = ROUNDOWN(address, B_PAGE_SIZE);
vm_address_space *addressSpace = NULL;
status_t status = B_OK;
vm_address_space *addressSpace;
*newIP = 0;
atomic_add((int32*)&sPageFaults, 1);
if (IS_KERNEL_ADDRESS(pageAddress)) {
addressSpace = vm_get_kernel_address_space();
@ -4850,6 +4854,27 @@ vm_get_physical_page(addr_t paddr, addr_t *_vaddr, uint32 flags)
}
void
vm_get_info(system_memory_info* info)
{
swap_get_info(info);
info->max_memory = vm_page_num_pages() * B_PAGE_SIZE;
info->page_faults = sPageFaults;
MutexLocker locker(sAvailableMemoryLock);
info->free_memory = sAvailableMemory;
info->needed_memory = sNeededMemory;
}
uint32
vm_num_page_faults(void)
{
return sPageFaults;
}
off_t
vm_available_memory(void)
{

View File

@ -2122,6 +2122,7 @@ vm_page_get_stats(system_info *info)
info->used_pages = gMappedPagesCount - blockCachePages;
info->cached_pages = sNumPages >= free + info->used_pages
? sNumPages - free - info->used_pages : 0;
info->page_faults = vm_num_page_faults();
// TODO: We don't consider pages used for page directories/tables yet.
}

View File

@ -1,11 +1,13 @@
/*
** Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
/*
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include <OS.h>
#include "syscalls.h"
#include <syscalls.h>
#include <system_info.h>
status_t
@ -18,6 +20,16 @@ _get_system_info(system_info *info, size_t size)
}
status_t
get_system_info_etc(int32 id, void *info, size_t size)
{
if (info == NULL || size == 0 || id < 0)
return B_BAD_VALUE;
return _kern_get_system_info_etc(id, info, size);
}
int32
is_computer_on(void)
{