Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Procfs enhancements #1066

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions fs/lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,14 @@ int fcntl_setlk(struct fd *fd, struct flock_ *flock, bool blocking) {
int err = file_lock_from_flock(fd, flock, &request);
if (err < 0)
goto out;
while ((err = file_lock_acquire(inode, &request)) == _EAGAIN) {
if (!blocking)
break;
err = wait_for(&inode->posix_unlock, &inode->lock, NULL);
if (err < 0)
break;
TASK_MAY_BLOCK {
while ((err = file_lock_acquire(inode, &request)) == _EAGAIN) {
if (!blocking)
break;
err = wait_for(&inode->posix_unlock, &inode->lock, NULL);
if (err < 0)
break;
}
}
out:
unlock(&inode->lock);
Expand Down
25 changes: 21 additions & 4 deletions fs/proc/pid.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ static int proc_pid_stat_show(struct proc_entry *entry, struct proc_data *buf) {
lock(&task->group->lock);
lock(&task->sighand->lock);

// program reads this using read-like syscall, so we are in blocking area,
// which means its io_block is set to true. When a proc reads an
// information about itself, but it shouldn't be marked as blocked.
char proc_state = (task->zombie ? 'Z' :
task->group->stopped ? 'T' :
task->io_block && task->pid != current->pid ? 'S' :
'R');

proc_printf(buf, "%d ", task->pid);
proc_printf(buf, "(%.16s) ", task->comm);
proc_printf(buf, "%c ",
task->zombie ? 'Z' :
task->group->stopped ? 'T' :
'R'); // I have no visibility into sleep state at the moment
proc_printf(buf, "%c ", proc_state);
proc_printf(buf, "%d ", task->parent ? task->parent->pid : 0);
proc_printf(buf, "%d ", task->group->pgid);
proc_printf(buf, "%d ", task->group->sid);
Expand Down Expand Up @@ -103,6 +108,17 @@ static int proc_pid_stat_show(struct proc_entry *entry, struct proc_data *buf) {
return 0;
}

static int proc_pid_statm_show(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
proc_printf(buf, "%lu ", 0l); // size
proc_printf(buf, "%lu ", 0l); // resident
proc_printf(buf, "%lu ", 0l); // shared
proc_printf(buf, "%lu ", 0l); // text
proc_printf(buf, "%lu ", 0l); // lib (unused since Linux 2.6)
proc_printf(buf, "%lu ", 0l); // data
proc_printf(buf, "%lu\n", 0l); // dt (unused since Linux 2.6)
return 0;
}

static int proc_pid_auxv_show(struct proc_entry *entry, struct proc_data *buf) {
struct task *task = proc_get_task(entry);
if (task == NULL)
Expand Down Expand Up @@ -257,6 +273,7 @@ struct proc_dir_entry proc_pid_entries[] = {
{"fd", S_IFDIR, .readdir = proc_pid_fd_readdir},
{"maps", .show = proc_pid_maps_show},
{"stat", .show = proc_pid_stat_show},
{"statm", .show = proc_pid_statm_show},
};

struct proc_dir_entry proc_pid = {NULL, S_IFDIR,
Expand Down
44 changes: 42 additions & 2 deletions fs/proc/root.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include <sys/param.h> // for MIN and MAX
#include <sys/stat.h>
#include <inttypes.h>
#include <string.h>
#include "kernel/calls.h"
#include "kernel/task.h"
#include "fs/proc.h"
#include "platform/platform.h"

Expand All @@ -13,8 +15,30 @@ static int proc_show_version(struct proc_entry *UNUSED(entry), struct proc_data
}

static int proc_show_stat(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
struct cpu_usage usage = get_cpu_usage();
proc_printf(buf, "cpu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64"\n", usage.user_ticks, usage.nice_ticks, usage.system_ticks, usage.idle_ticks);
int ncpus = get_cpu_count();
struct cpu_usage total_usage = get_total_cpu_usage();
struct cpu_usage* per_cpu_usage = 0;
struct uptime_info uptime_info = get_uptime();
unsigned uptime = uptime_info.uptime_ticks;

proc_printf(buf, "cpu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" 0 0 0 0\n", total_usage.user_ticks, total_usage.nice_ticks, total_usage.system_ticks, total_usage.idle_ticks);

int err = get_per_cpu_usage(&per_cpu_usage);
if (!err) {
for (int i = 0; i < ncpus; i++) {
proc_printf(buf, "cpu%d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" 0 0 0 0\n", i, per_cpu_usage[i].user_ticks, per_cpu_usage[i].nice_ticks, per_cpu_usage[i].system_ticks, per_cpu_usage[i].idle_ticks);
}
free(per_cpu_usage);
}

int blocked_task_count = get_count_of_blocked_tasks();
int alive_task_count = get_count_of_alive_tasks();
proc_printf(buf, "ctxt 0\n");
proc_printf(buf, "btime %u\n", uptime);
proc_printf(buf, "processes %d\n", alive_task_count);
proc_printf(buf, "procs_running %d\n", alive_task_count - blocked_task_count);
proc_printf(buf, "procs_blocked %d\n", blocked_task_count);

return 0;
}

Expand Down Expand Up @@ -48,6 +72,21 @@ static int proc_show_uptime(struct proc_entry *UNUSED(entry), struct proc_data *
return 0;
}

static int proc_show_loadavg(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
struct uptime_info uptime = get_uptime();
struct pid *last_pid = pid_get_last_allocated();
int last_pid_id = last_pid ? last_pid->id : 0;
double load_1m = uptime.load_1m / 65536.0;
double load_5m = uptime.load_5m / 65536.0;
double load_15m = uptime.load_15m / 65536.0;
int blocked_task_count = get_count_of_blocked_tasks();
int alive_task_count = get_count_of_alive_tasks();
// running_task_count is calculated approximetly, since we don't know the real number of currently running tasks.
int running_task_count = MIN(get_cpu_count(), (int)(alive_task_count - blocked_task_count));
proc_printf(buf, "%.2f %.2f %.2f %u/%u %u\n", load_1m, load_5m, load_15m, running_task_count, alive_task_count, last_pid_id);
return 0;
}

static int proc_readlink_self(struct proc_entry *UNUSED(entry), char *buf) {
sprintf(buf, "%d/", current->pid);
return 0;
Expand Down Expand Up @@ -97,6 +136,7 @@ static int proc_show_mounts(struct proc_entry *UNUSED(entry), struct proc_data *

// in alphabetical order
struct proc_dir_entry proc_root_entries[] = {
{"loadavg", .show = proc_show_loadavg},
{"meminfo", .show = proc_show_meminfo},
{"mounts", .show = proc_show_mounts},
{"self", S_IFLNK, .readlink = proc_readlink_self},
Expand Down
50 changes: 33 additions & 17 deletions fs/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <sys/stat.h>
#include <sys/un.h>
#include "kernel/calls.h"
#include "kernel/task.h"
#include "fs/fd.h"
#include "fs/inode.h"
#include "fs/path.h"
Expand Down Expand Up @@ -375,8 +376,10 @@ int_t sys_connect(fd_t sock_fd, addr_t sockaddr_addr, uint_t sockaddr_len) {
if (res == sizeof(struct fd *)) {
// Wait for acknowledgement that it happened.
lock(&peer_lock);
while (sock->socket.unix_peer == NULL)
wait_for_ignore_signals(&sock->socket.unix_got_peer, &peer_lock, NULL);
TASK_MAY_BLOCK {
while (sock->socket.unix_peer == NULL)
wait_for_ignore_signals(&sock->socket.unix_got_peer, &peer_lock, NULL);
}
unlock(&peer_lock);
}
}
Expand Down Expand Up @@ -409,14 +412,16 @@ int_t sys_accept(fd_t sock_fd, addr_t sockaddr_addr, addr_t sockaddr_len_addr) {

char sockaddr[sockaddr_len];
int client;
do {
sockrestart_begin_listen_wait(sock);
errno = 0;
client = accept(sock->real_fd,
sockaddr_addr != 0 ? (void *) sockaddr : NULL,
sockaddr_addr != 0 ? &sockaddr_len : NULL);
sockrestart_end_listen_wait(sock);
} while (sockrestart_should_restart_listen_wait() && errno == EINTR);
TASK_MAY_BLOCK {
do {
sockrestart_begin_listen_wait(sock);
errno = 0;
client = accept(sock->real_fd,
sockaddr_addr != 0 ? (void *) sockaddr : NULL,
sockaddr_addr != 0 ? &sockaddr_len : NULL);
sockrestart_end_listen_wait(sock);
} while (sockrestart_should_restart_listen_wait() && errno == EINTR);
}
if (client < 0)
return errno_map();

Expand Down Expand Up @@ -589,8 +594,11 @@ int_t sys_sendto(fd_t sock_fd, addr_t buffer_addr, dword_t len, dword_t flags, a
goto error;
}

ssize_t res = sendto(sock->real_fd, buffer, len, real_flags,
sockaddr_addr ? (void *) &sockaddr : NULL, sockaddr_len);
ssize_t res = 0;
TASK_MAY_BLOCK {
res = sendto(sock->real_fd, buffer, len, real_flags,
sockaddr_addr ? (void *) &sockaddr : NULL, sockaddr_len);
}
free(buffer);
if (res < 0)
return errno_map();
Expand All @@ -616,9 +624,12 @@ int_t sys_recvfrom(fd_t sock_fd, addr_t buffer_addr, dword_t len, dword_t flags,

char *buffer = malloc(len);
char sockaddr[sockaddr_len];
ssize_t res = recvfrom(sock->real_fd, buffer, len, real_flags,
sockaddr_addr != 0 ? (void *) sockaddr : NULL,
sockaddr_len_addr != 0 ? &sockaddr_len : NULL);
ssize_t res = 0;
TASK_MAY_BLOCK {
res = recvfrom(sock->real_fd, buffer, len, real_flags,
sockaddr_addr != 0 ? (void *) sockaddr : NULL,
sockaddr_len_addr != 0 ? &sockaddr_len : NULL);
}
if (res < 0) {
free(buffer);
return errno_map();
Expand Down Expand Up @@ -946,7 +957,9 @@ int_t sys_sendmsg(fd_t sock_fd, addr_t msghdr_addr, int_t flags) {
if (real_flags < 0)
goto out_free_scm;

err = sendmsg(sock->real_fd, &msg, real_flags);
TASK_MAY_BLOCK {
err = sendmsg(sock->real_fd, &msg, real_flags);
}
if (err < 0) {
err = errno_map();
goto out_free_scm;
Expand Down Expand Up @@ -1018,7 +1031,10 @@ int_t sys_recvmsg(fd_t sock_fd, addr_t msghdr_addr, int_t flags) {
msg_iov[i].iov_base = malloc(msg_iov_fake[i].len);
}

ssize_t res = recvmsg(sock->real_fd, &msg, real_flags);
ssize_t res = 0;
TASK_MAY_BLOCK {
res = recvmsg(sock->real_fd, &msg, real_flags);
}
int err = 0;
if (res < 0)
err = errno_map();
Expand Down
10 changes: 8 additions & 2 deletions kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,10 @@ int do_wait(int idtype, pid_t_ id, struct siginfo_ *info, struct rusage_ *rusage
dword_t sys_waitid(int_t idtype, pid_t_ id, addr_t info_addr, int_t options) {
STRACE("waitid(%d, %d, %#x, %#x)", idtype, id, info_addr, options);
struct siginfo_ info = {};
int_t res = do_wait(idtype, id, &info, NULL, options);
int_t res;
TASK_MAY_BLOCK {
res = do_wait(idtype, id, &info, NULL, options);
}
if (res < 0 || (res == 0 && info.child.pid == 0))
return res;
if (info_addr != 0 && user_put(info_addr, info))
Expand Down Expand Up @@ -360,7 +363,10 @@ dword_t sys_wait4(pid_t_ id, addr_t status_addr, dword_t options, addr_t rusage_

struct siginfo_ info = {.child.pid = 0xbaba};
struct rusage_ rusage;
int_t res = do_wait(idtype, id, &info, &rusage, options | WEXITED_);
int_t res;
TASK_MAY_BLOCK {
res = do_wait(idtype, id, &info, &rusage, options | WEXITED_);
}
if (res < 0 || (res == 0 && info.child.pid == 0))
return res;
if (status_addr != 0 && user_put(status_addr, info.child.status))
Expand Down
Loading