mcctrl procfs: use semaphores instead of spinlocks to avoid sleeping in GFP_KERNEL kmalloc() in atomic context
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
#include <linux/semaphore.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/delay.h>
|
#include <asm/delay.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
@@ -802,7 +803,7 @@ long mcexec_ret_syscall(ihk_os_t os, struct syscall_ret_desc *__user arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LIST_HEAD(mckernel_exec_files);
|
LIST_HEAD(mckernel_exec_files);
|
||||||
DEFINE_SPINLOCK(mckernel_exec_file_lock);
|
DEFINE_SEMAPHORE(mckernel_exec_file_lock);
|
||||||
|
|
||||||
|
|
||||||
struct mckernel_exec_file {
|
struct mckernel_exec_file {
|
||||||
@@ -889,7 +890,7 @@ int mcexec_open_exec(ihk_os_t os, char * __user filename)
|
|||||||
goto out_put_file;
|
goto out_put_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irq(&mckernel_exec_file_lock);
|
down(&mckernel_exec_file_lock);
|
||||||
/* Find previous file (if exists) and drop it */
|
/* Find previous file (if exists) and drop it */
|
||||||
list_for_each_entry(mcef_iter, &mckernel_exec_files, list) {
|
list_for_each_entry(mcef_iter, &mckernel_exec_files, list) {
|
||||||
if (mcef_iter->os == os && mcef_iter->pid == task_tgid_vnr(current)) {
|
if (mcef_iter->os == os && mcef_iter->pid == task_tgid_vnr(current)) {
|
||||||
@@ -910,7 +911,7 @@ int mcexec_open_exec(ihk_os_t os, char * __user filename)
|
|||||||
/* Create /proc/self/exe entry */
|
/* Create /proc/self/exe entry */
|
||||||
add_pid_entry(os_ind, task_tgid_vnr(current));
|
add_pid_entry(os_ind, task_tgid_vnr(current));
|
||||||
proc_exe_link(os_ind, task_tgid_vnr(current), fullpath);
|
proc_exe_link(os_ind, task_tgid_vnr(current), fullpath);
|
||||||
spin_unlock(&mckernel_exec_file_lock);
|
up(&mckernel_exec_file_lock);
|
||||||
|
|
||||||
dprintk("%d open_exec and holding file: %s\n", (int)task_tgid_vnr(current), filename);
|
dprintk("%d open_exec and holding file: %s\n", (int)task_tgid_vnr(current), filename);
|
||||||
|
|
||||||
@@ -937,7 +938,7 @@ int mcexec_close_exec(ihk_os_t os)
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irq(&mckernel_exec_file_lock);
|
down(&mckernel_exec_file_lock);
|
||||||
list_for_each_entry(mcef, &mckernel_exec_files, list) {
|
list_for_each_entry(mcef, &mckernel_exec_files, list) {
|
||||||
if (mcef->os == os && mcef->pid == task_tgid_vnr(current)) {
|
if (mcef->os == os && mcef->pid == task_tgid_vnr(current)) {
|
||||||
allow_write_access(mcef->fp);
|
allow_write_access(mcef->fp);
|
||||||
@@ -950,7 +951,7 @@ int mcexec_close_exec(ihk_os_t os)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&mckernel_exec_file_lock);
|
up(&mckernel_exec_file_lock);
|
||||||
|
|
||||||
return (found ? 0 : EINVAL);
|
return (found ? 0 : EINVAL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <linux/resource.h>
|
#include <linux/resource.h>
|
||||||
#include "mcctrl.h"
|
#include "mcctrl.h"
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
#include <linux/semaphore.h>
|
||||||
|
|
||||||
//#define PROCFS_DEBUG
|
//#define PROCFS_DEBUG
|
||||||
|
|
||||||
@@ -81,7 +82,7 @@ struct procfs_list_entry {
|
|||||||
* file.
|
* file.
|
||||||
*/
|
*/
|
||||||
LIST_HEAD(procfs_file_list);
|
LIST_HEAD(procfs_file_list);
|
||||||
static ihk_spinlock_t procfs_file_list_lock;
|
DEFINE_SEMAPHORE(procfs_file_list_lock);
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
getpath(struct procfs_list_entry *e, char *buf, int bufsize)
|
getpath(struct procfs_list_entry *e, char *buf, int bufsize)
|
||||||
@@ -375,67 +376,62 @@ _add_tid_entry(int osnum, int pid, int tid, const struct cred *cred)
|
|||||||
void
|
void
|
||||||
add_tid_entry(int osnum, int pid, int tid)
|
add_tid_entry(int osnum, int pid, int tid)
|
||||||
{
|
{
|
||||||
unsigned long irqflag;
|
|
||||||
const struct cred *cred = get_pid_cred(pid);
|
const struct cred *cred = get_pid_cred(pid);
|
||||||
|
|
||||||
if(!cred)
|
if(!cred)
|
||||||
return;
|
return;
|
||||||
irqflag = ihk_ikc_spinlock_lock(&procfs_file_list_lock);
|
down(&procfs_file_list_lock);
|
||||||
_add_tid_entry(osnum, pid, tid, cred);
|
_add_tid_entry(osnum, pid, tid, cred);
|
||||||
ihk_ikc_spinlock_unlock(&procfs_file_list_lock, irqflag);
|
up(&procfs_file_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
add_pid_entry(int osnum, int pid)
|
add_pid_entry(int osnum, int pid)
|
||||||
{
|
{
|
||||||
struct procfs_list_entry *parent;
|
struct procfs_list_entry *parent;
|
||||||
unsigned long irqflag;
|
|
||||||
const struct cred *cred = get_pid_cred(pid);
|
const struct cred *cred = get_pid_cred(pid);
|
||||||
|
|
||||||
if(!cred)
|
if(!cred)
|
||||||
return;
|
return;
|
||||||
irqflag = ihk_ikc_spinlock_lock(&procfs_file_list_lock);
|
down(&procfs_file_list_lock);
|
||||||
parent = get_pid_entry(osnum, pid);
|
parent = get_pid_entry(osnum, pid);
|
||||||
add_procfs_entries(parent, pid_entry_stuff, cred->uid, cred->gid);
|
add_procfs_entries(parent, pid_entry_stuff, cred->uid, cred->gid);
|
||||||
_add_tid_entry(osnum, pid, pid, cred);
|
_add_tid_entry(osnum, pid, pid, cred);
|
||||||
ihk_ikc_spinlock_unlock(&procfs_file_list_lock, irqflag);
|
up(&procfs_file_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
delete_tid_entry(int osnum, int pid, int tid)
|
delete_tid_entry(int osnum, int pid, int tid)
|
||||||
{
|
{
|
||||||
unsigned long irqflag;
|
|
||||||
struct procfs_list_entry *e;
|
struct procfs_list_entry *e;
|
||||||
|
|
||||||
irqflag = ihk_ikc_spinlock_lock(&procfs_file_list_lock);
|
down(&procfs_file_list_lock);
|
||||||
e = find_tid_entry(osnum, pid, tid);
|
e = find_tid_entry(osnum, pid, tid);
|
||||||
if(e)
|
if(e)
|
||||||
delete_procfs_entries(e);
|
delete_procfs_entries(e);
|
||||||
ihk_ikc_spinlock_unlock(&procfs_file_list_lock, irqflag);
|
up(&procfs_file_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
delete_pid_entry(int osnum, int pid)
|
delete_pid_entry(int osnum, int pid)
|
||||||
{
|
{
|
||||||
unsigned long irqflag;
|
|
||||||
struct procfs_list_entry *e;
|
struct procfs_list_entry *e;
|
||||||
|
|
||||||
irqflag = ihk_ikc_spinlock_lock(&procfs_file_list_lock);
|
down(&procfs_file_list_lock);
|
||||||
e = find_pid_entry(osnum, pid);
|
e = find_pid_entry(osnum, pid);
|
||||||
if(e)
|
if(e)
|
||||||
delete_procfs_entries(e);
|
delete_procfs_entries(e);
|
||||||
ihk_ikc_spinlock_unlock(&procfs_file_list_lock, irqflag);
|
up(&procfs_file_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
proc_exe_link(int osnum, int pid, const char *path)
|
proc_exe_link(int osnum, int pid, const char *path)
|
||||||
{
|
{
|
||||||
struct procfs_list_entry *parent;
|
struct procfs_list_entry *parent;
|
||||||
unsigned long irqflag;
|
|
||||||
kuid_t uid = KUIDT_INIT(0);
|
kuid_t uid = KUIDT_INIT(0);
|
||||||
kgid_t gid = KGIDT_INIT(0);
|
kgid_t gid = KGIDT_INIT(0);
|
||||||
|
|
||||||
irqflag = ihk_ikc_spinlock_lock(&procfs_file_list_lock);
|
down(&procfs_file_list_lock);
|
||||||
parent = find_pid_entry(osnum, pid);
|
parent = find_pid_entry(osnum, pid);
|
||||||
if(parent){
|
if(parent){
|
||||||
struct procfs_list_entry *task;
|
struct procfs_list_entry *task;
|
||||||
@@ -451,7 +447,7 @@ proc_exe_link(int osnum, int pid, const char *path)
|
|||||||
uid, gid, path);
|
uid, gid, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ihk_ikc_spinlock_unlock(&procfs_file_list_lock, irqflag);
|
up(&procfs_file_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -463,14 +459,13 @@ void
|
|||||||
procfs_init(int osnum)
|
procfs_init(int osnum)
|
||||||
{
|
{
|
||||||
struct procfs_list_entry *parent;
|
struct procfs_list_entry *parent;
|
||||||
unsigned long irqflag;
|
|
||||||
kuid_t uid = KUIDT_INIT(0);
|
kuid_t uid = KUIDT_INIT(0);
|
||||||
kgid_t gid = KGIDT_INIT(0);
|
kgid_t gid = KGIDT_INIT(0);
|
||||||
|
|
||||||
irqflag = ihk_ikc_spinlock_lock(&procfs_file_list_lock);
|
down(&procfs_file_list_lock);
|
||||||
parent = get_base_entry(osnum);
|
parent = get_base_entry(osnum);
|
||||||
add_procfs_entries(parent, base_entry_stuff, uid, gid);
|
add_procfs_entries(parent, base_entry_stuff, uid, gid);
|
||||||
ihk_ikc_spinlock_unlock(&procfs_file_list_lock, irqflag);
|
up(&procfs_file_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -481,14 +476,13 @@ procfs_init(int osnum)
|
|||||||
void
|
void
|
||||||
procfs_exit(int osnum)
|
procfs_exit(int osnum)
|
||||||
{
|
{
|
||||||
unsigned long irqflag;
|
|
||||||
struct procfs_list_entry *e;
|
struct procfs_list_entry *e;
|
||||||
|
|
||||||
irqflag = ihk_ikc_spinlock_lock(&procfs_file_list_lock);
|
down(&procfs_file_list_lock);
|
||||||
e = find_base_entry(osnum);
|
e = find_base_entry(osnum);
|
||||||
if(e)
|
if(e)
|
||||||
delete_procfs_entries(e);
|
delete_procfs_entries(e);
|
||||||
ihk_ikc_spinlock_unlock(&procfs_file_list_lock, irqflag);
|
up(&procfs_file_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user