Skip to content

Commit 3d54941

Browse files
author
Mike Miller
committed
Merge branch 'procfs' of https://github.com/nimelehin/ish into AOK
Incorporated upstream PR ish-app#1066, procps enhancements
2 parents 5a53c34 + dd0dd60 commit 3d54941

File tree

16 files changed

+347
-79
lines changed

16 files changed

+347
-79
lines changed

fs/lock.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,14 @@ int fcntl_setlk(struct fd *fd, struct flock_ *flock, bool blocking) {
226226
int err = file_lock_from_flock(fd, flock, &request);
227227
if (err < 0)
228228
goto out;
229-
while ((err = file_lock_acquire(inode, &request)) == _EAGAIN) {
230-
if (!blocking)
231-
break;
232-
err = wait_for(&inode->posix_unlock, &inode->lock, NULL);
233-
if (err < 0)
234-
break;
229+
TASK_MAY_BLOCK {
230+
while ((err = file_lock_acquire(inode, &request)) == _EAGAIN) {
231+
if (!blocking)
232+
break;
233+
err = wait_for(&inode->posix_unlock, &inode->lock, NULL);
234+
if (err < 0)
235+
break;
236+
}
235237
}
236238
out:
237239
unlock(&inode->lock);

fs/proc/pid.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,17 @@ static int proc_pid_stat_show(struct proc_entry *entry, struct proc_data *buf) {
3232
lock(&task->group->lock);
3333
lock(&task->sighand->lock);
3434

35+
// program reads this using read-like syscall, so we are in blocking area,
36+
// which means its io_block is set to true. When a proc reads an
37+
// information about itself, but it shouldn't be marked as blocked.
38+
char proc_state = (task->zombie ? 'Z' :
39+
task->group->stopped ? 'T' :
40+
task->io_block && task->pid != current->pid ? 'S' :
41+
'R');
42+
3543
proc_printf(buf, "%d ", task->pid);
3644
proc_printf(buf, "(%.16s) ", task->comm);
37-
proc_printf(buf, "%c ",
38-
task->zombie ? 'Z' :
39-
task->group->stopped ? 'T' :
40-
'R'); // I have no visibility into sleep state at the moment
45+
proc_printf(buf, "%c ", proc_state);
4146
proc_printf(buf, "%d ", task->parent ? task->parent->pid : 0);
4247
proc_printf(buf, "%d ", task->group->pgid);
4348
proc_printf(buf, "%d ", task->group->sid);
@@ -103,6 +108,17 @@ static int proc_pid_stat_show(struct proc_entry *entry, struct proc_data *buf) {
103108
return 0;
104109
}
105110

111+
static int proc_pid_statm_show(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
112+
proc_printf(buf, "%lu ", 0l); // size
113+
proc_printf(buf, "%lu ", 0l); // resident
114+
proc_printf(buf, "%lu ", 0l); // shared
115+
proc_printf(buf, "%lu ", 0l); // text
116+
proc_printf(buf, "%lu ", 0l); // lib (unused since Linux 2.6)
117+
proc_printf(buf, "%lu ", 0l); // data
118+
proc_printf(buf, "%lu\n", 0l); // dt (unused since Linux 2.6)
119+
return 0;
120+
}
121+
106122
static int proc_pid_auxv_show(struct proc_entry *entry, struct proc_data *buf) {
107123
struct task *task = proc_get_task(entry);
108124
if (task == NULL)
@@ -267,6 +283,7 @@ struct proc_children proc_pid_children = PROC_CHILDREN({
267283
{"fd", S_IFDIR, .readdir = proc_pid_fd_readdir},
268284
{"maps", .show = proc_pid_maps_show},
269285
{"stat", .show = proc_pid_stat_show},
286+
{"statm", .show = proc_pid_statm_show},
270287
});
271288

272289
struct proc_dir_entry proc_pid = {NULL, S_IFDIR,

fs/proc/root.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
#include <sys/param.h> // for MIN and MAX
12
#include <sys/stat.h>
23
#include <inttypes.h>
34
#include <string.h>
45
#include "kernel/calls.h"
6+
#include "kernel/task.h"
57
#include "fs/proc.h"
68
#include "platform/platform.h"
79

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

1517
static int proc_show_stat(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
16-
struct cpu_usage usage = get_cpu_usage();
17-
proc_printf(buf, "cpu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64"\n", usage.user_ticks, usage.nice_ticks, usage.system_ticks, usage.idle_ticks);
18+
int ncpus = get_cpu_count();
19+
struct cpu_usage total_usage = get_total_cpu_usage();
20+
struct cpu_usage* per_cpu_usage = 0;
21+
struct uptime_info uptime_info = get_uptime();
22+
unsigned uptime = uptime_info.uptime_ticks;
23+
24+
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);
25+
26+
int err = get_per_cpu_usage(&per_cpu_usage);
27+
if (!err) {
28+
for (int i = 0; i < ncpus; i++) {
29+
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);
30+
}
31+
free(per_cpu_usage);
32+
}
33+
34+
int blocked_task_count = get_count_of_blocked_tasks();
35+
int alive_task_count = get_count_of_alive_tasks();
36+
proc_printf(buf, "ctxt 0\n");
37+
proc_printf(buf, "btime %u\n", uptime);
38+
proc_printf(buf, "processes %d\n", alive_task_count);
39+
proc_printf(buf, "procs_running %d\n", alive_task_count - blocked_task_count);
40+
proc_printf(buf, "procs_blocked %d\n", blocked_task_count);
41+
1842
return 0;
1943
}
2044

@@ -48,6 +72,21 @@ static int proc_show_uptime(struct proc_entry *UNUSED(entry), struct proc_data *
4872
return 0;
4973
}
5074

75+
static int proc_show_loadavg(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
76+
struct uptime_info uptime = get_uptime();
77+
struct pid *last_pid = pid_get_last_allocated();
78+
int last_pid_id = last_pid ? last_pid->id : 0;
79+
double load_1m = uptime.load_1m / 65536.0;
80+
double load_5m = uptime.load_5m / 65536.0;
81+
double load_15m = uptime.load_15m / 65536.0;
82+
int blocked_task_count = get_count_of_blocked_tasks();
83+
int alive_task_count = get_count_of_alive_tasks();
84+
// running_task_count is calculated approximetly, since we don't know the real number of currently running tasks.
85+
int running_task_count = MIN(get_cpu_count(), (int)(alive_task_count - blocked_task_count));
86+
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);
87+
return 0;
88+
}
89+
5190
static int proc_readlink_self(struct proc_entry *UNUSED(entry), char *buf) {
5291
sprintf(buf, "%d/", current->pid);
5392
return 0;
@@ -98,6 +137,7 @@ static int proc_show_mounts(struct proc_entry *UNUSED(entry), struct proc_data *
98137
// in alphabetical order
99138
struct proc_dir_entry proc_root_entries[] = {
100139
{"ish", S_IFDIR, .children = &proc_ish_children},
140+
{"loadavg", .show = proc_show_loadavg},
101141
{"meminfo", .show = proc_show_meminfo},
102142
{"mounts", .show = proc_show_mounts},
103143
{"self", S_IFLNK, .readlink = proc_readlink_self},

fs/sock.c

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <sys/stat.h>
66
#include <sys/un.h>
77
#include "kernel/calls.h"
8+
#include "kernel/task.h"
89
#include "fs/fd.h"
910
#include "fs/inode.h"
1011
#include "fs/path.h"
@@ -375,8 +376,10 @@ int_t sys_connect(fd_t sock_fd, addr_t sockaddr_addr, uint_t sockaddr_len) {
375376
if (res == sizeof(struct fd *)) {
376377
// Wait for acknowledgement that it happened.
377378
lock(&peer_lock);
378-
while (sock->socket.unix_peer == NULL)
379-
wait_for_ignore_signals(&sock->socket.unix_got_peer, &peer_lock, NULL);
379+
TASK_MAY_BLOCK {
380+
while (sock->socket.unix_peer == NULL)
381+
wait_for_ignore_signals(&sock->socket.unix_got_peer, &peer_lock, NULL);
382+
}
380383
unlock(&peer_lock);
381384
}
382385
}
@@ -409,14 +412,16 @@ int_t sys_accept(fd_t sock_fd, addr_t sockaddr_addr, addr_t sockaddr_len_addr) {
409412

410413
char sockaddr[sockaddr_len];
411414
int client;
412-
do {
413-
sockrestart_begin_listen_wait(sock);
414-
errno = 0;
415-
client = accept(sock->real_fd,
416-
sockaddr_addr != 0 ? (void *) sockaddr : NULL,
417-
sockaddr_addr != 0 ? &sockaddr_len : NULL);
418-
sockrestart_end_listen_wait(sock);
419-
} while (sockrestart_should_restart_listen_wait() && errno == EINTR);
415+
TASK_MAY_BLOCK {
416+
do {
417+
sockrestart_begin_listen_wait(sock);
418+
errno = 0;
419+
client = accept(sock->real_fd,
420+
sockaddr_addr != 0 ? (void *) sockaddr : NULL,
421+
sockaddr_addr != 0 ? &sockaddr_len : NULL);
422+
sockrestart_end_listen_wait(sock);
423+
} while (sockrestart_should_restart_listen_wait() && errno == EINTR);
424+
}
420425
if (client < 0)
421426
return errno_map();
422427

@@ -589,8 +594,11 @@ int_t sys_sendto(fd_t sock_fd, addr_t buffer_addr, dword_t len, dword_t flags, a
589594
goto error;
590595
}
591596

592-
ssize_t res = sendto(sock->real_fd, buffer, len, real_flags,
593-
sockaddr_addr ? (void *) &sockaddr : NULL, sockaddr_len);
597+
ssize_t res = 0;
598+
TASK_MAY_BLOCK {
599+
res = sendto(sock->real_fd, buffer, len, real_flags,
600+
sockaddr_addr ? (void *) &sockaddr : NULL, sockaddr_len);
601+
}
594602
free(buffer);
595603
if (res < 0)
596604
return errno_map();
@@ -616,9 +624,12 @@ int_t sys_recvfrom(fd_t sock_fd, addr_t buffer_addr, dword_t len, dword_t flags,
616624

617625
char *buffer = malloc(len);
618626
char sockaddr[sockaddr_len];
619-
ssize_t res = recvfrom(sock->real_fd, buffer, len, real_flags,
620-
sockaddr_addr != 0 ? (void *) sockaddr : NULL,
621-
sockaddr_len_addr != 0 ? &sockaddr_len : NULL);
627+
ssize_t res = 0;
628+
TASK_MAY_BLOCK {
629+
res = recvfrom(sock->real_fd, buffer, len, real_flags,
630+
sockaddr_addr != 0 ? (void *) sockaddr : NULL,
631+
sockaddr_len_addr != 0 ? &sockaddr_len : NULL);
632+
}
622633
if (res < 0) {
623634
free(buffer);
624635
return errno_map();
@@ -946,7 +957,9 @@ int_t sys_sendmsg(fd_t sock_fd, addr_t msghdr_addr, int_t flags) {
946957
if (real_flags < 0)
947958
goto out_free_scm;
948959

949-
err = sendmsg(sock->real_fd, &msg, real_flags);
960+
TASK_MAY_BLOCK {
961+
err = sendmsg(sock->real_fd, &msg, real_flags);
962+
}
950963
if (err < 0) {
951964
err = errno_map();
952965
goto out_free_scm;
@@ -1018,7 +1031,10 @@ int_t sys_recvmsg(fd_t sock_fd, addr_t msghdr_addr, int_t flags) {
10181031
msg_iov[i].iov_base = malloc(msg_iov_fake[i].len);
10191032
}
10201033

1021-
ssize_t res = recvmsg(sock->real_fd, &msg, real_flags);
1034+
ssize_t res = 0;
1035+
TASK_MAY_BLOCK {
1036+
res = recvmsg(sock->real_fd, &msg, real_flags);
1037+
}
10221038
int err = 0;
10231039
if (res < 0)
10241040
err = errno_map();

kernel/exit.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,10 @@ int do_wait(int idtype, pid_t_ id, struct siginfo_ *info, struct rusage_ *rusage
332332
dword_t sys_waitid(int_t idtype, pid_t_ id, addr_t info_addr, int_t options) {
333333
STRACE("waitid(%d, %d, %#x, %#x)", idtype, id, info_addr, options);
334334
struct siginfo_ info = {};
335-
int_t res = do_wait(idtype, id, &info, NULL, options);
335+
int_t res;
336+
TASK_MAY_BLOCK {
337+
res = do_wait(idtype, id, &info, NULL, options);
338+
}
336339
if (res < 0 || (res == 0 && info.child.pid == 0))
337340
return res;
338341
if (info_addr != 0 && user_put(info_addr, info))
@@ -360,7 +363,10 @@ dword_t sys_wait4(pid_t_ id, addr_t status_addr, dword_t options, addr_t rusage_
360363

361364
struct siginfo_ info = {.child.pid = 0xbaba};
362365
struct rusage_ rusage;
363-
int_t res = do_wait(idtype, id, &info, &rusage, options | WEXITED_);
366+
int_t res;
367+
TASK_MAY_BLOCK {
368+
res = do_wait(idtype, id, &info, &rusage, options | WEXITED_);
369+
}
364370
if (res < 0 || (res == 0 && info.child.pid == 0))
365371
return res;
366372
if (status_addr != 0 && user_put(status_addr, info.child.status))

0 commit comments

Comments
 (0)