Compare commits
18 Commits
1.5.1-knl+
...
1.5.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 14d819eff4 | |||
| 1cbe389879 | |||
| 0758f6254e | |||
| db732a245c | |||
| 08f2840f7d | |||
| 521bdc6181 | |||
| e7b6a3472b | |||
| 11756d96ef | |||
| f185be06eb | |||
| 854bc85602 | |||
| ab8fe0bbbf | |||
| b87c06cbcb | |||
| b939ca9370 | |||
| ec202a1ca9 | |||
| d4471df94e | |||
| a6ac4acf40 | |||
| 8ff754c466 | |||
| 90dba00742 |
@ -1801,8 +1801,9 @@ SYSCALL_DECLARE(mmap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((flags & MAP_FIXED) && ((addr < region->user_start)
|
||||
|| (region->user_end <= addr))) {
|
||||
if (addr < region->user_start
|
||||
|| region->user_end <= addr
|
||||
|| len > (region->user_end - region->user_start)) {
|
||||
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n",
|
||||
addr0, len0, prot, flags0, fd, off0);
|
||||
error = -ENOMEM;
|
||||
|
||||
@ -1570,8 +1570,9 @@ SYSCALL_DECLARE(mmap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((flags & MAP_FIXED) && ((addr < region->user_start)
|
||||
|| (region->user_end <= addr))) {
|
||||
if (addr < region->user_start
|
||||
|| region->user_end <= addr
|
||||
|| len > (region->user_end - region->user_start)) {
|
||||
ekprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):ENOMEM\n",
|
||||
addr0, len0, prot, flags0, fd, off0);
|
||||
error = -ENOMEM;
|
||||
|
||||
@ -43,7 +43,8 @@ error_exit() {
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 1
|
||||
# Retun -EINVAL
|
||||
exit -22
|
||||
}
|
||||
fi
|
||||
|
||||
@ -144,3 +145,5 @@ for cpuid in `find /sys/bus/cpu/devices/* -maxdepth 0 -name "cpu[0123456789]*" -
|
||||
rm -rf /tmp/mcos/mcos0_sys/bus/cpu/devices/$cpuid
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
||||
@ -8,6 +8,9 @@ if grep mcoverlay /proc/modules &>/dev/null; then
|
||||
if [ -e /tmp/mcos ]; then rm -rf /tmp/mcos; fi
|
||||
if ! rmmod mcoverlay 2>/dev/null; then
|
||||
echo "error: removing mcoverlay" >&2
|
||||
exit 1
|
||||
# Return -EINVAL
|
||||
exit -22
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
# the same set of resources as it used previously.
|
||||
# Note that the script does not output anything unless an error occurs.
|
||||
|
||||
ret=1
|
||||
prefix="@prefix@"
|
||||
BINDIR="${prefix}/bin"
|
||||
SBINDIR="${prefix}/sbin"
|
||||
@ -204,7 +205,8 @@ error_exit() {
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 1
|
||||
# Propagate exit status if any
|
||||
exit $ret
|
||||
}
|
||||
|
||||
ihk_ikc_irq_core=0
|
||||
@ -255,7 +257,11 @@ fi
|
||||
|
||||
# Remove mcoverlay if loaded
|
||||
if [ "$enable_mcoverlay" == "yes" ]; then
|
||||
. ${SBINDIR}/mcoverlay-destroy.sh
|
||||
${SBINDIR}/mcoverlay-destroy.sh
|
||||
ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
error_exit "initial"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Stop irqbalance
|
||||
@ -458,7 +464,11 @@ fi
|
||||
|
||||
# Overlay /proc, /sys with McKernel specific contents
|
||||
if [ "$enable_mcoverlay" == "yes" ]; then
|
||||
. ${SBINDIR}/mcoverlay-create.sh
|
||||
${SBINDIR}/mcoverlay-create.sh
|
||||
ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
error_exit "os_created"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start irqbalance with CPUs and IRQ for McKernel banned
|
||||
|
||||
@ -100,7 +100,13 @@ if grep mcctrl /proc/modules &>/dev/null; then
|
||||
fi
|
||||
|
||||
# Remove mcoverlay if loaded
|
||||
. ${SBINDIR}/mcoverlay-destroy.sh
|
||||
${SBINDIR}/mcoverlay-destroy.sh
|
||||
ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo "error: mcoverlay-destroy.sh" >&2
|
||||
exit $ret
|
||||
fi
|
||||
|
||||
|
||||
# Remove SMP module
|
||||
if grep ihk_smp_@ARCH@ /proc/modules &>/dev/null; then
|
||||
|
||||
26
configure
vendored
26
configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for mckernel 1.5.0.
|
||||
# Generated by GNU Autoconf 2.69 for mckernel 1.5.1.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@ -577,8 +577,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='mckernel'
|
||||
PACKAGE_TARNAME='mckernel'
|
||||
PACKAGE_VERSION='1.5.0'
|
||||
PACKAGE_STRING='mckernel 1.5.0'
|
||||
PACKAGE_VERSION='1.5.1'
|
||||
PACKAGE_STRING='mckernel 1.5.1'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -1262,7 +1262,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures mckernel 1.5.0 to adapt to many kinds of systems.
|
||||
\`configure' configures mckernel 1.5.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1323,7 +1323,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of mckernel 1.5.0:";;
|
||||
short | recursive ) echo "Configuration of mckernel 1.5.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1431,7 +1431,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
mckernel configure 1.5.0
|
||||
mckernel configure 1.5.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -1729,7 +1729,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by mckernel $as_me 1.5.0, which was
|
||||
It was created by mckernel $as_me 1.5.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -2082,11 +2082,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
|
||||
IHK_VERSION=1.5.0
|
||||
MCKERNEL_VERSION=1.5.0
|
||||
IHK_VERSION=1.5.1
|
||||
MCKERNEL_VERSION=1.5.1
|
||||
DCFA_VERSION=DCFA_VERSION_m4
|
||||
IHK_RELEASE_DATE=2018-04-05
|
||||
MCKERNEL_RELEASE_DATE=2018-04-05
|
||||
IHK_RELEASE_DATE=2018-07-09
|
||||
MCKERNEL_RELEASE_DATE=2018-07-09
|
||||
DCFA_RELEASE_DATE=DCFA_RELEASE_DATE_m4
|
||||
|
||||
|
||||
@ -5585,7 +5585,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by mckernel $as_me 1.5.0, which was
|
||||
This file was extended by mckernel $as_me 1.5.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -5647,7 +5647,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
mckernel config.status 1.5.0
|
||||
mckernel config.status 1.5.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
# configure.ac COPYRIGHT FUJITSU LIMITED 2015-2016
|
||||
AC_PREREQ(2.63)
|
||||
m4_define([IHK_VERSION_m4],[1.5.0])dnl
|
||||
m4_define([MCKERNEL_VERSION_m4],[1.5.0])dnl
|
||||
m4_define([IHK_RELEASE_DATE_m4],[2018-04-05])dnl
|
||||
m4_define([MCKERNEL_RELEASE_DATE_m4],[2018-04-05])dnl
|
||||
m4_define([IHK_VERSION_m4],[1.5.1])dnl
|
||||
m4_define([MCKERNEL_VERSION_m4],[1.5.1])dnl
|
||||
m4_define([IHK_RELEASE_DATE_m4],[2018-07-09])dnl
|
||||
m4_define([MCKERNEL_RELEASE_DATE_m4],[2018-07-09])dnl
|
||||
|
||||
AC_INIT([mckernel], MCKERNEL_VERSION_m4)
|
||||
|
||||
|
||||
@ -111,10 +111,8 @@ typedef unsigned long __cpu_set_unit;
|
||||
|
||||
struct program_load_desc {
|
||||
int num_sections;
|
||||
int status;
|
||||
int cpu;
|
||||
int pid;
|
||||
int err;
|
||||
int stack_prot;
|
||||
int pgid;
|
||||
int cred[8];
|
||||
@ -253,7 +251,6 @@ enum perf_ctrl_type {
|
||||
|
||||
struct perf_ctrl_desc {
|
||||
enum perf_ctrl_type ctrl_type;
|
||||
int status;
|
||||
union {
|
||||
/* for SET, GET */
|
||||
struct {
|
||||
|
||||
@ -107,6 +107,7 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_per_proc_data *ppd = NULL;
|
||||
int num_sections;
|
||||
int free_ikc_pointers = 1;
|
||||
|
||||
desc = kmalloc(sizeof(*desc), GFP_KERNEL);
|
||||
if (!desc) {
|
||||
@ -140,9 +141,9 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
pdesc = kmalloc(sizeof(struct program_load_desc) +
|
||||
sizeof(struct program_image_section)
|
||||
* num_sections, GFP_KERNEL);
|
||||
pdesc = kmalloc(sizeof(struct program_load_desc) +
|
||||
sizeof(struct program_image_section) * num_sections,
|
||||
GFP_KERNEL);
|
||||
memcpy(pdesc, desc, sizeof(struct program_load_desc));
|
||||
|
||||
if (copy_from_user(pdesc->sections, udesc->sections,
|
||||
@ -167,10 +168,10 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
ret = -EFAULT;
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
|
||||
envs = kmalloc(pdesc->envs_len, GFP_KERNEL);
|
||||
if (copy_from_user(envs, pdesc->envs, pdesc->envs_len)) {
|
||||
ret = -EFAULT;
|
||||
ret = -EFAULT;
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
@ -187,36 +188,24 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
|
||||
dprintk("# of sections: %d\n", pdesc->num_sections);
|
||||
dprintk("%p (%lx)\n", pdesc, isp.arg);
|
||||
|
||||
pdesc->status = 0;
|
||||
mb();
|
||||
ret = mcctrl_ikc_send(os, pdesc->cpu, &isp);
|
||||
if(ret < 0) {
|
||||
printk("%s: ERROR mcctrl_ikc_send: %d\n", __FUNCTION__, ret);
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(ppd->wq_prepare, pdesc->status);
|
||||
ret = mcctrl_ikc_send_wait(os, pdesc->cpu, &isp, 0, NULL,
|
||||
&free_ikc_pointers, 3, pdesc, args, envs);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
if (pdesc->err < 0) {
|
||||
ret = pdesc->err;
|
||||
/* either send or remote prepare_process failed */
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
/* Update rpgtable */
|
||||
ppd->rpgtable = pdesc->rpgtable;
|
||||
|
||||
if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) +
|
||||
|
||||
if (copy_to_user(udesc, pdesc, sizeof(struct program_load_desc) +
|
||||
sizeof(struct program_image_section) * num_sections)) {
|
||||
ret = -EFAULT;
|
||||
ret = -EFAULT;
|
||||
goto put_and_free_out;
|
||||
}
|
||||
|
||||
dprintk("%s: pid %d, rpgtable: 0x%lx added\n",
|
||||
dprintk("%s: pid %d, rpgtable: 0x%lx added\n",
|
||||
__FUNCTION__, ppd->pid, ppd->rpgtable);
|
||||
|
||||
ret = 0;
|
||||
@ -224,10 +213,12 @@ static long mcexec_prepare_image(ihk_os_t os,
|
||||
put_and_free_out:
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
free_out:
|
||||
kfree(args);
|
||||
kfree(pdesc);
|
||||
kfree(envs);
|
||||
kfree(desc);
|
||||
if (free_ikc_pointers) {
|
||||
kfree(args);
|
||||
kfree(pdesc);
|
||||
kfree(envs);
|
||||
kfree(desc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -485,25 +476,33 @@ out:
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(signalq);
|
||||
|
||||
struct mcctrl_signal_desc {
|
||||
struct mcctrl_signal msig;
|
||||
struct mcctrl_wakeup_desc wakeup;
|
||||
void *addrs[1];
|
||||
};
|
||||
|
||||
static long mcexec_send_signal(ihk_os_t os, struct signal_desc *sigparam)
|
||||
{
|
||||
struct ikc_scd_packet isp;
|
||||
struct mcctrl_channel *c;
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct signal_desc sig;
|
||||
struct mcctrl_signal msig[2];
|
||||
struct mcctrl_signal_desc *desc;
|
||||
struct mcctrl_signal *msigp;
|
||||
int rc;
|
||||
int rc, do_free;
|
||||
|
||||
if (copy_from_user(&sig, sigparam, sizeof(struct signal_desc))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
msigp = msig;
|
||||
if(((unsigned long)msig & 0xfffffffffffff000L) !=
|
||||
((unsigned long)(msig + 1) & 0xfffffffffffff000L))
|
||||
msigp++;
|
||||
memset(msigp, '\0', sizeof msig);
|
||||
desc = kmalloc(sizeof(*desc), GFP_KERNEL);
|
||||
if (!desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
msigp = &desc->msig;
|
||||
memset(msigp, '\0', sizeof(*msigp));
|
||||
msigp->sig = sig.sig;
|
||||
msigp->pid = sig.pid;
|
||||
msigp->tid = sig.tid;
|
||||
@ -515,25 +514,19 @@ static long mcexec_send_signal(ihk_os_t os, struct signal_desc *sigparam)
|
||||
isp.pid = sig.pid;
|
||||
isp.arg = virt_to_phys(msigp);
|
||||
|
||||
if ((rc = mcctrl_ikc_send(os, sig.cpu, &isp)) < 0) {
|
||||
rc = mcctrl_ikc_send_wait(os, sig.cpu, &isp, 0, &desc->wakeup,
|
||||
&do_free, 1, desc);
|
||||
if (rc < 0) {
|
||||
printk("mcexec_send_signal: mcctrl_ikc_send ret=%d\n", rc);
|
||||
if (do_free)
|
||||
kfree(desc);
|
||||
return rc;
|
||||
}
|
||||
wait_event_interruptible(signalq, msigp->cond != 0);
|
||||
|
||||
kfree(desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sig_done(unsigned long arg, int err)
|
||||
{
|
||||
struct mcctrl_signal *msigp;
|
||||
|
||||
msigp = phys_to_virt(arg);
|
||||
msigp->cond = 1;
|
||||
wake_up_interruptible(&signalq);
|
||||
}
|
||||
|
||||
static long mcexec_get_cpu(ihk_os_t os)
|
||||
{
|
||||
struct ihk_cpu_info *info;
|
||||
@ -1691,7 +1684,6 @@ int mcexec_create_per_process_data(ihk_os_t os)
|
||||
INIT_LIST_HEAD(&ppd->wq_list);
|
||||
INIT_LIST_HEAD(&ppd->wq_req_list);
|
||||
INIT_LIST_HEAD(&ppd->wq_list_exact);
|
||||
init_waitqueue_head(&ppd->wq_prepare);
|
||||
init_waitqueue_head(&ppd->wq_procfs);
|
||||
spin_lock_init(&ppd->wq_list_lock);
|
||||
memset(&ppd->cpu_set, 0, sizeof(cpumask_t));
|
||||
@ -2019,58 +2011,65 @@ long mcctrl_perf_num(ihk_os_t os, unsigned long arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mcctrl_perf_ctrl_desc {
|
||||
struct perf_ctrl_desc desc;
|
||||
struct mcctrl_wakeup_desc wakeup;
|
||||
void *addrs[1];
|
||||
};
|
||||
#define wakeup_desc_of_perf_desc(_desc) \
|
||||
(&container_of((_desc), struct mcctrl_perf_ctrl_desc, desc)->wakeup)
|
||||
|
||||
long mcctrl_perf_set(ihk_os_t os, struct ihk_perf_event_attr *__user arg)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct ikc_scd_packet isp;
|
||||
struct perf_ctrl_desc *perf_desc = NULL;
|
||||
struct perf_ctrl_desc *perf_desc;
|
||||
struct ihk_perf_event_attr attr;
|
||||
struct ihk_cpu_info *info = ihk_os_get_cpu_info(os);
|
||||
int ret = 0;
|
||||
int i = 0, j = 0;
|
||||
int need_free;
|
||||
|
||||
for (i = 0; i < usrdata->perf_event_num; i++) {
|
||||
if (copy_from_user(&attr, &arg[i], sizeof(struct ihk_perf_event_attr))) {
|
||||
printk("%s: error: copying ihk_perf_event_attr from user\n",
|
||||
__FUNCTION__);
|
||||
ret = copy_from_user(&attr, &arg[i],
|
||||
sizeof(struct ihk_perf_event_attr));
|
||||
if (ret) {
|
||||
pr_err("%s: error: copying ihk_perf_event_attr from user\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
printk("%s: error: allocating perf_ctrl_desc\n",
|
||||
__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_SET;
|
||||
perf_desc->status = 0;
|
||||
perf_desc->target_cntr = i;
|
||||
perf_desc->config = attr.config;
|
||||
perf_desc->exclude_kernel = attr.exclude_kernel;
|
||||
perf_desc->exclude_user = attr.exclude_user;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) {
|
||||
printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(perfctrlq, perf_desc->status);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kfree(perf_desc);
|
||||
perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc),
|
||||
GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_SET;
|
||||
perf_desc->target_cntr = i;
|
||||
perf_desc->config = attr.config;
|
||||
perf_desc->exclude_kernel = attr.exclude_kernel;
|
||||
perf_desc->exclude_user = attr.exclude_user;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
ret = mcctrl_ikc_send_wait(os, j, &isp, 0,
|
||||
wakeup_desc_of_perf_desc(perf_desc),
|
||||
&need_free, 1, perf_desc);
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n",
|
||||
__func__, ret);
|
||||
if (need_free)
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(perf_desc);
|
||||
}
|
||||
|
||||
return usrdata->perf_event_num;
|
||||
@ -2080,48 +2079,46 @@ long mcctrl_perf_get(ihk_os_t os, unsigned long *__user arg)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct ikc_scd_packet isp;
|
||||
struct perf_ctrl_desc *perf_desc = NULL;
|
||||
struct perf_ctrl_desc *perf_desc;
|
||||
struct ihk_cpu_info *info = ihk_os_get_cpu_info(os);
|
||||
unsigned long value_sum = 0;
|
||||
int ret = 0;
|
||||
int i = 0, j = 0;
|
||||
int need_free;
|
||||
|
||||
for (i = 0; i < usrdata->perf_event_num; i++) {
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
printk("%s: error: allocating perf_ctrl_desc\n",
|
||||
__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_GET;
|
||||
perf_desc->status = 0;
|
||||
perf_desc->target_cntr = i;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) {
|
||||
printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(perfctrlq, perf_desc->status);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
value_sum += perf_desc->read_value;
|
||||
kfree(perf_desc);
|
||||
perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc),
|
||||
GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_GET;
|
||||
perf_desc->target_cntr = i;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
ret = mcctrl_ikc_send_wait(os, j, &isp, 0,
|
||||
wakeup_desc_of_perf_desc(perf_desc),
|
||||
&need_free, 1, perf_desc);
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n",
|
||||
__func__, ret);
|
||||
if (need_free)
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
value_sum += perf_desc->read_value;
|
||||
}
|
||||
kfree(perf_desc);
|
||||
if (copy_to_user(&arg[i], &value_sum, sizeof(unsigned long))) {
|
||||
printk("%s: error: copying read_value to user\n",
|
||||
__FUNCTION__);
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
value_sum = 0;
|
||||
@ -2134,46 +2131,44 @@ long mcctrl_perf_enable(ihk_os_t os)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct ikc_scd_packet isp;
|
||||
struct perf_ctrl_desc *perf_desc = NULL;
|
||||
struct perf_ctrl_desc *perf_desc;
|
||||
struct ihk_cpu_info *info = ihk_os_get_cpu_info(os);
|
||||
unsigned int cntr_mask = 0;
|
||||
int ret = 0;
|
||||
int i = 0, j = 0;
|
||||
int need_free;
|
||||
|
||||
for (i = 0; i < usrdata->perf_event_num; i++) {
|
||||
cntr_mask |= 1 << i;
|
||||
}
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
printk("%s: error: allocating perf_ctrl_desc\n",
|
||||
__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_ENABLE;
|
||||
perf_desc->status = 0;
|
||||
perf_desc->target_cntr_mask = cntr_mask;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) {
|
||||
printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(perfctrlq, perf_desc->status);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
kfree(perf_desc);
|
||||
perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_ENABLE;
|
||||
perf_desc->target_cntr_mask = cntr_mask;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
ret = mcctrl_ikc_send_wait(os, j, &isp, 0,
|
||||
wakeup_desc_of_perf_desc(perf_desc),
|
||||
&need_free, 1, perf_desc);
|
||||
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n",
|
||||
__func__, ret);
|
||||
if (need_free)
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
}
|
||||
kfree(perf_desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2182,46 +2177,43 @@ long mcctrl_perf_disable(ihk_os_t os)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct ikc_scd_packet isp;
|
||||
struct perf_ctrl_desc *perf_desc = NULL;
|
||||
struct perf_ctrl_desc *perf_desc;
|
||||
struct ihk_cpu_info *info = ihk_os_get_cpu_info(os);
|
||||
unsigned int cntr_mask = 0;
|
||||
int ret = 0;
|
||||
int i = 0, j = 0;
|
||||
int need_free;
|
||||
|
||||
for (i = 0; i < usrdata->perf_event_num; i++) {
|
||||
cntr_mask |= 1 << i;
|
||||
}
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
perf_desc = kmalloc(sizeof(struct perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
printk("%s: error: allocating perf_ctrl_desc\n",
|
||||
__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_DISABLE;
|
||||
perf_desc->status = 0;
|
||||
perf_desc->target_cntr_mask = cntr_mask;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
if ((ret = mcctrl_ikc_send(os, j, &isp)) < 0) {
|
||||
printk("%s: mcctrl_ikc_send ret=%d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible(perfctrlq, perf_desc->status);
|
||||
if (ret < 0) {
|
||||
printk("%s: ERROR after wait: %d\n", __FUNCTION__, ret);
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
kfree(perf_desc);
|
||||
perf_desc = kmalloc(sizeof(struct mcctrl_perf_ctrl_desc), GFP_KERNEL);
|
||||
if (!perf_desc) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(perf_desc, '\0', sizeof(struct perf_ctrl_desc));
|
||||
|
||||
perf_desc->ctrl_type = PERF_CTRL_DISABLE;
|
||||
perf_desc->target_cntr_mask = cntr_mask;
|
||||
|
||||
memset(&isp, '\0', sizeof(struct ikc_scd_packet));
|
||||
isp.msg = SCD_MSG_PERF_CTRL;
|
||||
isp.arg = virt_to_phys(perf_desc);
|
||||
|
||||
for (j = 0; j < info->n_cpus; j++) {
|
||||
ret = mcctrl_ikc_send_wait(os, j, &isp, 0,
|
||||
wakeup_desc_of_perf_desc(perf_desc),
|
||||
&need_free, 1, perf_desc);
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send_wait ret=%d\n",
|
||||
__func__, ret);
|
||||
if (need_free)
|
||||
kfree(perf_desc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
}
|
||||
kfree(perf_desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2233,15 +2225,6 @@ long mcctrl_perf_destroy(ihk_os_t os)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mcctrl_perf_ack(ihk_os_t os, struct ikc_scd_packet *packet)
|
||||
{
|
||||
struct perf_ctrl_desc *perf_desc = phys_to_virt(packet->arg);
|
||||
|
||||
perf_desc->status = 1;
|
||||
wake_up_interruptible(&perfctrlq);
|
||||
|
||||
}
|
||||
|
||||
/* Compose LWK-specific rusage structure */
|
||||
long mcctrl_getrusage(ihk_os_t ihk_os, struct mcctrl_ioctl_getrusage_desc *__user _desc)
|
||||
{
|
||||
@ -2925,28 +2908,6 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void mcexec_prepare_ack(ihk_os_t os, unsigned long arg, int err)
|
||||
{
|
||||
struct program_load_desc *desc = phys_to_virt(arg);
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_per_proc_data *ppd = NULL;
|
||||
|
||||
ppd = mcctrl_get_per_proc_data(usrdata, desc->pid);
|
||||
if (!ppd) {
|
||||
printk("%s: ERROR: no per process data for PID %d\n",
|
||||
__FUNCTION__, desc->pid);
|
||||
return;
|
||||
}
|
||||
|
||||
desc->err = err;
|
||||
desc->status = 1;
|
||||
mb();
|
||||
|
||||
wake_up_all(&ppd->wq_prepare);
|
||||
mcctrl_put_per_proc_data(ppd);
|
||||
}
|
||||
|
||||
|
||||
/* Per-CPU register manipulation functions */
|
||||
struct mcctrl_os_cpu_response {
|
||||
int done;
|
||||
|
||||
@ -49,15 +49,123 @@
|
||||
|
||||
//struct mcctrl_channel *channels;
|
||||
|
||||
void mcexec_prepare_ack(ihk_os_t os, unsigned long arg, int err);
|
||||
static void mcctrl_ikc_init(ihk_os_t os, int cpu, unsigned long rphys, struct ihk_ikc_channel_desc *c);
|
||||
int mcexec_syscall(struct mcctrl_usrdata *ud, struct ikc_scd_packet *packet);
|
||||
void sig_done(unsigned long arg, int err);
|
||||
void mcctrl_perf_ack(ihk_os_t os, struct ikc_scd_packet *packet);
|
||||
void mcctrl_os_read_write_cpu_response(ihk_os_t os,
|
||||
struct ikc_scd_packet *pisp);
|
||||
void mcctrl_eventfd(ihk_os_t os, struct ikc_scd_packet *pisp);
|
||||
|
||||
/* Assumes usrdata->wakeup_descs_lock taken */
|
||||
static void mcctrl_wakeup_desc_cleanup(ihk_os_t os,
|
||||
struct mcctrl_wakeup_desc *desc)
|
||||
{
|
||||
int i;
|
||||
|
||||
list_del(&desc->chain);
|
||||
|
||||
for (i = 0; i < desc->free_addrs_count; i++) {
|
||||
kfree(desc->free_addrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void mcctrl_wakeup_cb(ihk_os_t os, struct ikc_scd_packet *packet)
|
||||
{
|
||||
struct mcctrl_wakeup_desc *desc = packet->reply;
|
||||
|
||||
|
||||
WRITE_ONCE(desc->err, packet->err);
|
||||
|
||||
/*
|
||||
* Check if the other side is still waiting, and signal it we're done.
|
||||
*
|
||||
* Setting status needs to be done last because the other side could
|
||||
* wake up opportunistically between this set and the wake_up call.
|
||||
*
|
||||
* If the other side is no longer waiting, free the memory that was
|
||||
* left for us.
|
||||
*/
|
||||
if (cmpxchg(&desc->status, 0, 1)) {
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&usrdata->wakeup_descs_lock, flags);
|
||||
mcctrl_wakeup_desc_cleanup(os, desc);
|
||||
spin_unlock_irqrestore(&usrdata->wakeup_descs_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
wake_up_interruptible(&desc->wq);
|
||||
}
|
||||
|
||||
int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp,
|
||||
long int timeout, struct mcctrl_wakeup_desc *desc,
|
||||
int *do_frees, int free_addrs_count, ...)
|
||||
{
|
||||
int ret, i;
|
||||
int alloc_desc = (desc == NULL);
|
||||
va_list ap;
|
||||
|
||||
if (free_addrs_count)
|
||||
*do_frees = 1;
|
||||
if (alloc_desc)
|
||||
desc = kmalloc(sizeof(struct mcctrl_wakeup_desc) +
|
||||
(free_addrs_count + 1) * sizeof(void *),
|
||||
GFP_KERNEL);
|
||||
if (!desc) {
|
||||
pr_warn("%s: Could not allocate wakeup descriptor", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
pisp->reply = desc;
|
||||
va_start(ap, free_addrs_count);
|
||||
for (i = 0; i < free_addrs_count; i++) {
|
||||
desc->free_addrs[i] = va_arg(ap, void*);
|
||||
}
|
||||
va_end(ap);
|
||||
if (alloc_desc)
|
||||
desc->free_addrs[free_addrs_count++] = desc;
|
||||
desc->free_addrs_count = free_addrs_count;
|
||||
init_waitqueue_head(&desc->wq);
|
||||
WRITE_ONCE(desc->err, 0);
|
||||
WRITE_ONCE(desc->status, 0);
|
||||
|
||||
ret = mcctrl_ikc_send(os, cpu, pisp);
|
||||
if (ret < 0) {
|
||||
pr_warn("%s: mcctrl_ikc_send failed: %d\n", __func__, ret);
|
||||
kfree(desc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
ret = wait_event_interruptible_timeout(desc->wq,
|
||||
desc->status, timeout);
|
||||
} else {
|
||||
ret = wait_event_interruptible(desc->wq, desc->status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if wait aborted (signal..) or timed out, and notify
|
||||
* the callback it will need to free things for us
|
||||
*/
|
||||
if (!cmpxchg(&desc->status, 0, 1)) {
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&usrdata->wakeup_descs_lock, flags);
|
||||
list_add(&desc->chain, &usrdata->wakeup_descs_list);
|
||||
spin_unlock_irqrestore(&usrdata->wakeup_descs_lock, flags);
|
||||
if (free_addrs_count)
|
||||
*do_frees = 0;
|
||||
return ret < 0 ? ret : -ETIME;
|
||||
}
|
||||
|
||||
ret = READ_ONCE(desc->err);
|
||||
if (alloc_desc)
|
||||
kfree(desc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* XXX: this runs in atomic context! */
|
||||
static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
void *__packet, void *__os)
|
||||
@ -72,11 +180,9 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
break;
|
||||
|
||||
case SCD_MSG_PREPARE_PROCESS_ACKED:
|
||||
mcexec_prepare_ack(__os, pisp->arg, 0);
|
||||
break;
|
||||
|
||||
case SCD_MSG_PREPARE_PROCESS_NACKED:
|
||||
mcexec_prepare_ack(__os, pisp->arg, pisp->err);
|
||||
case SCD_MSG_PERF_ACK:
|
||||
case SCD_MSG_SEND_SIGNAL_ACK:
|
||||
mcctrl_wakeup_cb(__os, pisp);
|
||||
break;
|
||||
|
||||
case SCD_MSG_SYSCALL_ONESIDE:
|
||||
@ -87,9 +193,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
procfs_answer(usrdata, pisp->pid);
|
||||
break;
|
||||
|
||||
case SCD_MSG_SEND_SIGNAL:
|
||||
sig_done(pisp->arg, pisp->err);
|
||||
break;
|
||||
|
||||
case SCD_MSG_SYSFS_REQ_CREATE:
|
||||
case SCD_MSG_SYSFS_REQ_MKDIR:
|
||||
@ -113,10 +216,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
get_vdso_info(__os, pisp->arg);
|
||||
break;
|
||||
|
||||
case SCD_MSG_PERF_ACK:
|
||||
mcctrl_perf_ack(__os, pisp);
|
||||
break;
|
||||
|
||||
case SCD_MSG_CPU_RW_REG_RESP:
|
||||
mcctrl_os_read_write_cpu_response(__os, pisp);
|
||||
break;
|
||||
@ -157,10 +256,15 @@ static int dummy_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
|
||||
int mcctrl_ikc_send(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp)
|
||||
{
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_usrdata *usrdata;
|
||||
|
||||
if (cpu < 0 || os == NULL || usrdata == NULL ||
|
||||
cpu >= usrdata->num_channels || !usrdata->channels[cpu].c) {
|
||||
if (cpu < 0 || os == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
usrdata = ihk_host_os_get_usrdata(os);
|
||||
if (usrdata == NULL || cpu >= usrdata->num_channels ||
|
||||
!usrdata->channels[cpu].c) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return ihk_ikc_send(usrdata->channels[cpu].c, pisp, 0);
|
||||
@ -354,6 +458,8 @@ int prepare_ikc_channels(ihk_os_t os)
|
||||
mutex_init(&usrdata->part_exec.lock);
|
||||
INIT_LIST_HEAD(&usrdata->part_exec.pli_list);
|
||||
usrdata->part_exec.nr_processes = -1;
|
||||
INIT_LIST_HEAD(&usrdata->wakeup_descs_list);
|
||||
spin_lock_init(&usrdata->wakeup_descs_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -375,7 +481,9 @@ void __destroy_ikc_channel(ihk_os_t os, struct mcctrl_channel *pmc)
|
||||
void destroy_ikc_channels(ihk_os_t os)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
struct mcctrl_usrdata *usrdata = ihk_host_os_get_usrdata(os);
|
||||
struct mcctrl_wakeup_desc *mwd_entry, *mwd_next;
|
||||
|
||||
if (!usrdata) {
|
||||
printk("%s: WARNING: no mcctrl_usrdata found\n", __FUNCTION__);
|
||||
@ -395,6 +503,12 @@ void destroy_ikc_channels(ihk_os_t os)
|
||||
ihk_ikc_destroy_channel(usrdata->ikc2linux[i]);
|
||||
}
|
||||
}
|
||||
spin_lock_irqsave(&usrdata->wakeup_descs_lock, flags);
|
||||
list_for_each_entry_safe(mwd_entry, mwd_next,
|
||||
&usrdata->wakeup_descs_list, chain) {
|
||||
mcctrl_wakeup_desc_cleanup(os, mwd_entry);
|
||||
}
|
||||
spin_unlock_irqrestore(&usrdata->wakeup_descs_lock, flags);
|
||||
|
||||
kfree(usrdata->channels);
|
||||
kfree(usrdata->ikc2linux);
|
||||
|
||||
@ -48,7 +48,6 @@
|
||||
|
||||
#define SCD_MSG_PREPARE_PROCESS 0x1
|
||||
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
||||
#define SCD_MSG_PREPARE_PROCESS_NACKED 0x7
|
||||
#define SCD_MSG_SCHEDULE_PROCESS 0x3
|
||||
#define SCD_MSG_WAKE_UP_SYSCALL_THREAD 0x14
|
||||
|
||||
@ -56,7 +55,8 @@
|
||||
#define SCD_MSG_INIT_CHANNEL_ACKED 0x6
|
||||
|
||||
#define SCD_MSG_SYSCALL_ONESIDE 0x4
|
||||
#define SCD_MSG_SEND_SIGNAL 0x8
|
||||
#define SCD_MSG_SEND_SIGNAL 0x7
|
||||
#define SCD_MSG_SEND_SIGNAL_ACK 0x8
|
||||
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
||||
#define SCD_MSG_GET_VDSO_INFO 0xa
|
||||
|
||||
@ -128,6 +128,7 @@ enum mcctrl_os_cpu_operation {
|
||||
struct ikc_scd_packet {
|
||||
int msg;
|
||||
int err;
|
||||
void *reply;
|
||||
union {
|
||||
/* for traditional SCD_MSG_* */
|
||||
struct {
|
||||
@ -163,9 +164,10 @@ struct ikc_scd_packet {
|
||||
int eventfd_type;
|
||||
};
|
||||
};
|
||||
char padding[12];
|
||||
char padding[8];
|
||||
};
|
||||
|
||||
|
||||
struct mcctrl_priv {
|
||||
ihk_os_t os;
|
||||
struct program_load_desc *desc;
|
||||
@ -231,7 +233,6 @@ struct mcctrl_per_proc_data {
|
||||
struct list_head wq_list_exact; /* These requests come from IKC IRQ handler targeting a particular thread */
|
||||
|
||||
ihk_spinlock_t wq_list_lock;
|
||||
wait_queue_head_t wq_prepare;
|
||||
wait_queue_head_t wq_procfs;
|
||||
|
||||
struct list_head per_thread_data_hash[MCCTRL_PER_THREAD_DATA_HASH_SIZE];
|
||||
@ -342,6 +343,8 @@ struct mcctrl_usrdata {
|
||||
wait_queue_head_t wq_procfs;
|
||||
struct list_head per_proc_data_hash[MCCTRL_PER_PROC_DATA_HASH_SIZE];
|
||||
rwlock_t per_proc_data_hash_lock[MCCTRL_PER_PROC_DATA_HASH_SIZE];
|
||||
struct list_head wakeup_descs_list;
|
||||
spinlock_t wakeup_descs_lock;
|
||||
|
||||
void **keys;
|
||||
struct sysfsm_data sysfsm_data;
|
||||
@ -367,6 +370,34 @@ int mcctrl_ikc_send(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp);
|
||||
int mcctrl_ikc_send_msg(ihk_os_t os, int cpu, int msg, int ref, unsigned long arg);
|
||||
int mcctrl_ikc_is_valid_thread(ihk_os_t os, int cpu);
|
||||
|
||||
struct mcctrl_wakeup_desc {
|
||||
int status;
|
||||
int err;
|
||||
wait_queue_head_t wq;
|
||||
struct list_head chain;
|
||||
int free_addrs_count;
|
||||
void *free_addrs[];
|
||||
};
|
||||
|
||||
/* ikc query-and-wait helper
|
||||
*
|
||||
* Arguments:
|
||||
* - os, cpu and pisp as per mcctl_ikc_send()
|
||||
* - timeout: time to wait for reply in ms
|
||||
* - desc: if set, memory area to be used for desc.
|
||||
* Care must be taken to leave room for variable-length array.
|
||||
* - do_free: returns bool that specify if the caller should free
|
||||
* its memory on error (e.g. if ikc_send failed in the first place,
|
||||
* the reply has no chance of coming and memory should be free)
|
||||
* Always true on success.
|
||||
* - free_addrs_count & ...: addresses to kmalloc'd pointers that
|
||||
* are referenced in the message and must be left intact if we
|
||||
* abort to timeout/signal.
|
||||
*/
|
||||
int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp,
|
||||
long int timeout, struct mcctrl_wakeup_desc *desc,
|
||||
int *do_frees, int free_addrs_count, ...);
|
||||
|
||||
ihk_os_t osnum_to_os(int n);
|
||||
|
||||
/* syscall.c */
|
||||
|
||||
@ -597,14 +597,9 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
|
||||
case SCD_MSG_PREPARE_PROCESS:
|
||||
|
||||
if((rc = process_msg_prepare_process(packet->arg)) == 0){
|
||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_ACKED;
|
||||
pckt.err = 0;
|
||||
}
|
||||
else{
|
||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_NACKED;
|
||||
pckt.err = rc;
|
||||
}
|
||||
pckt.err = process_msg_prepare_process(packet->arg);
|
||||
pckt.msg = SCD_MSG_PREPARE_PROCESS_ACKED;
|
||||
pckt.reply = packet->reply;
|
||||
pckt.ref = packet->ref;
|
||||
pckt.arg = packet->arg;
|
||||
syscall_channel_send(resp_channel, &pckt);
|
||||
@ -660,10 +655,11 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
memcpy(&info, sp, sizeof(struct mcctrl_signal));
|
||||
ihk_mc_unmap_virtual(sp, 1, 0);
|
||||
ihk_mc_unmap_memory(NULL, pp, sizeof(struct mcctrl_signal));
|
||||
pckt.msg = SCD_MSG_SEND_SIGNAL;
|
||||
pckt.msg = SCD_MSG_SEND_SIGNAL_ACK;
|
||||
pckt.err = 0;
|
||||
pckt.ref = packet->ref;
|
||||
pckt.arg = packet->arg;
|
||||
pckt.reply = packet->reply;
|
||||
syscall_channel_send(resp_channel, &pckt);
|
||||
|
||||
rc = do_kill(NULL, info.pid, info.tid, info.sig, &info.info, 0);
|
||||
@ -736,6 +732,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
||||
pckt.msg = SCD_MSG_PERF_ACK;
|
||||
pckt.err = 0;
|
||||
pckt.arg = packet->arg;
|
||||
pckt.reply = packet->reply;
|
||||
ihk_ikc_send(resp_channel, &pckt, 0);
|
||||
|
||||
ret = 0;
|
||||
|
||||
@ -34,7 +34,7 @@ void *__kmalloc(int size, ihk_mc_ap_flag flag);
|
||||
void __kfree(void *ptr);
|
||||
|
||||
int _memcheck(void *ptr, char *msg, char *file, int line, int free);
|
||||
int memcheckall();
|
||||
int memcheckall(void);
|
||||
int freecheck(int runcount);
|
||||
void kmalloc_consolidate_free_list(void);
|
||||
|
||||
|
||||
@ -825,8 +825,8 @@ struct process *find_process(int pid, struct mcs_rwlock_node_irqsave *lock);
|
||||
void process_unlock(struct process *proc, struct mcs_rwlock_node_irqsave *lock);
|
||||
void chain_process(struct process *);
|
||||
void chain_thread(struct thread *);
|
||||
void proc_init();
|
||||
void set_timer();
|
||||
void proc_init(void);
|
||||
void set_timer(void);
|
||||
struct sig_pending *hassigpending(struct thread *thread);
|
||||
|
||||
#endif
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
|
||||
#define SCD_MSG_PREPARE_PROCESS 0x1
|
||||
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
|
||||
#define SCD_MSG_PREPARE_PROCESS_NACKED 0x7
|
||||
#define SCD_MSG_SCHEDULE_PROCESS 0x3
|
||||
#define SCD_MSG_WAKE_UP_SYSCALL_THREAD 0x14
|
||||
|
||||
@ -38,8 +37,9 @@
|
||||
#define SCD_MSG_INIT_CHANNEL_ACKED 0x6
|
||||
|
||||
#define SCD_MSG_SYSCALL_ONESIDE 0x4
|
||||
#define SCD_MSG_SEND_SIGNAL 0x8
|
||||
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
||||
#define SCD_MSG_SEND_SIGNAL 0x7
|
||||
#define SCD_MSG_SEND_SIGNAL_ACK 0x8
|
||||
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
||||
#define SCD_MSG_GET_VDSO_INFO 0xa
|
||||
|
||||
#define SCD_MSG_GET_CPU_MAPPING 0xc
|
||||
@ -168,10 +168,8 @@ typedef unsigned long __cpu_set_unit;
|
||||
|
||||
struct program_load_desc {
|
||||
int num_sections;
|
||||
int status;
|
||||
int cpu;
|
||||
int pid;
|
||||
int err;
|
||||
int stack_prot;
|
||||
int pgid;
|
||||
int cred[8];
|
||||
@ -241,6 +239,7 @@ enum mcctrl_os_cpu_operation {
|
||||
struct ikc_scd_packet {
|
||||
int msg;
|
||||
int err;
|
||||
void *reply;
|
||||
union {
|
||||
/* for traditional SCD_MSG_* */
|
||||
struct {
|
||||
@ -276,7 +275,7 @@ struct ikc_scd_packet {
|
||||
int eventfd_type;
|
||||
};
|
||||
};
|
||||
char padding[12];
|
||||
char padding[8];
|
||||
};
|
||||
|
||||
#define IHK_SCD_REQ_THREAD_SPINNING 0
|
||||
@ -340,7 +339,7 @@ struct syscall_post {
|
||||
#define SYSCALL_FOOTER return do_syscall(&request, ihk_mc_get_processor_id(), 0)
|
||||
|
||||
extern long do_syscall(struct syscall_request *req, int cpu, int pid);
|
||||
extern int obtain_clone_cpuid();
|
||||
int obtain_clone_cpuid(cpu_set_t *cpu_set);
|
||||
extern long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx);
|
||||
|
||||
#define DECLARATOR(number,name) __NR_##name = number,
|
||||
@ -458,7 +457,7 @@ static inline unsigned long timespec_to_jiffy(const struct timespec *ats)
|
||||
return ats->tv_sec * 100 + ats->tv_nsec / 10000000;
|
||||
}
|
||||
|
||||
void reset_cputime();
|
||||
void reset_cputime(void);
|
||||
void set_cputime(int mode);
|
||||
int do_munmap(void *addr, size_t len);
|
||||
intptr_t do_mmap(intptr_t addr0, size_t len0, int prot, int flags, int fd,
|
||||
@ -520,7 +519,6 @@ enum perf_ctrl_type {
|
||||
|
||||
struct perf_ctrl_desc {
|
||||
enum perf_ctrl_type ctrl_type;
|
||||
int status;
|
||||
union {
|
||||
/* for SET, GET */
|
||||
struct {
|
||||
|
||||
@ -1746,11 +1746,16 @@ static void rusage_init()
|
||||
{
|
||||
int npages;
|
||||
unsigned long phys;
|
||||
const struct ihk_mc_cpu_info *cpu_info = ihk_mc_get_cpu_info();
|
||||
|
||||
if (!cpu_info) {
|
||||
panic("rusage_init: PANIC: ihk_mc_get_cpu_info returned NULL");
|
||||
}
|
||||
|
||||
npages = (sizeof(struct rusage_global) + PAGE_SIZE -1) >> PAGE_SHIFT;
|
||||
rusage = ihk_mc_alloc_pages(npages, IHK_MC_AP_CRITICAL);
|
||||
memset(rusage, 0, npages * PAGE_SIZE);
|
||||
rusage->num_processors = num_processors;
|
||||
rusage->num_processors = cpu_info->ncpus;
|
||||
rusage->num_numa_nodes = ihk_mc_get_nr_numa_nodes();
|
||||
rusage->ns_per_tsc = ihk_mc_get_ns_per_tsc();
|
||||
phys = virt_to_phys(rusage);
|
||||
|
||||
@ -369,6 +369,7 @@ void process_procfs_request(struct ikc_scd_packet *rpacket)
|
||||
0UL,
|
||||
0UL,
|
||||
0,
|
||||
range->memobj && range->memobj->path ? range->memobj->path :
|
||||
range->start ==
|
||||
(unsigned long)vm->vdso_addr ? "[vdso]" :
|
||||
range->start ==
|
||||
|
||||
@ -2135,6 +2135,9 @@ static void munmap_all(void)
|
||||
/* free vm_ranges which do_munmap() failed to remove. */
|
||||
free_process_memory_ranges(thread->vm);
|
||||
|
||||
/* reset vm_region's map area */
|
||||
thread->vm->region.map_end = thread->vm->region.map_start;
|
||||
|
||||
return;
|
||||
} /* munmap_all() */
|
||||
|
||||
@ -2237,21 +2240,22 @@ SYSCALL_DECLARE(execve)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cpu_local_var(current)->proc->ptrace) {
|
||||
if (thread->proc->ptrace) {
|
||||
ihk_mc_syscall_ret(ctx) = 0;
|
||||
ptrace_syscall_event(cpu_local_var(current));
|
||||
ptrace_syscall_event(thread);
|
||||
}
|
||||
|
||||
/* Unmap all memory areas of the process, userspace will be gone */
|
||||
munmap_all();
|
||||
|
||||
ihk_mc_init_user_process(&cpu_local_var(current)->ctx,
|
||||
&cpu_local_var(current)->uctx,
|
||||
((char *)cpu_local_var(current)) +
|
||||
/* Code assumes no process switch from here on */
|
||||
preempt_disable();
|
||||
ihk_mc_init_user_process(&thread->ctx, &thread->uctx,
|
||||
((char *)thread) +
|
||||
KERNEL_STACK_NR_PAGES * PAGE_SIZE, desc->entry, 0);
|
||||
|
||||
/* Create virtual memory ranges and update args/envs */
|
||||
if (prepare_process_ranges_args_envs(cpu_local_var(current), desc, desc,
|
||||
if (prepare_process_ranges_args_envs(thread, desc, desc,
|
||||
PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_FOR_USER,
|
||||
argv_flat, argv_flat_len, envp_flat, envp_flat_len) != 0) {
|
||||
kprintf("execve(): PANIC: preparing ranges, args, envs, stack\n");
|
||||
@ -2286,7 +2290,7 @@ SYSCALL_DECLARE(execve)
|
||||
clear_fp_regs(thread);
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_19 */
|
||||
|
||||
error = ptrace_report_exec(cpu_local_var(current));
|
||||
error = ptrace_report_exec(thread);
|
||||
if(error) {
|
||||
kprintf("execve(): ERROR: ptrace_report_exec()\n");
|
||||
}
|
||||
@ -2309,10 +2313,16 @@ end:
|
||||
/* Lock run queue because enter_user_mode expects to release it */
|
||||
cpu_local_var(runq_irqstate) =
|
||||
ihk_mc_spinlock_lock(&(get_this_cpu_local_var()->runq_lock));
|
||||
preempt_enable();
|
||||
|
||||
ihk_mc_switch_context(NULL, &cpu_local_var(current)->ctx,
|
||||
cpu_local_var(current));
|
||||
ihk_mc_switch_context(NULL, &thread->ctx, thread);
|
||||
|
||||
/* not reached */
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* no preempt_enable, errors can only happen before we disabled it */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2467,7 +2477,7 @@ retry_tid:
|
||||
|
||||
/* TODO: clean-up new */
|
||||
release_cpuid(cpuid);
|
||||
return -EFAULT;
|
||||
return newproc->pid;
|
||||
}
|
||||
|
||||
/* In a single threaded process TID equals to PID */
|
||||
@ -6786,22 +6796,14 @@ SYSCALL_DECLARE(sched_getaffinity)
|
||||
int ret;
|
||||
|
||||
dkprintf("%s() len: %d, mask: %p\n", __FUNCTION__, len, u_cpu_set);
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_5 /* sched_getaffinity arguments check add (S64FX_10) */
|
||||
if (len * 8 < num_processors) {
|
||||
kprintf("%s:%d Too small buffer.\n", __FILE__, __LINE__);
|
||||
dkprintf("%s: Too small buffer.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (len & (sizeof(unsigned long)-1)) {
|
||||
kprintf("%s:%d Size not align to unsigned long.\n", __FILE__, __LINE__);
|
||||
dkprintf("%s: Size not align to unsigned long.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_5 */
|
||||
if (!len || u_cpu_set == (cpu_set_t *)-1)
|
||||
return -EINVAL;
|
||||
|
||||
if ((len * BITS_PER_BYTE) < __CPU_SETSIZE)
|
||||
return -EINVAL;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_5 */
|
||||
|
||||
len = MIN2(len, sizeof(k_cpu_set));
|
||||
|
||||
@ -6836,11 +6838,8 @@ SYSCALL_DECLARE(sched_getaffinity)
|
||||
}
|
||||
|
||||
dkprintf("%s() len: %d, ret: %d\n", __FUNCTION__, len, ret);
|
||||
#ifdef POSTK_DEBUG_TEMP_FIX_58 /* sched_getafifnity return value fix */
|
||||
|
||||
return ret;
|
||||
#else /* POSTK_DEBUG_TEMP_FIX_58 */
|
||||
return len;
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_58 */
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(get_cpu_id)
|
||||
@ -7705,8 +7704,8 @@ SYSCALL_DECLARE(mremap)
|
||||
const size_t newsize0 = ihk_mc_syscall_arg2(ctx);
|
||||
const int flags = ihk_mc_syscall_arg3(ctx);
|
||||
const uintptr_t newaddr = ihk_mc_syscall_arg4(ctx);
|
||||
const ssize_t oldsize = (oldsize0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
const ssize_t newsize = (newsize0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
const size_t oldsize = (oldsize0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
const size_t newsize = (newsize0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
const uintptr_t oldstart = oldaddr;
|
||||
const uintptr_t oldend = oldstart + oldsize;
|
||||
struct thread *thread = cpu_local_var(current);
|
||||
@ -7725,9 +7724,9 @@ SYSCALL_DECLARE(mremap)
|
||||
oldaddr, oldsize0, newsize0, flags, newaddr);
|
||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||
|
||||
/* check arguments */
|
||||
if ((oldaddr & ~PAGE_MASK)
|
||||
|| (oldsize < 0)
|
||||
|| (newsize <= 0)
|
||||
|| (newsize == 0)
|
||||
|| (flags & ~(MREMAP_MAYMOVE | MREMAP_FIXED))
|
||||
|| ((flags & MREMAP_FIXED)
|
||||
&& !(flags & MREMAP_MAYMOVE))
|
||||
@ -7740,6 +7739,24 @@ SYSCALL_DECLARE(mremap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (oldend < oldstart) {
|
||||
error = -EINVAL;
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"old range overflow. %d\n",
|
||||
oldaddr, oldsize0, newsize0,
|
||||
flags, newaddr, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (newsize > (vm->region.user_end - vm->region.user_start)) {
|
||||
error = -ENOMEM;
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"cannot allocate. %d\n",
|
||||
oldaddr, oldsize0, newsize0,
|
||||
flags, newaddr, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check original mapping */
|
||||
range = lookup_process_memory_range(vm, oldstart, oldstart+PAGE_SIZE);
|
||||
if (!range || (oldstart < range->start) || (range->end < oldend)
|
||||
@ -7754,15 +7771,6 @@ SYSCALL_DECLARE(mremap)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (oldend < oldstart) {
|
||||
error = -EINVAL;
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"old range overflow. %d\n",
|
||||
oldaddr, oldsize0, newsize0, flags, newaddr,
|
||||
error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* determine new mapping range */
|
||||
need_relocate = 0;
|
||||
if (flags & MREMAP_FIXED) {
|
||||
|
||||
@ -60,9 +60,9 @@ void ihk_mc_boot_cpu(int cpuid, unsigned long pc);
|
||||
int ihk_mc_get_processor_id(void);
|
||||
int ihk_mc_get_hardware_processor_id(void);
|
||||
int ihk_mc_get_numa_id(void);
|
||||
int ihk_mc_get_nr_cores();
|
||||
int ihk_mc_get_nr_linux_cores();
|
||||
int ihk_mc_get_osnum();
|
||||
int ihk_mc_get_nr_cores(void);
|
||||
int ihk_mc_get_nr_linux_cores(void);
|
||||
int ihk_mc_get_osnum(void);
|
||||
int ihk_mc_get_core(int id, unsigned long *linux_core_id, unsigned long *apic_id,
|
||||
int *numa_id);
|
||||
int ihk_mc_get_ikc_cpu(int id);
|
||||
@ -78,7 +78,7 @@ void ihk_mc_init_context(ihk_mc_kernel_context_t *new_ctx,
|
||||
void (*next_function)(void));
|
||||
|
||||
int ihk_mc_get_extra_reg_id(unsigned long hw_config, unsigned long hw_config_ext);
|
||||
unsigned int ihk_mc_get_nr_extra_regs();
|
||||
unsigned int ihk_mc_get_nr_extra_regs(void);
|
||||
int ihk_mc_get_extra_reg_idx(int id);
|
||||
unsigned int ihk_mc_get_extra_reg_msr(int id);
|
||||
unsigned long ihk_mc_get_extra_reg_event(int id);
|
||||
|
||||
@ -224,7 +224,7 @@ void remote_flush_tlb_array_cpumask(struct process_vm *vm,
|
||||
int cpu_id);
|
||||
|
||||
int ihk_get_kmsg_buf(unsigned long *addr, unsigned long *size);
|
||||
char *ihk_get_kargs();
|
||||
char *ihk_get_kargs(void);
|
||||
|
||||
int ihk_set_monitor(unsigned long addr, unsigned long size);
|
||||
int ihk_set_rusage(unsigned long addr, unsigned long size);
|
||||
|
||||
152
test/840/C840.sh
152
test/840/C840.sh
@ -1,152 +0,0 @@
|
||||
#!/bin/sh
|
||||
if ! sudo ls /sys/kernel/debug | grep kmemleak > /dev/null 2>&1; then
|
||||
echo kmemleak: not found >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 'C840T01... '
|
||||
ng=0
|
||||
sync
|
||||
sudo /sbin/sysctl vm.drop_caches=3 > /dev/null 2>&1
|
||||
./ihkosctl 0 clear_kmsg
|
||||
sudo dmesg -c > /dev/null
|
||||
sudo sh -c 'echo clear > /sys/kernel/debug/kmemleak'
|
||||
./mcexec ./C840T01
|
||||
if [ `sudo cat /sys/kernel/debug/kmemleak | wc -l` != 0 ]; then
|
||||
echo 'C840T01: NG (kmemleak)'
|
||||
ng=1
|
||||
fi
|
||||
if ! dmesg | grep 'remote_page_fault:interrupted. -512' > /dev/null 2>&1; then
|
||||
echo 'C840T01: WARN (remote_page_fault)'
|
||||
ng=1
|
||||
fi
|
||||
if ! ./ihkosctl 0 kmsg | grep 'is dead, terminate()' > /dev/null 2>&1; then
|
||||
echo 'C840T01: WARN (syscall offloading)'
|
||||
ng=1
|
||||
fi
|
||||
if [ $ng = 0 ]; then
|
||||
echo C840T01: OK
|
||||
fi
|
||||
|
||||
echo 'C840T02... '
|
||||
ng=0
|
||||
sync
|
||||
sudo /sbin/sysctl vm.drop_caches=3 > /dev/null 2>&1
|
||||
./ihkosctl 0 clear_kmsg
|
||||
sudo dmesg -c > /dev/null
|
||||
sudo sh -c 'echo clear > /sys/kernel/debug/kmemleak'
|
||||
./mcexec ./C840T02
|
||||
if [ `sudo cat /sys/kernel/debug/kmemleak | wc -l` != 0 ]; then
|
||||
echo 'C840T02: NG (kmemleak)'
|
||||
ng=1
|
||||
fi
|
||||
if dmesg | grep 'remote_page_fault:interrupted. -512' > /dev/null 2>&1; then
|
||||
echo 'C840T02: WARN (remote_page_fault)'
|
||||
ng=1
|
||||
fi
|
||||
if ! ./ihkosctl 0 kmsg | grep 'is dead, terminate()' > /dev/null 2>&1; then
|
||||
echo 'C840T02: WARN (syscall offloading)'
|
||||
ng=1
|
||||
fi
|
||||
if [ $ng = 0 ]; then
|
||||
echo C840T02: OK
|
||||
fi
|
||||
|
||||
echo 'C840T03... '
|
||||
ng=0
|
||||
sync
|
||||
sudo /sbin/sysctl vm.drop_caches=3 > /dev/null 2>&1
|
||||
./ihkosctl 0 clear_kmsg
|
||||
sudo dmesg -c > /dev/null
|
||||
sudo sh -c 'echo clear > /sys/kernel/debug/kmemleak'
|
||||
./mcexec ./C840T03
|
||||
if [ `sudo cat /sys/kernel/debug/kmemleak | wc -l` != 0 ]; then
|
||||
echo 'C840T03: NG (kmemleak)'
|
||||
ng=1
|
||||
fi
|
||||
if dmesg | grep 'remote_page_fault:interrupted. -512' > /dev/null 2>&1; then
|
||||
echo 'C840T03: WARN (remote_page_fault)'
|
||||
ng=1
|
||||
fi
|
||||
if ./ihkosctl 0 kmsg | grep 'is dead, terminate()' > /dev/null 2>&1; then
|
||||
echo 'C840T03: WARN (syscall offloading)'
|
||||
ng=1
|
||||
fi
|
||||
if [ $ng = 0 ]; then
|
||||
echo C840T03: OK
|
||||
fi
|
||||
|
||||
echo 'C840T04... '
|
||||
ng=0
|
||||
sync
|
||||
sudo /sbin/sysctl vm.drop_caches=3 > /dev/null 2>&1
|
||||
./ihkosctl 0 clear_kmsg
|
||||
sudo dmesg -c > /dev/null
|
||||
sudo sh -c 'echo clear > /sys/kernel/debug/kmemleak'
|
||||
timeout -s 9 2 ./mcexec ./C840T04
|
||||
sleep 2
|
||||
if [ `sudo cat /sys/kernel/debug/kmemleak | wc -l` != 0 ]; then
|
||||
echo 'C840T04: NG (kmemleak)'
|
||||
ng=1
|
||||
fi
|
||||
if ! dmesg | grep 'remote_page_fault:interrupted. -512' > /dev/null 2>&1; then
|
||||
echo 'C840T04: WARN (remote_page_fault)'
|
||||
ng=1
|
||||
fi
|
||||
if ! ./ihkosctl 0 kmsg | grep 'is dead, terminate()' > /dev/null 2>&1; then
|
||||
echo 'C840T04: WARN (syscall offloading)'
|
||||
ng=1
|
||||
fi
|
||||
if [ $ng = 0 ]; then
|
||||
echo C840T04: OK
|
||||
fi
|
||||
|
||||
echo 'C840T05... '
|
||||
ng=0
|
||||
sync
|
||||
sudo /sbin/sysctl vm.drop_caches=3 > /dev/null 2>&1
|
||||
./ihkosctl 0 clear_kmsg
|
||||
sudo dmesg -c > /dev/null
|
||||
sudo sh -c 'echo clear > /sys/kernel/debug/kmemleak'
|
||||
timeout -s 9 2 ./mcexec ./C840T05
|
||||
sleep 2
|
||||
if [ `sudo cat /sys/kernel/debug/kmemleak | wc -l` != 0 ]; then
|
||||
echo 'C840T05: NG (kmemleak)'
|
||||
ng=1
|
||||
fi
|
||||
if dmesg | grep 'remote_page_fault:interrupted. -512' > /dev/null 2>&1; then
|
||||
echo 'C840T05: WARN (remote_page_fault)'
|
||||
ng=1
|
||||
fi
|
||||
if ! ./ihkosctl 0 kmsg | grep 'is dead, terminate()' > /dev/null 2>&1; then
|
||||
echo 'C840T05: WARN (syscall offloading)'
|
||||
ng=1
|
||||
fi
|
||||
if [ $ng = 0 ]; then
|
||||
echo C840T05: OK
|
||||
fi
|
||||
|
||||
echo 'C840T06... '
|
||||
ng=0
|
||||
sync
|
||||
sudo /sbin/sysctl vm.drop_caches=3 > /dev/null 2>&1
|
||||
./ihkosctl 0 clear_kmsg
|
||||
sudo dmesg -c > /dev/null
|
||||
sudo sh -c 'echo clear > /sys/kernel/debug/kmemleak'
|
||||
timeout -s 9 2 ./mcexec ./C840T06
|
||||
sleep 2
|
||||
if [ `sudo cat /sys/kernel/debug/kmemleak | wc -l` != 0 ]; then
|
||||
echo 'C840T06: NG (kmemleak)'
|
||||
ng=1
|
||||
fi
|
||||
if dmesg | grep 'remote_page_fault:interrupted. -512' > /dev/null 2>&1; then
|
||||
echo 'C840T06: WARN (remote_page_fault)'
|
||||
ng=1
|
||||
fi
|
||||
if ./ihkosctl 0 kmsg | grep 'is dead, terminate()' > /dev/null 2>&1; then
|
||||
echo 'C840T06: WARN (syscall offloading)'
|
||||
ng=1
|
||||
fi
|
||||
if [ $ng = 0 ]; then
|
||||
echo C840T06: OK
|
||||
fi
|
||||
@ -1,28 +0,0 @@
|
||||
スクリプトは Wed Jun 6 14:38:21 2018
|
||||
に開始しました[?1034hbash-4.2$ sh C840.sh
|
||||
C840T01...
|
||||
Terminate by signal 9
|
||||
C840.sh: 14 行: 22464 強制終了 ./mcexec ./C840T01
|
||||
C840T01: OK
|
||||
C840T02...
|
||||
Terminate by signal 9
|
||||
C840.sh: 38 行: 22500 強制終了 ./mcexec ./C840T02
|
||||
C840T02: OK
|
||||
C840T03...
|
||||
Terminate by signal 9
|
||||
C840.sh: 62 行: 22535 強制終了 ./mcexec ./C840T03
|
||||
C840T03: OK
|
||||
C840T04...
|
||||
C840.sh: 86 行: 22570 強制終了 timeout -s 9 2 ./mcexec ./C840T04
|
||||
C840T04: OK
|
||||
C840T05...
|
||||
C840.sh: 111 行: 22598 強制終了 timeout -s 9 2 ./mcexec ./C840T05
|
||||
C840T05: OK
|
||||
C840T06...
|
||||
C840.sh: 136 行: 22626 強制終了 timeout -s 9 2 ./mcexec ./C840T06
|
||||
C840T06: OK
|
||||
bash-4.2$ exit
|
||||
exit
|
||||
|
||||
スクリプトは Wed Jun 6 14:38:51 2018
|
||||
に終了しました
|
||||
@ -1,46 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int fd;
|
||||
void *p;
|
||||
long l;
|
||||
pid_t pid;
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
sleep(1);
|
||||
kill(getppid(), SIGKILL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fd = open("rpf.data", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("open(rpf.data)");
|
||||
exit(1);
|
||||
}
|
||||
p = mmap(NULL, 512*1024*1024, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (p == (void *)-1) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
fd = open("rpf.out", O_WRONLY|O_CREAT|O_TRUNC, 0600);
|
||||
if (fd == -1) {
|
||||
perror("open(fpt.out)");
|
||||
exit(1);
|
||||
}
|
||||
l = write(fd, p, 512*1024*1024);
|
||||
printf("write=%ld\n", l);
|
||||
close(fd);
|
||||
munmap(p, 512*1024*1024);
|
||||
exit(0);
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
pid_t pid;
|
||||
int pfd[2];
|
||||
char c;
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
sleep(1);
|
||||
kill(getppid(), SIGKILL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pipe(pfd);
|
||||
read(pfd[0], &c, 1);
|
||||
exit(0);
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
sleep(1);
|
||||
kill(getppid(), SIGKILL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
for(;;);
|
||||
exit(0);
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int fd;
|
||||
void *p;
|
||||
long l;
|
||||
|
||||
fd = open("rpf.data", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("open(rpf.data)");
|
||||
exit(1);
|
||||
}
|
||||
p = mmap(NULL, 512*1024*1024, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (p == (void *)-1) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
fd = open("rpf.out", O_WRONLY|O_CREAT|O_TRUNC, 0600);
|
||||
if (fd == -1) {
|
||||
perror("open(fpt.out)");
|
||||
exit(1);
|
||||
}
|
||||
l = write(fd, p, 512*1024*1024);
|
||||
printf("write=%ld\n", l);
|
||||
close(fd);
|
||||
munmap(p, 512*1024*1024);
|
||||
exit(0);
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int pfd[2];
|
||||
char c;
|
||||
|
||||
pipe(pfd);
|
||||
read(pfd[0], &c, 1);
|
||||
exit(0);
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
for(;;);
|
||||
exit(0);
|
||||
}
|
||||
587
test/926/C926.c
587
test/926/C926.c
@ -1,587 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
pid_t pid1;
|
||||
pid_t pid2;
|
||||
pid_t pid3;
|
||||
int st;
|
||||
int p[2];
|
||||
int shmid;
|
||||
int *sp;
|
||||
key_t key;
|
||||
int valid1;
|
||||
int valid2;
|
||||
int valid3;
|
||||
char c;
|
||||
int result;
|
||||
struct shmid_ds buf;
|
||||
|
||||
key = ftok(argv[0], 0);
|
||||
|
||||
printf("C926T01... ");
|
||||
fflush(stdout);
|
||||
valid1 = 1;
|
||||
valid2 = 2;
|
||||
valid3 = 2;
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pid1 = fork()) == 0) {
|
||||
close(p[0]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 0
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
*sp = 1;
|
||||
// step 1
|
||||
st = *sp == valid1? 1: 0;
|
||||
shmdt(sp);
|
||||
write(p[1], &c, 1);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
if ((pid2 = fork()) == 0) {
|
||||
close(p[1]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 2
|
||||
read(p[0], &c, 1);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
(*sp)++;
|
||||
// step 3
|
||||
st = *sp == valid2? 1: 0;
|
||||
shmdt(sp);
|
||||
// step 4
|
||||
exit(st);
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
result = 0;
|
||||
waitpid(pid1, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
waitpid(pid2, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if ((pid3 = fork()) == 0) {
|
||||
// step 5
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
st = *sp == valid3? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
waitpid(pid3, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if (result == 3) {
|
||||
printf("OK\n");
|
||||
}
|
||||
else {
|
||||
printf("NG\n");
|
||||
}
|
||||
|
||||
printf("C926T02... ");
|
||||
fflush(stdout);
|
||||
valid1 = 1;
|
||||
valid2 = 2;
|
||||
valid3 = 2;
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pid1 = fork()) == 0) {
|
||||
close(p[0]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 0
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
*sp = 1;
|
||||
// step 1
|
||||
st = *sp == valid1? 1: 0;
|
||||
exit(st);
|
||||
}
|
||||
|
||||
if ((pid2 = fork()) == 0) {
|
||||
close(p[1]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 2
|
||||
read(p[0], &c, 1);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
(*sp)++;
|
||||
// step 3
|
||||
st = *sp == valid2? 1: 0;
|
||||
shmdt(sp);
|
||||
// step 4
|
||||
exit(st);
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
result = 0;
|
||||
waitpid(pid1, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
waitpid(pid2, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if ((pid3 = fork()) == 0) {
|
||||
// step 5
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
st = *sp == valid3? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
waitpid(pid3, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if (result == 3) {
|
||||
printf("OK\n");
|
||||
}
|
||||
else {
|
||||
printf("NG\n");
|
||||
}
|
||||
|
||||
printf("C926T03... ");
|
||||
fflush(stdout);
|
||||
valid1 = 1;
|
||||
valid2 = 1;
|
||||
valid3 = 1;
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pid1 = fork()) == 0) {
|
||||
close(p[0]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 0
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
*sp = 1;
|
||||
// step 1
|
||||
shmctl(shmid, IPC_RMID, &buf);
|
||||
write(p[1], &c, 1);
|
||||
|
||||
// step3
|
||||
read(p[1], &c, 1);
|
||||
st = *sp == valid1? 1: 0;
|
||||
shmdt(sp);
|
||||
write(p[1], &c, 1);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
if ((pid2 = fork()) == 0) {
|
||||
close(p[1]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 2
|
||||
read(p[0], &c, 1);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
(*sp)++;
|
||||
write(p[0], &c, 1);
|
||||
// step 4
|
||||
read(p[0], &c, 1);
|
||||
st = *sp == valid2? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
result = 0;
|
||||
waitpid(pid1, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
waitpid(pid2, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if ((pid3 = fork()) == 0) {
|
||||
// step 5
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
st = *sp == valid3? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
waitpid(pid3, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if (result == 3) {
|
||||
printf("OK\n");
|
||||
}
|
||||
else {
|
||||
printf("NG\n");
|
||||
}
|
||||
|
||||
printf("C926T04... ");
|
||||
fflush(stdout);
|
||||
valid1 = 1;
|
||||
valid2 = 1;
|
||||
valid3 = 1;
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pid1 = fork()) == 0) {
|
||||
close(p[0]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 0
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
*sp = 1;
|
||||
// step 1
|
||||
shmctl(shmid, IPC_RMID, &buf);
|
||||
write(p[1], &c, 1);
|
||||
|
||||
// step4
|
||||
read(p[1], &c, 1);
|
||||
st = *sp == valid1? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
if ((pid2 = fork()) == 0) {
|
||||
close(p[1]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 2
|
||||
read(p[0], &c, 1);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
(*sp)++;
|
||||
// step 3
|
||||
st = *sp == valid2? 1: 0;
|
||||
shmdt(sp);
|
||||
write(p[0], &c, 1);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
result = 0;
|
||||
waitpid(pid1, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
waitpid(pid2, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if ((pid3 = fork()) == 0) {
|
||||
// step 5
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
st = *sp == valid3? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
waitpid(pid3, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if (result == 3) {
|
||||
printf("OK\n");
|
||||
}
|
||||
else {
|
||||
printf("NG\n");
|
||||
}
|
||||
|
||||
printf("C926T05... ");
|
||||
fflush(stdout);
|
||||
valid1 = 1;
|
||||
valid2 = 1;
|
||||
valid3 = 1;
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pid1 = fork()) == 0) {
|
||||
close(p[0]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 0
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
*sp = 1;
|
||||
// step 1
|
||||
shmctl(shmid, IPC_RMID, &buf);
|
||||
// step2
|
||||
st = *sp == valid1? 1: 0;
|
||||
shmdt(sp);
|
||||
write(p[1], &c, 1);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
if ((pid2 = fork()) == 0) {
|
||||
close(p[1]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 3
|
||||
read(p[0], &c, 1);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
(*sp)++;
|
||||
// step 4
|
||||
st = *sp == valid2? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
result = 0;
|
||||
waitpid(pid1, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
waitpid(pid2, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if ((pid3 = fork()) == 0) {
|
||||
// step 5
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
st = *sp == valid3? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
waitpid(pid3, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if (result == 3) {
|
||||
printf("OK\n");
|
||||
}
|
||||
else {
|
||||
printf("NG\n");
|
||||
}
|
||||
|
||||
printf("C926T06... ");
|
||||
fflush(stdout);
|
||||
valid1 = 1;
|
||||
valid2 = 1;
|
||||
valid3 = 1;
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pid1 = fork()) == 0) {
|
||||
close(p[0]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 0
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
*sp = 1;
|
||||
// step 1
|
||||
shmctl(shmid, IPC_RMID, &buf);
|
||||
// step2
|
||||
st = *sp == valid1? 1: 0;
|
||||
exit(st);
|
||||
}
|
||||
|
||||
if ((pid2 = fork()) == 0) {
|
||||
close(p[1]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 3
|
||||
read(p[0], &c, 1);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
(*sp)++;
|
||||
// step 4
|
||||
st = *sp == valid2? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
result = 0;
|
||||
waitpid(pid1, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
waitpid(pid2, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if ((pid3 = fork()) == 0) {
|
||||
// step 5
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
st = *sp == valid3? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
waitpid(pid3, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if (result == 3) {
|
||||
printf("OK\n");
|
||||
}
|
||||
else {
|
||||
printf("NG\n");
|
||||
}
|
||||
|
||||
printf("C926T07... ");
|
||||
fflush(stdout);
|
||||
valid1 = 2;
|
||||
valid2 = 2;
|
||||
valid3 = 0;
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pid1 = fork()) == 0) {
|
||||
close(p[0]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 0
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
*sp = 1;
|
||||
write(p[1], &c, 1);
|
||||
// step 2
|
||||
read(p[1], &c, 1);
|
||||
shmctl(shmid, IPC_RMID, &buf);
|
||||
// step2
|
||||
st = *sp == valid1? 1: 0;
|
||||
exit(st);
|
||||
}
|
||||
|
||||
if ((pid2 = fork()) == 0) {
|
||||
close(p[1]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 1
|
||||
read(p[0], &c, 1);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
(*sp)++;
|
||||
write(p[0], &c, 1);
|
||||
// step 3
|
||||
read(p[0], &c, 1);
|
||||
st = *sp == valid2? 1: 0;
|
||||
shmdt(sp);
|
||||
// step 4
|
||||
exit(st);
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
result = 0;
|
||||
waitpid(pid1, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
waitpid(pid2, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if ((pid3 = fork()) == 0) {
|
||||
// step 5
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
st = *sp == valid3? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
waitpid(pid3, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if (result == 3) {
|
||||
printf("OK\n");
|
||||
}
|
||||
else {
|
||||
printf("NG\n");
|
||||
}
|
||||
|
||||
printf("C926T08... ");
|
||||
fflush(stdout);
|
||||
valid1 = 2;
|
||||
valid2 = 2;
|
||||
valid3 = 2;
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((pid1 = fork()) == 0) {
|
||||
close(p[0]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 0
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
*sp = 1;
|
||||
write(p[1], &c, 1);
|
||||
// step 2
|
||||
read(p[1], &c, 1);
|
||||
// step2
|
||||
st = *sp == valid1? 1: 0;
|
||||
exit(st);
|
||||
}
|
||||
|
||||
if ((pid2 = fork()) == 0) {
|
||||
close(p[1]);
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
// step 1
|
||||
read(p[0], &c, 1);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
(*sp)++;
|
||||
write(p[0], &c, 1);
|
||||
// step 3
|
||||
read(p[0], &c, 1);
|
||||
st = *sp == valid2? 1: 0;
|
||||
shmdt(sp);
|
||||
// step 4
|
||||
exit(st);
|
||||
}
|
||||
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
result = 0;
|
||||
waitpid(pid1, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
waitpid(pid2, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if ((pid3 = fork()) == 0) {
|
||||
// step 5
|
||||
shmid = shmget(key, 4096, IPC_CREAT | 0660);
|
||||
sp = shmat(shmid, NULL, 0);
|
||||
st = *sp == valid3? 1: 0;
|
||||
shmdt(sp);
|
||||
exit(st);
|
||||
}
|
||||
|
||||
waitpid(pid3, &st, 0);
|
||||
if (WIFEXITED(st))
|
||||
result += WEXITSTATUS(st);
|
||||
|
||||
if (result == 3) {
|
||||
printf("OK\n");
|
||||
}
|
||||
else {
|
||||
printf("NG\n");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
スクリプトは Wed Jun 6 14:39:24 2018
|
||||
に開始しました[?1034hbash-4.2$ ./mcexec C[K./C926
|
||||
C926T01... OK
|
||||
C926T02... OK
|
||||
C926T03... OK
|
||||
C926T04... OK
|
||||
C926T05... OK
|
||||
C926T06... OK
|
||||
C926T07... OK
|
||||
C926T08... OK
|
||||
bash-4.2$ exit
|
||||
exit
|
||||
|
||||
スクリプトは Wed Jun 6 14:39:38 2018
|
||||
に終了しました
|
||||
108
test/issues/1121/C1121.sh
Normal file
108
test/issues/1121/C1121.sh
Normal file
@ -0,0 +1,108 @@
|
||||
#!/bin/sh
|
||||
BIN=
|
||||
SBIN=
|
||||
OSTEST=
|
||||
LTP=
|
||||
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 10G@0,10G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
|
||||
|
||||
if [ -f ../../../config.h ]; then
|
||||
str=`grep "^#define BINDIR " ../../../config.h | head -1 | sed 's/^#define BINDIR /BINDIR=/'`
|
||||
eval $str
|
||||
fi
|
||||
if [ "x$BINDIR" = x ];then
|
||||
BINDIR="$BIN"
|
||||
fi
|
||||
|
||||
if [ -f ../../../Makefile ]; then
|
||||
str=`grep ^SBINDIR ../../../Makefile | head -1 | sed 's/ //g'`
|
||||
eval $str
|
||||
fi
|
||||
if [ "x$SBINDIR" = x ];then
|
||||
SBINDIR="$SBIN"
|
||||
fi
|
||||
|
||||
if [ -f $HOME/ltp/testcases/bin/sched_setaffinity01 ]; then
|
||||
LTPDIR=$HOME/ltp/testcases
|
||||
fi
|
||||
if [ "x$LTPDIR" = x ]; then
|
||||
LTPDIR="$LTP"
|
||||
fi
|
||||
|
||||
if [ -f $HOME/ostest/bin/test_mck ]; then
|
||||
OSTESTDIR=$HOME/ostest/
|
||||
fi
|
||||
if [ "x$OSTESTDIR" = x ]; then
|
||||
OSTESTDIR="$OSTEST"
|
||||
fi
|
||||
|
||||
if [ ! -x $SBINDIR/mcstop+release.sh ]; then
|
||||
echo mcstop+releas: not found >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -n "mcstop+release.sh ... "
|
||||
sudo $SBINDIR/mcstop+release.sh
|
||||
echo "done"
|
||||
|
||||
if [ ! -x $SBINDIR/mcreboot.sh ]; then
|
||||
echo mcreboot: not found >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -n "mcreboot.sh $BOOTPARAM ... "
|
||||
sudo $SBINDIR/mcreboot.sh $BOOTPARAM
|
||||
echo "done"
|
||||
|
||||
if [ ! -x $BINDIR/mcexec ]; then
|
||||
echo mcexec: not found >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tid=001
|
||||
echo "*** RT_$tid start *******************************"
|
||||
sudo $BINDIR/mcexec $OSTESTDIR/bin/test_mck -s sched_setaffinity -n 0 -- -p 20 2>&1 | tee ./RT_${tid}.txt
|
||||
if grep "RESULT: ok" ./RT_${tid}.txt > /dev/null 2>&1 ; then
|
||||
echo "*** RT_$tid: PASSED"
|
||||
else
|
||||
echo "*** RT_$tid: FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
tid=002
|
||||
echo "*** RT_$tid start *******************************"
|
||||
sudo $BINDIR/mcexec $OSTESTDIR/bin/test_mck -s sched_setaffinity -n 1 -- -p 20 2>&1 | tee ./RT_${tid}.txt
|
||||
if grep "RESULT: ok" ./RT_${tid}.txt > /dev/null 2>&1 ; then
|
||||
echo "*** RT_$tid: PASSED"
|
||||
else
|
||||
echo "*** RT_$tid: FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
tid=003
|
||||
echo "*** RT_$tid start *******************************"
|
||||
sudo $BINDIR/mcexec $OSTESTDIR/bin/test_mck -s sched_getaffinity -n 3 -- -p 20 2>&1 | tee ./RT_${tid}.txt
|
||||
if grep "RESULT: ok" ./RT_${tid}.txt > /dev/null 2>&1 ; then
|
||||
echo "*** RT_$tid: PASSED"
|
||||
else
|
||||
echo "*** RT_$tid: FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
tid=004
|
||||
echo "*** RT_$tid start *******************************"
|
||||
sudo $BINDIR/mcexec $OSTESTDIR/bin/test_mck -s sched_getaffinity -n 5 -- -p 20 2>&1 | tee ./RT_${tid}.txt
|
||||
if grep "RESULT: ok" ./RT_${tid}.txt > /dev/null 2>&1 ; then
|
||||
echo "*** RT_$tid: PASSED"
|
||||
else
|
||||
echo "*** RT_$tid: FAILED"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
tid=001
|
||||
echo "*** LT_$tid start *******************************"
|
||||
sudo $BINDIR/mcexec $LTPDIR/bin/sched_setaffinity01 2>&1 | tee ./LT_${tid}.txt
|
||||
ok=`grep TPASS LT_${tid}.txt | wc -l`
|
||||
ng=`grep TFAIL LT_${tid}.txt | wc -l`
|
||||
if [ $ng = 0 ]; then
|
||||
echo "*** LT_$tid: PASSED (ok:$ok)"
|
||||
else
|
||||
echo "*** LT_$tid: FAILED (ok:$ok, ng:$ng)"
|
||||
fi
|
||||
14
test/issues/1121/Makefile
Normal file
14
test/issues/1121/Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
CC = gcc
|
||||
TARGET=
|
||||
|
||||
CPPFLAGS =
|
||||
LDFLAGS =
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
test: all
|
||||
@sh ./C1121.sh
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) *.o
|
||||
|
||||
36
test/issues/1121/README
Normal file
36
test/issues/1121/README
Normal file
@ -0,0 +1,36 @@
|
||||
【Issue#1121 動作確認】
|
||||
□ テスト内容
|
||||
1. Issueで報告された再現プログラムでの確認
|
||||
RT_001: ostest-sched_setaffinity.000
|
||||
自プロセスのaffinityの設定と取得が行えることを確認
|
||||
|
||||
RT_002: ostest-sched_setaffinity.001
|
||||
自プロセスのaffinityを設定し、CPUのmigrateができることを確認
|
||||
|
||||
RT_003: ostest-sched_getaffinity.003
|
||||
存在しないプロセスIDを指定したsched_getaffinity()を実行し、
|
||||
-1 が返り、errnoにESRCH が設定されることを確認
|
||||
|
||||
RT_004: ostest-sched_getaffinity.005
|
||||
子プロセスを生成し、以下を確認
|
||||
- 子プロセスが親プロセスのaffinityを取得
|
||||
- 子プロセスが自プロセスのaffinityを取得
|
||||
- 親プロセス、自プロセスから取得したaffinityが等しいことを確認
|
||||
|
||||
2. 既存のsched_setaffinity機能に影響がないことをLTPを用いて確認
|
||||
LT_001: ltp-sched_setaffinity01
|
||||
異常な引数を指定した際に返される値と
|
||||
設定されるerrnoが正しいことを確認 (OK 4件)
|
||||
|
||||
□ 実行手順
|
||||
$ make test
|
||||
|
||||
実行できない場合は、C1121.shの以下の行を適切に書き換えた後に実行。
|
||||
BIN= mcexec が存在するパス
|
||||
SBIN= mcreboot.sh が存在するパス
|
||||
OSTEST= OSTESTが存在するパス
|
||||
LTP= LTPが存在するパス
|
||||
|
||||
□ 実行結果
|
||||
result.log 参照。
|
||||
すべての項目をPASSしていることを確認。
|
||||
35
test/issues/1121/result.log
Normal file
35
test/issues/1121/result.log
Normal file
@ -0,0 +1,35 @@
|
||||
*** RT_001 start *******************************
|
||||
TEST_SUITE: sched_setaffinity
|
||||
TEST_NUMBER: 0
|
||||
ARGS: -p 20
|
||||
RESULT: ok
|
||||
*** RT_001: PASSED
|
||||
|
||||
*** RT_002 start *******************************
|
||||
TEST_SUITE: sched_setaffinity
|
||||
TEST_NUMBER: 1
|
||||
ARGS: -p 20
|
||||
RESULT: ok
|
||||
*** RT_002: PASSED
|
||||
|
||||
*** RT_003 start *******************************
|
||||
TEST_SUITE: sched_getaffinity
|
||||
TEST_NUMBER: 3
|
||||
ARGS: -p 20
|
||||
sched_getaffinity result:-1, errno:3 (expect error is "ESRCH"=3)
|
||||
RESULT: ok
|
||||
*** RT_003: PASSED
|
||||
|
||||
*** RT_004 start *******************************
|
||||
TEST_SUITE: sched_getaffinity
|
||||
TEST_NUMBER: 5
|
||||
ARGS: -p 20
|
||||
RESULT: ok
|
||||
*** RT_004: PASSED
|
||||
|
||||
*** LT_001 start *******************************
|
||||
sched_setaffinity01 1 TPASS : expected failure with 'Bad address'
|
||||
sched_setaffinity01 2 TPASS : expected failure with 'Invalid argument'
|
||||
sched_setaffinity01 3 TPASS : expected failure with 'No such process'
|
||||
sched_setaffinity01 4 TPASS : expected failure with 'Operation not permitted'
|
||||
*** LT_001: PASSED (ok:4)
|
||||
66
test/issues/731/C731.sh
Normal file
66
test/issues/731/C731.sh
Normal file
@ -0,0 +1,66 @@
|
||||
#!/bin/sh
|
||||
BIN=
|
||||
SBIN=
|
||||
LTP=
|
||||
BOOTPARAM="-c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1"
|
||||
|
||||
if [ -f ../../../config.h ]; then
|
||||
str=`grep "^#define BINDIR " ../../../config.h | head -1 | sed 's/^#define BINDIR /BINDIR=/'`
|
||||
eval $str
|
||||
fi
|
||||
if [ "x$BINDIR" = x ];then
|
||||
BINDIR="$BIN"
|
||||
fi
|
||||
|
||||
if [ -f ../../../Makefile ]; then
|
||||
str=`grep ^SBINDIR ../../../Makefile | head -1 | sed 's/ //g'`
|
||||
eval $str
|
||||
fi
|
||||
if [ "x$SBINDIR" = x ];then
|
||||
SBINDIR="$SBIN"
|
||||
fi
|
||||
|
||||
if [ -f $HOME/ltp/testcases/bin/fork01 ]; then
|
||||
LTPDIR=$HOME/ltp/testcases
|
||||
fi
|
||||
if [ "x$LTPDIR" = x ]; then
|
||||
LTPDIR="$LTP"
|
||||
fi
|
||||
|
||||
if ! lsmod | grep mcctrl > /dev/null 2>&1; then
|
||||
if [ ! -x $SBINDIR/mcreboot.sh ]; then
|
||||
echo no mcreboot found >&2
|
||||
exit 1
|
||||
fi
|
||||
sudo $SBINDIR/mcreboot.sh $BOOTPARAM
|
||||
fi
|
||||
|
||||
if [ ! -x $BINDIR/mcexec ]; then
|
||||
echo no mcexec found >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo $BINDIR/mcexec ./g310a 2>&1 | tee g310a.txt
|
||||
if grep "fork: Permission denied" g310a.txt > /dev/null 2>&1 ; then
|
||||
echo "*** C731T001: g310a OK"
|
||||
else
|
||||
echo "*** C731T001: g310a NG"
|
||||
fi
|
||||
|
||||
if [ x$LTPDIR = x ]; then
|
||||
echo no LTP found >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for i in 01:002 02:003 03:004 04:005 07:006 08:007; do
|
||||
tp=`echo $i|sed 's/:.*//'`
|
||||
id=`echo $i|sed 's/.*://'`
|
||||
$BINDIR/mcexec $LTPDIR/bin/fork$tp 2>&1 | tee fork$tp.txt
|
||||
ok=`grep TPASS fork$tp.txt | wc -l`
|
||||
ng=`grep TFAIL fork$tp.txt | wc -l`
|
||||
if [ $ng = 0 ]; then
|
||||
echo "*** C731T$id: fork$tp OK ($ok)"
|
||||
else
|
||||
echo "*** C731T$id: fork$tp NG (ok=$ok ng=%ng)"
|
||||
fi
|
||||
done
|
||||
46
test/issues/731/C731.txt
Normal file
46
test/issues/731/C731.txt
Normal file
@ -0,0 +1,46 @@
|
||||
Script started on Thu Jun 28 09:16:36 2018
|
||||
bash-4.2$ make test
|
||||
gcc -o g310a g310a.c -Wall -g
|
||||
sh ./C731.sh
|
||||
Error: Failed to open /dev/mcos0.
|
||||
ERROR: opening /dev/mcos0
|
||||
fork(): error with child process after fork
|
||||
fork: Permission denied
|
||||
waitpid: No child processes
|
||||
*** C731T001: g310a OK
|
||||
fork01 1 TPASS : fork() returned 14513
|
||||
fork01 2 TPASS : child pid and fork() return agree: 14513
|
||||
*** C731T002: fork01 OK (2)
|
||||
fork02 0 TINFO : Inside parent
|
||||
fork02 0 TINFO : Inside child
|
||||
fork02 0 TINFO : exit status of wait 0
|
||||
fork02 1 TPASS : test 1 PASSED
|
||||
*** C731T003: fork02 OK (1)
|
||||
fork03 0 TINFO : process id in parent of child from fork : 14669
|
||||
fork03 1 TPASS : test 1 PASSED
|
||||
*** C731T004: fork03 OK (1)
|
||||
fork04 1 TPASS : Env var TERM unchanged after fork(): xterm
|
||||
fork04 2 TPASS : Env var NoTSetzWq unchanged after fork(): getenv() does not find variable set
|
||||
fork04 3 TPASS : Env var TESTPROG unchanged after fork(): FRKTCS04
|
||||
*** C731T005: fork04 OK (3)
|
||||
fork07 0 TINFO : Forking 100 children
|
||||
fork07 0 TINFO : Forked all 100 children, now collecting
|
||||
fork07 0 TINFO : Collected all 100 children
|
||||
fork07 1 TPASS : 100/100 children read correctly from an inheritted fd
|
||||
*** C731T006: fork07 OK (1)
|
||||
fork08 0 TINFO : parent forksval: 1
|
||||
fork08 0 TINFO : parent forksval: 2
|
||||
fork08 0 TINFO : second child got char: b
|
||||
fork08 1 TPASS : Test passed in childnumber 2
|
||||
fork08 0 TINFO : exit status of wait expected 0 got 0
|
||||
fork08 1 TPASS : parent test PASSED
|
||||
fork08 0 TINFO : exit status of wait expected 0 got 0
|
||||
fork08 2 TPASS : parent test PASSED
|
||||
fork08 0 TINFO : exit status of wait expected 0 got 0
|
||||
fork08 3 TPASS : parent test PASSED
|
||||
fork08 0 TINFO : Number of processes forked is 2
|
||||
*** C731T007: fork08 OK (4)
|
||||
bash-4.2$ exit
|
||||
exit
|
||||
|
||||
Script done on Thu Jun 28 09:17:21 2018
|
||||
13
test/issues/731/Makefile
Normal file
13
test/issues/731/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
CC=gcc
|
||||
TARGET=g310a
|
||||
|
||||
all:: $(TARGET)
|
||||
|
||||
g310a: g310a.c
|
||||
$(CC) -o g310a g310a.c -Wall -g
|
||||
|
||||
test:: $(TARGET)
|
||||
sh ./C731.sh
|
||||
|
||||
clean::
|
||||
rm -f *.o $(TARGET)
|
||||
35
test/issues/731/README
Normal file
35
test/issues/731/README
Normal file
@ -0,0 +1,35 @@
|
||||
【Issue#731 動作確認】
|
||||
□ テスト内容
|
||||
1. g310aの実行確認
|
||||
C731T001 g310aを実行し、forkが Permission denied でエラーとなることを確認
|
||||
|
||||
2. 既存fork機能に影響しないことをLTPを用いて確認
|
||||
C731T002 fork01 の実行確認
|
||||
fork後に子プロセスのプロセスIDが正しいことを確認 (OK 2件)
|
||||
C731T003 fork02 の実行確認
|
||||
fork後にwaitを行い、waitが子プロセスのPIDを返却することを確認(OK 1件)
|
||||
C731T004 fork03 の実行確認
|
||||
子プロセスがfork後に計算を行えること、また子プロセスでのfork返却値が0で
|
||||
あることを確認 (OK 1件)
|
||||
C731T005 fork04 の実行確認
|
||||
forkで生成した子プロセスが環境変数を変更しても、親プロセス側の
|
||||
環境変数に変化が無いことを確認 (OK 3件)
|
||||
C731T006 fork07 の実行確認
|
||||
forkした子プロセスに、親プロセスからファイルディスクリプタを
|
||||
引き継いでいることを確認 (OK 1件)
|
||||
C731T007 fork08 の実行確認
|
||||
forkした複数の子プロセスが、それぞれ親プロセスから引き継いだファイル
|
||||
ディスクリプタを別個に操作できることを確認
|
||||
(ある子プロセスがcloseしても別な子プロセスがI/O可能) (OK 4件)
|
||||
|
||||
□ 実行手順
|
||||
$ make test
|
||||
|
||||
実行できない場合は、C731.shの以下の行を適切に書き換えた後に実行。
|
||||
BIN= mcexec が存在するパス
|
||||
SBIN= mcreboot.sh が存在するパス
|
||||
LTP= LTPが存在するパス
|
||||
|
||||
□ 実行結果
|
||||
C731.txt 参照。
|
||||
全ての項目が OK となっていることを確認。
|
||||
2
test/issues/731/fork01.txt
Normal file
2
test/issues/731/fork01.txt
Normal file
@ -0,0 +1,2 @@
|
||||
fork01 1 TPASS : fork() returned 14513
|
||||
fork01 2 TPASS : child pid and fork() return agree: 14513
|
||||
4
test/issues/731/fork02.txt
Normal file
4
test/issues/731/fork02.txt
Normal file
@ -0,0 +1,4 @@
|
||||
fork02 0 TINFO : Inside parent
|
||||
fork02 0 TINFO : Inside child
|
||||
fork02 0 TINFO : exit status of wait 0
|
||||
fork02 1 TPASS : test 1 PASSED
|
||||
2
test/issues/731/fork03.txt
Normal file
2
test/issues/731/fork03.txt
Normal file
@ -0,0 +1,2 @@
|
||||
fork03 0 TINFO : process id in parent of child from fork : 14669
|
||||
fork03 1 TPASS : test 1 PASSED
|
||||
3
test/issues/731/fork04.txt
Normal file
3
test/issues/731/fork04.txt
Normal file
@ -0,0 +1,3 @@
|
||||
fork04 1 TPASS : Env var TERM unchanged after fork(): xterm
|
||||
fork04 2 TPASS : Env var NoTSetzWq unchanged after fork(): getenv() does not find variable set
|
||||
fork04 3 TPASS : Env var TESTPROG unchanged after fork(): FRKTCS04
|
||||
4
test/issues/731/fork07.txt
Normal file
4
test/issues/731/fork07.txt
Normal file
@ -0,0 +1,4 @@
|
||||
fork07 0 TINFO : Forking 100 children
|
||||
fork07 0 TINFO : Forked all 100 children, now collecting
|
||||
fork07 0 TINFO : Collected all 100 children
|
||||
fork07 1 TPASS : 100/100 children read correctly from an inheritted fd
|
||||
11
test/issues/731/fork08.txt
Normal file
11
test/issues/731/fork08.txt
Normal file
@ -0,0 +1,11 @@
|
||||
fork08 0 TINFO : parent forksval: 1
|
||||
fork08 0 TINFO : parent forksval: 2
|
||||
fork08 0 TINFO : second child got char: b
|
||||
fork08 1 TPASS : Test passed in childnumber 2
|
||||
fork08 0 TINFO : exit status of wait expected 0 got 0
|
||||
fork08 1 TPASS : parent test PASSED
|
||||
fork08 0 TINFO : exit status of wait expected 0 got 0
|
||||
fork08 2 TPASS : parent test PASSED
|
||||
fork08 0 TINFO : exit status of wait expected 0 got 0
|
||||
fork08 3 TPASS : parent test PASSED
|
||||
fork08 0 TINFO : Number of processes forked is 2
|
||||
55
test/issues/731/g310a.c
Normal file
55
test/issues/731/g310a.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* g310a: If superuser try to fork() after seteuid(bin), ...
|
||||
*/
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int error;
|
||||
struct passwd *pwd;
|
||||
pid_t pid;
|
||||
int ws;
|
||||
|
||||
if (geteuid()) {
|
||||
printf("not a superuser\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
pwd = getpwnam("bin");
|
||||
if (!pwd) {
|
||||
perror("getpwnam");
|
||||
return 1;
|
||||
}
|
||||
|
||||
error = seteuid(pwd->pw_uid);
|
||||
if (error) {
|
||||
perror("seteuid");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("fork");
|
||||
}
|
||||
|
||||
if (!pid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid = waitpid(pid, &ws, 0);
|
||||
if (pid == -1) {
|
||||
perror("waitpid");
|
||||
return 1;
|
||||
}
|
||||
if (ws) {
|
||||
printf("ws: %#x\n", ws);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("done.\n");
|
||||
return 0;
|
||||
}
|
||||
5
test/issues/731/g310a.txt
Normal file
5
test/issues/731/g310a.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Error: Failed to open /dev/mcos0.
|
||||
ERROR: opening /dev/mcos0
|
||||
fork(): error with child process after fork
|
||||
fork: Permission denied
|
||||
waitpid: No child processes
|
||||
@ -1,18 +1,18 @@
|
||||
.SUFFIXES: # Clear suffixes
|
||||
.SUFFIXES: .c
|
||||
.SUFFIXES: .c
|
||||
|
||||
CC = gcc
|
||||
|
||||
CPPFLAGS = -I$(HOME)/project/os/install/include
|
||||
CCFLAGS = -g
|
||||
LDFLAGS = -L$(HOME)/project/os/install/lib -lihk -Wl,-rpath -Wl,$(HOME)/project/os/install/lib
|
||||
EXES =
|
||||
SRCS =
|
||||
LDFLAGS = -L$(HOME)/project/os/install/lib -lihk -Wl,-rpath -Wl,$(HOME)/project/os/install/lib -lpthread
|
||||
EXES =
|
||||
SRCS =
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
CPPFLAGSMCK = -I$(HOME)/usr/include
|
||||
CCFLAGSMCK = -g -O0
|
||||
LDFLAGSMCK = -static
|
||||
LDFLAGSMCK = -static -lpthread
|
||||
SRCSMCK = $(shell ls rusage*.c)
|
||||
EXESMCK = $(SRCSMCK:.c=)
|
||||
OBJSMCK = $(SRCSMCK:.c=.o)
|
||||
@ -163,5 +163,17 @@ rusage103: rusage103.o
|
||||
rusage103.o: rusage103.c
|
||||
$(CC) $(CCFLAGS) $(CPPFLAGS) -c $<
|
||||
|
||||
%_mck: %_mck.o
|
||||
$(CC) -o $@ $^ $(LDFLAGSMCK)
|
||||
|
||||
%_mck.o:: %_mck.c
|
||||
$(CC) $(CCFLAGSMCK) $(CPPFLAGSMCK) -c $<
|
||||
|
||||
%_lin.o:: %_lin.c
|
||||
$(CC) $(CCFLAGS) $(CPPFLAGS) -c $<
|
||||
|
||||
%_lin: %_lin.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f core $(EXES) $(OBJS) $(EXESMCK) $(OBJSMCK)
|
||||
|
||||
@ -102,15 +102,16 @@ rusage021: Run npb bt-mz.S.4
|
||||
2-ppn x 2-tpn x 2-node (wallaby{14,15}) [OK]
|
||||
2-ppn x 1-tpn x 2-node (polaris,kochab) [OK]
|
||||
|
||||
rusage100: Test ihk_os_getrusage()
|
||||
rusage100: Test ihk_os_getrusage()
|
||||
anon mmap,num_threads=1 [OK]
|
||||
|
||||
rusage101: Test ihk_os_getrusage()
|
||||
anon mmap,num_threads=2 [OK]
|
||||
|
||||
rusage102: Test ihk_os_getrusage()
|
||||
rusage102: Test ihk_os_getrusage()
|
||||
file map,num_threads=1 [OK]
|
||||
|
||||
rusage103: Test ihk_os_getrusage()
|
||||
anon mmap@numa#1 [OK]
|
||||
|
||||
rusage104: Test ihk_os_getrusage(), user time per CPU
|
||||
|
||||
@ -17,13 +17,18 @@ case ${testname} in
|
||||
printf "*** Enable debug messages in rusage.h, memory.c, fileobj.c, shmobj.c, process.c by defining DEBUG macro, e.g. #define RUSAGE_DEBUG and then recompile IHK/McKernel.\n"
|
||||
printf "*** Install xpmem by git-clone https://github.com/hjelmn/xpmem.\n"
|
||||
;;
|
||||
rusage10?)
|
||||
rusage100 | rusage101 | rusage102 | rusage103)
|
||||
printf "*** Refer to rusage100.patch to add syscall #900 by editing syscall_list.h and syscall.c and recompile IHK/McKernel.\n"
|
||||
;;
|
||||
rusage104)
|
||||
printf "*** Apply rusage104.patch to enable syscall #900"
|
||||
printf "which reports rusage values.\n"
|
||||
;;
|
||||
*)
|
||||
printf "*** Enable debug messages in rusage.h, memory.c, fileobj.c, shmobj.c, process.c by defining DEBUG macro, e.g. #define RUSAGE_DEBUG and then recompile IHK/McKernel.\n"
|
||||
;;
|
||||
esac
|
||||
|
||||
read -p "*** Hit return when ready!" key
|
||||
|
||||
case ${testname} in
|
||||
@ -45,6 +50,11 @@ case ${testname} in
|
||||
bn=npb/NPB3.3.1-MZ/NPB3.3-MZ-MPI/bin/bt-mz.S.4
|
||||
perl -e 'print "polaris:2\nkochab:2\n"' > ./hostfile
|
||||
;;
|
||||
rusage104)
|
||||
bn=${testname}
|
||||
make clean > /dev/null 2> /dev/null
|
||||
make ${bn}_mck ${bn}_lin
|
||||
;;
|
||||
*)
|
||||
bn=${testname}
|
||||
make clean > /dev/null 2> /dev/null
|
||||
@ -141,8 +151,11 @@ case ${testname} in
|
||||
rusage103)
|
||||
bootopt="-m 256M@1"
|
||||
;;
|
||||
rusage104)
|
||||
bootopt="-c 1,2,3 -m 256M"
|
||||
;;
|
||||
*)
|
||||
echo Unknown test case
|
||||
echo Unknown test case
|
||||
exit 255
|
||||
esac
|
||||
|
||||
@ -199,6 +212,12 @@ else
|
||||
echo "================================================" >> ./${testname}.log
|
||||
sudo ${install}/sbin/ihkosctl 0 kmsg >> ./${testname}.log
|
||||
;;
|
||||
rusage104)
|
||||
${install}/bin/mcexec ${mcexecopt} ./${bn}_mck
|
||||
${install}/bin/mcexec ${mcexecopt} ./${bn}_lin
|
||||
sudo ${install}/sbin/ihkosctl 0 kmsg > ./${testname}.log
|
||||
grep user ./${testname}.log
|
||||
;;
|
||||
*)
|
||||
${install}/bin/mcexec ${mcexecopt} ./${bn} ${testopt}
|
||||
sudo ${install}/sbin/ihkosctl 0 kmsg > ./${testname}.log
|
||||
@ -206,10 +225,13 @@ else
|
||||
fi
|
||||
|
||||
case ${testname} in
|
||||
rusage10?)
|
||||
rusage100 | rusage101 | rusage102 | rusage103)
|
||||
printf "*** Check the ihk_os_getrusage() result (the first part of ${testname}.log) matches with the syscall #900 result (the second part) \n"
|
||||
;;
|
||||
|
||||
rusage104)
|
||||
printf "*** It behaves as expected when there's no [NG] and "
|
||||
printf "\"All tests finished\" is shown\n"
|
||||
;;
|
||||
*)
|
||||
printf "*** cat ${testname}.log (kmsg) > ./match.pl to confirm there's no stray add/sub.\n"
|
||||
printf "*** Look ${testname}.log (kmsg) to confirm memory_stat_*[*] returned to zero when the last thread exits.\n"
|
||||
|
||||
47
test/rusage/rusage104.patch
Normal file
47
test/rusage/rusage104.patch
Normal file
@ -0,0 +1,47 @@
|
||||
diff --git arch/x86_64/kernel/include/syscall_list.h arch/x86_64/kernel/include/syscall_list.h
|
||||
index 48b1ea0..3717bb2 100644
|
||||
--- arch/x86_64/kernel/include/syscall_list.h
|
||||
+++ arch/x86_64/kernel/include/syscall_list.h
|
||||
@@ -168,4 +168,6 @@ SYSCALL_HANDLED(802, linux_mlock)
|
||||
SYSCALL_HANDLED(803, suspend_threads)
|
||||
SYSCALL_HANDLED(804, resume_threads)
|
||||
SYSCALL_HANDLED(811, linux_spawn)
|
||||
+
|
||||
+SYSCALL_HANDLED(900, dump_rusage)
|
||||
/**** End of File ****/
|
||||
diff --git kernel/syscall.c kernel/syscall.c
|
||||
index 8dc0a0e..9969a4b 100644
|
||||
--- kernel/syscall.c
|
||||
+++ kernel/syscall.c
|
||||
@@ -9477,3 +9477,31 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
|
||||
return l;
|
||||
}
|
||||
+
|
||||
+SYSCALL_DECLARE(dump_rusage)
|
||||
+{
|
||||
+ /* rusage debug */
|
||||
+ int i;
|
||||
+ for(i = 0; i < IHK_MAX_NUM_PGSIZES; i++) {
|
||||
+ kprintf("memory_stat_rss[%d]=%ld\n", i, rusage->memory_stat_rss[i]);
|
||||
+ }
|
||||
+ for(i = 0; i < IHK_MAX_NUM_PGSIZES; i++) {
|
||||
+ kprintf("memory_stat_mapped_file[%d]=%ld\n", i, rusage->memory_stat_mapped_file[i]);
|
||||
+ }
|
||||
+ kprintf("memory_max_usage=%ld\n", rusage->memory_max_usage);
|
||||
+ kprintf("memory_kmem_usage=%ld\n", rusage->memory_kmem_usage);
|
||||
+ kprintf("memory_kmem_max_usage=%ld\n", rusage->memory_kmem_max_usage);
|
||||
+ for (i = 0; i < rusage->num_numa_nodes; i++) {
|
||||
+ kprintf("memory_numa_stat[%d]=%ld\n", i, rusage->memory_numa_stat[i]);
|
||||
+ }
|
||||
+ kprintf("ns_per_tsc=%ld\n", rusage->ns_per_tsc);
|
||||
+ for (i = 0; i < rusage->num_processors; i++) {
|
||||
+ kprintf("cpu[%d].user_tsc=%ld\n", i, rusage->cpu[i].user_tsc);
|
||||
+ kprintf("cpu[%d].system_tsc=%ld\n", i, rusage->cpu[i].system_tsc);
|
||||
+ }
|
||||
+
|
||||
+ kprintf("num_threads=%d\n", rusage->num_threads);
|
||||
+ kprintf("max_num_threads=%d\n", rusage->max_num_threads);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
38
test/rusage/rusage104_lin.c
Normal file
38
test/rusage/rusage104_lin.c
Normal file
@ -0,0 +1,38 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "ihklib.h"
|
||||
#include "mckernel/ihklib_rusage.h"
|
||||
#include "util.h"
|
||||
|
||||
#define DELAY0 (100UL * 1000 * 1000)
|
||||
#define DELAY1 (200UL * 1000 * 1000)
|
||||
#define SCALE 1.5
|
||||
#define WITHIN_RANGE(x, y, s) (x >= y && x <= y * s)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct mckernel_rusage rusage;
|
||||
|
||||
if ((ret = ihk_os_getrusage(0, &rusage, sizeof(rusage)))) {
|
||||
fprintf(stderr, "%s: ihk_os_getrusage failed\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
OKNG(WITHIN_RANGE(rusage.cpuacct_usage_percpu[1], DELAY0, SCALE),
|
||||
"cpu 0: user time: expected: %ld nsec, reported: %ld nsec\n",
|
||||
DELAY0, rusage.cpuacct_usage_percpu[1]);
|
||||
OKNG(WITHIN_RANGE(rusage.cpuacct_usage_percpu[2], DELAY1, SCALE),
|
||||
"cpu 1: user time: expected: %ld nsec, reported: %ld nsec\n",
|
||||
DELAY1, rusage.cpuacct_usage_percpu[2]);
|
||||
|
||||
printf("All tests finished\n");
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
221
test/rusage/rusage104_mck.c
Normal file
221
test/rusage/rusage104_mck.c
Normal file
@ -0,0 +1,221 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
#define DELAY0 (100UL * 1000 * 1000)
|
||||
#define DELAY1 (200UL * 1000 * 1000)
|
||||
|
||||
struct thr_arg {
|
||||
unsigned long delay;
|
||||
};
|
||||
|
||||
struct thr_arg thr_arg[2] = { { .delay = DELAY0 }, { .delay = DELAY1 } };
|
||||
pthread_t thr[2];
|
||||
|
||||
#define DIFFNSEC(end, start) ((end.tv_sec - start.tv_sec) * 1000000000UL + \
|
||||
(end.tv_nsec - start.tv_nsec))
|
||||
#define TIMER_KIND CLOCK_MONOTONIC_RAW /* CLOCK_THREAD_CPUTIME_ID */
|
||||
|
||||
static int print_cpu_last_executed_on(void)
|
||||
{
|
||||
int ret = 0;
|
||||
char fn[256];
|
||||
char *result;
|
||||
pid_t tid = syscall(SYS_gettid);
|
||||
int fd;
|
||||
int offset;
|
||||
int amount = 0;
|
||||
char *list;
|
||||
char *token;
|
||||
int i;
|
||||
int cpu;
|
||||
|
||||
sprintf(fn, "/proc/%d/task/%d/stat", getpid(), (int)tid);
|
||||
fd = open(fn, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
printf("open() failed\n");
|
||||
goto fn_fail;
|
||||
}
|
||||
|
||||
result = malloc(65536);
|
||||
if (result == NULL) {
|
||||
printf("malloc() failed");
|
||||
goto fn_fail;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
while (1) {
|
||||
amount = read(fd, result + offset, 65536);
|
||||
// printf("amount=%d\n", amount);
|
||||
if (amount == -1) {
|
||||
printf("read() failed");
|
||||
goto fn_fail;
|
||||
}
|
||||
if (amount == 0) {
|
||||
goto eof;
|
||||
}
|
||||
offset += amount;
|
||||
}
|
||||
eof:;
|
||||
//printf("result:%s\n", result);
|
||||
|
||||
list = result;
|
||||
for (i = 0; i < 39; i++) {
|
||||
token = strsep(&list, " ");
|
||||
}
|
||||
|
||||
cpu = sched_getcpu();
|
||||
if (cpu == -1) {
|
||||
printf("getcpu() failed\n");
|
||||
goto fn_fail;
|
||||
}
|
||||
|
||||
printf("[INFO] stat-cpu=%02d,sched_getcpu=%02d,tid=%d\n",
|
||||
token ? atoi(token) : -1, cpu, tid);
|
||||
fn_exit:
|
||||
free(result);
|
||||
return ret;
|
||||
fn_fail:
|
||||
ret = -1;
|
||||
goto fn_exit;
|
||||
}
|
||||
|
||||
static inline void asm_loop(unsigned long n)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < (n); j++) {
|
||||
asm volatile(
|
||||
"movq $0, %%rcx\n\t"
|
||||
"1:\t"
|
||||
"addq $1, %%rcx\n\t"
|
||||
"cmpq $99, %%rcx\n\t"
|
||||
"jle 1b\n\t"
|
||||
:
|
||||
:
|
||||
: "rcx", "cc");
|
||||
}
|
||||
}
|
||||
|
||||
double nspw; /* nsec per work */
|
||||
unsigned long nsec;
|
||||
|
||||
void fwq_init(void)
|
||||
{
|
||||
struct timespec start, end;
|
||||
int i;
|
||||
|
||||
clock_gettime(TIMER_KIND, &start);
|
||||
#define N_INIT 10000000
|
||||
asm_loop(N_INIT);
|
||||
clock_gettime(TIMER_KIND, &end);
|
||||
nsec = DIFFNSEC(end, start);
|
||||
nspw = nsec / (double)N_INIT;
|
||||
}
|
||||
|
||||
#if 1
|
||||
void fwq(long delay_nsec)
|
||||
{
|
||||
if (delay_nsec < 0) {
|
||||
return;
|
||||
}
|
||||
asm_loop(delay_nsec / nspw);
|
||||
}
|
||||
#else
|
||||
/* For machines with large core-to-core performance variation (e.g. OFP) */
|
||||
void fwq(long delay_nsec)
|
||||
{
|
||||
struct timespec start, end;
|
||||
|
||||
if (delay_nsec < 0) {
|
||||
return;
|
||||
}
|
||||
clock_gettime(TIMER_KIND, &start);
|
||||
|
||||
while (1) {
|
||||
clock_gettime(TIMER_KIND, &end);
|
||||
if (DIFFNSEC(end, start) >= delay_nsec) {
|
||||
break;
|
||||
}
|
||||
asm_loop(2); /* ~150 ns per iteration on FOP */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void *util_thread(void *_arg)
|
||||
{
|
||||
struct thr_arg *arg = (struct thr_arg *)_arg;
|
||||
|
||||
print_cpu_last_executed_on();
|
||||
fwq(arg->delay);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
cpu_set_t cpuset;
|
||||
pthread_attr_t attr[2];
|
||||
|
||||
fwq_init();
|
||||
|
||||
/* Migrate to cpu#0 */
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(0, &cpuset);
|
||||
sched_setaffinity(0, sizeof(cpu_set_t), &cpuset);
|
||||
print_cpu_last_executed_on();
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(i + 1, &cpuset);
|
||||
|
||||
if ((ret = pthread_attr_init(&attr[i]))) {
|
||||
printf("%s: ERROR: pthread_attr_init failed (%d)\n",
|
||||
__func__, ret);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((ret = pthread_attr_setaffinity_np(&attr[i],
|
||||
sizeof(cpu_set_t), &cpuset))) {
|
||||
printf("%s: ERROR: pthread_attr_setaffinity_np "
|
||||
"failed (%d)\n", __func__, ret);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((ret = pthread_create(&thr[i], &attr[i],
|
||||
util_thread, &thr_arg[i]))) {
|
||||
fprintf(stderr, "ERROR: pthread_create failed (%d)\n",
|
||||
ret);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
pthread_join(thr[i], NULL);
|
||||
}
|
||||
|
||||
if ((ret = syscall(900))) {
|
||||
fprintf(stderr, "%s: syscall failed\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
44
test/rusage/util.h
Normal file
44
test/rusage/util.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef __UTIL_H_INCLUDED__
|
||||
#define __UTIL_H_INCLUDED__
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dprintf(...) do { \
|
||||
char msg[1024]; \
|
||||
sprintf(msg, __VA_ARGS__); \
|
||||
fprintf(stderr, "%s,%s", __func__, msg); \
|
||||
} while (0)
|
||||
#else
|
||||
#define dprintf(...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define eprintf(...) do { \
|
||||
char msg[1024]; \
|
||||
sprintf(msg, __VA_ARGS__); \
|
||||
fprintf(stderr, "%s,%s", __func__, msg); \
|
||||
} while (0)
|
||||
|
||||
#define CHKANDJUMP(cond, err, ...) do { \
|
||||
if (cond) { \
|
||||
eprintf(__VA_ARGS__); \
|
||||
ret = err; \
|
||||
goto fn_fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define OKNG(cond, ...) do { \
|
||||
if (cond) { \
|
||||
printf("[ OK ] "); \
|
||||
printf(__VA_ARGS__); \
|
||||
} else { \
|
||||
printf("[ NG ] "); \
|
||||
printf(__VA_ARGS__); \
|
||||
ret = -EINVAL; \
|
||||
goto out; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user