Tofu: proper cleanup of device files when mcexec gets killed
Change-Id: I6cb0290f72d96682700f945b29585e132e525ac1
This commit is contained in:
committed by
Masamichi Takagi
parent
1918df7765
commit
e5f4a4e87d
@ -2,6 +2,7 @@
|
|||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#include <linux/mm_types.h>
|
#include <linux/mm_types.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#if KERNEL_VERSION(4, 11, 0) <= LINUX_VERSION_CODE
|
#if KERNEL_VERSION(4, 11, 0) <= LINUX_VERSION_CODE
|
||||||
#include <linux/sched/task_stack.h>
|
#include <linux/sched/task_stack.h>
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
|
||||||
@ -27,6 +28,14 @@ void *vdso_end;
|
|||||||
static struct vm_special_mapping (*vdso_spec)[2];
|
static struct vm_special_mapping (*vdso_spec)[2];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Tofu CQ and barrier gate release functions */
|
||||||
|
struct file_operations *mcctrl_tof_utofu_procfs_ops_cq;
|
||||||
|
int (*mcctrl_tof_utofu_release_cq)(struct inode *inode,
|
||||||
|
struct file *filp);
|
||||||
|
struct file_operations *mcctrl_tof_utofu_procfs_ops_bch;
|
||||||
|
int (*mcctrl_tof_utofu_release_bch)(struct inode *inode,
|
||||||
|
struct file *filp);
|
||||||
|
|
||||||
int arch_symbols_init(void)
|
int arch_symbols_init(void)
|
||||||
{
|
{
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
|
||||||
@ -43,6 +52,26 @@ int arch_symbols_init(void)
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mcctrl_tof_utofu_procfs_ops_cq =
|
||||||
|
(void *)kallsyms_lookup_name("tof_utofu_procfs_ops_cq");
|
||||||
|
if (WARN_ON(!mcctrl_tof_utofu_procfs_ops_cq))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
mcctrl_tof_utofu_procfs_ops_bch =
|
||||||
|
(void *)kallsyms_lookup_name("tof_utofu_procfs_ops_bch");
|
||||||
|
if (WARN_ON(!mcctrl_tof_utofu_procfs_ops_bch))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
mcctrl_tof_utofu_release_cq =
|
||||||
|
(void *)kallsyms_lookup_name("tof_utofu_release_cq");
|
||||||
|
if (WARN_ON(!mcctrl_tof_utofu_release_cq))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
mcctrl_tof_utofu_release_bch =
|
||||||
|
(void *)kallsyms_lookup_name("tof_utofu_release_bch");
|
||||||
|
if (WARN_ON(!mcctrl_tof_utofu_release_bch))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,3 +446,106 @@ long arch_switch_ctx(struct uti_switch_ctx_desc *desc)
|
|||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tofu CQ and BCH release handlers
|
||||||
|
*/
|
||||||
|
int __mcctrl_tof_utofu_release_cq(struct inode *inode, struct file *filp);
|
||||||
|
int __mcctrl_tof_utofu_release_bch(struct inode *inode, struct file *filp);
|
||||||
|
|
||||||
|
void mcctrl_tofu_hijack_release_handlers(void)
|
||||||
|
{
|
||||||
|
mcctrl_tof_utofu_procfs_ops_cq->release =
|
||||||
|
__mcctrl_tof_utofu_release_cq;
|
||||||
|
mcctrl_tof_utofu_procfs_ops_bch->release =
|
||||||
|
__mcctrl_tof_utofu_release_bch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mcctrl_tofu_restore_release_handlers(void)
|
||||||
|
{
|
||||||
|
mcctrl_tof_utofu_procfs_ops_cq->release =
|
||||||
|
mcctrl_tof_utofu_release_cq;
|
||||||
|
mcctrl_tof_utofu_procfs_ops_bch->release =
|
||||||
|
mcctrl_tof_utofu_release_bch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __mcctrl_tof_utofu_release_handler(struct inode *inode, struct file *filp,
|
||||||
|
int (*__release_func)(struct inode *inode, struct file *filp))
|
||||||
|
{
|
||||||
|
struct mcctrl_usrdata *usrdata;
|
||||||
|
struct mcctrl_file_to_pidfd *f2pfd;
|
||||||
|
struct mcctrl_per_proc_data *ppd;
|
||||||
|
struct ikc_scd_packet isp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dprintk("%s: current PID: %d, comm: %s \n",
|
||||||
|
__func__, task_tgid_vnr(current), current->comm);
|
||||||
|
|
||||||
|
f2pfd = mcctrl_file_to_pidfd_hash_lookup(filp, current->group_leader);
|
||||||
|
if (!f2pfd) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintk("%s: current PID: %d, PID: %d, fd: %d ...\n",
|
||||||
|
__func__, task_tgid_vnr(current), f2pfd->pid, f2pfd->fd);
|
||||||
|
usrdata = ihk_host_os_get_usrdata(f2pfd->os);
|
||||||
|
|
||||||
|
/* Look up per-process structure */
|
||||||
|
ppd = mcctrl_get_per_proc_data(usrdata, f2pfd->pid);
|
||||||
|
if (!ppd) {
|
||||||
|
pr_err("%s: PID: %d, fd: %d no PPD\n",
|
||||||
|
__func__, f2pfd->pid, f2pfd->fd);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintk("%s: PID: %d, fd: %d PPD OK\n",
|
||||||
|
__func__, f2pfd->pid, f2pfd->fd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are in release() due to the process being killed,
|
||||||
|
* or because the application didn't close the file properly.
|
||||||
|
* Ask McKernel to clean up this fd.
|
||||||
|
*/
|
||||||
|
isp.msg = SCD_MSG_CLEANUP_FD;
|
||||||
|
isp.pid = f2pfd->pid;
|
||||||
|
isp.arg = f2pfd->fd;
|
||||||
|
|
||||||
|
ret = mcctrl_ikc_send_wait(f2pfd->os, ppd->ikc_target_cpu,
|
||||||
|
&isp, -20, NULL, NULL, 0);
|
||||||
|
if (ret != 0) {
|
||||||
|
dprintk("%s: WARNING: failed to send IKC msg: %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
mcctrl_file_to_pidfd_hash_remove(filp, f2pfd->os,
|
||||||
|
current->group_leader, f2pfd->fd);
|
||||||
|
|
||||||
|
mcctrl_put_per_proc_data(ppd);
|
||||||
|
|
||||||
|
/* Do not call into Linux driver if timed out in SIGKILL.. */
|
||||||
|
if (ret == -ETIME && __fatal_signal_pending(current)) {
|
||||||
|
pr_err("%s: WARNING: failed to send IKC msg in SIGKILL: %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
goto out_no_release;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
dprintk("%s: current PID: %d, comm: %s -> calling release\n",
|
||||||
|
__func__, task_tgid_vnr(current), current->comm);
|
||||||
|
return __release_func(inode, filp);
|
||||||
|
|
||||||
|
out_no_release:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __mcctrl_tof_utofu_release_cq(struct inode *inode, struct file *filp)
|
||||||
|
{
|
||||||
|
return __mcctrl_tof_utofu_release_handler(inode, filp,
|
||||||
|
mcctrl_tof_utofu_release_cq);
|
||||||
|
}
|
||||||
|
|
||||||
|
int __mcctrl_tof_utofu_release_bch(struct inode *inode, struct file *filp)
|
||||||
|
{
|
||||||
|
return __mcctrl_tof_utofu_release_handler(inode, filp,
|
||||||
|
mcctrl_tof_utofu_release_bch);
|
||||||
|
}
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
#include <linux/semaphore.h>
|
#include <linux/semaphore.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/delay.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>
|
||||||
@ -378,6 +379,7 @@ static void release_handler(ihk_os_t os, void *param)
|
|||||||
int os_ind = ihk_host_os_get_index(os);
|
int os_ind = ihk_host_os_get_index(os);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct host_thread *thread;
|
struct host_thread *thread;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Finalize FS switch for uti threads */
|
/* Finalize FS switch for uti threads */
|
||||||
write_lock_irqsave(&host_thread_lock, flags);
|
write_lock_irqsave(&host_thread_lock, flags);
|
||||||
@ -399,7 +401,13 @@ static void release_handler(ihk_os_t os, void *param)
|
|||||||
|
|
||||||
dprintk("%s: SCD_MSG_CLEANUP_PROCESS, info: %p, cpu: %d\n",
|
dprintk("%s: SCD_MSG_CLEANUP_PROCESS, info: %p, cpu: %d\n",
|
||||||
__FUNCTION__, info, info->cpu);
|
__FUNCTION__, info, info->cpu);
|
||||||
mcctrl_ikc_send(os, info->cpu, &isp);
|
ret = mcctrl_ikc_send_wait(os, info->cpu,
|
||||||
|
&isp, -20, NULL, NULL, 0);
|
||||||
|
if (ret != 0) {
|
||||||
|
printk("%s: WARNING: failed to send IKC msg: %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
}
|
||||||
|
|
||||||
if (os_ind >= 0) {
|
if (os_ind >= 0) {
|
||||||
delete_pid_entry(os_ind, info->pid);
|
delete_pid_entry(os_ind, info->pid);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,6 +50,7 @@ extern void procfs_exit(int);
|
|||||||
extern void uti_attr_finalize(void);
|
extern void uti_attr_finalize(void);
|
||||||
extern void binfmt_mcexec_init(void);
|
extern void binfmt_mcexec_init(void);
|
||||||
extern void binfmt_mcexec_exit(void);
|
extern void binfmt_mcexec_exit(void);
|
||||||
|
extern void mcctrl_file_to_pidfd_hash_init(void);
|
||||||
|
|
||||||
extern int mcctrl_os_read_cpu_register(ihk_os_t os, int cpu,
|
extern int mcctrl_os_read_cpu_register(ihk_os_t os, int cpu,
|
||||||
struct ihk_os_cpu_register *desc);
|
struct ihk_os_cpu_register *desc);
|
||||||
@ -57,6 +58,11 @@ extern int mcctrl_os_write_cpu_register(ihk_os_t os, int cpu,
|
|||||||
struct ihk_os_cpu_register *desc);
|
struct ihk_os_cpu_register *desc);
|
||||||
extern int mcctrl_get_request_os_cpu(ihk_os_t os, int *cpu);
|
extern int mcctrl_get_request_os_cpu(ihk_os_t os, int *cpu);
|
||||||
|
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
extern void mcctrl_tofu_hijack_release_handlers(void);
|
||||||
|
extern void mcctrl_tofu_restore_release_handlers(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
static long mcctrl_ioctl(ihk_os_t os, unsigned int request, void *priv,
|
static long mcctrl_ioctl(ihk_os_t os, unsigned int request, void *priv,
|
||||||
unsigned long arg, struct file *file)
|
unsigned long arg, struct file *file)
|
||||||
{
|
{
|
||||||
@ -319,10 +325,15 @@ static int __init mcctrl_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
binfmt_mcexec_init();
|
binfmt_mcexec_init();
|
||||||
|
mcctrl_file_to_pidfd_hash_init();
|
||||||
|
|
||||||
if ((ret = symbols_init()))
|
if ((ret = symbols_init()))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
mcctrl_tofu_hijack_release_handlers();
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((ret = ihk_host_register_os_notifier(&mcctrl_os_notifier)) != 0) {
|
if ((ret = ihk_host_register_os_notifier(&mcctrl_os_notifier)) != 0) {
|
||||||
printk("mcctrl: error: registering OS notifier\n");
|
printk("mcctrl: error: registering OS notifier\n");
|
||||||
goto error;
|
goto error;
|
||||||
@ -345,6 +356,9 @@ static void __exit mcctrl_exit(void)
|
|||||||
|
|
||||||
binfmt_mcexec_exit();
|
binfmt_mcexec_exit();
|
||||||
uti_attr_finalize();
|
uti_attr_finalize();
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
mcctrl_tofu_restore_release_handlers();
|
||||||
|
#endif
|
||||||
|
|
||||||
printk("mcctrl: unregistered.\n");
|
printk("mcctrl: unregistered.\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,8 +148,29 @@ int mcctrl_ikc_send_wait(ihk_os_t os, int cpu, struct ikc_scd_packet *pisp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
ret = wait_event_interruptible_timeout(desc->wq,
|
/*
|
||||||
desc->status, timeout);
|
* Negative timeout indicates busy waiting, which can be used
|
||||||
|
* in situations where wait_event_interruptible_XXX() would
|
||||||
|
* fail, e.g., in a signal handler, at the time the process
|
||||||
|
* is being killed, etc.
|
||||||
|
*/
|
||||||
|
if (timeout < 0) {
|
||||||
|
unsigned long timeout_jiffies =
|
||||||
|
jiffies + msecs_to_jiffies(timeout * -1);
|
||||||
|
ret = -ETIME;
|
||||||
|
|
||||||
|
while (time_before(jiffies, timeout_jiffies)) {
|
||||||
|
schedule();
|
||||||
|
if (READ_ONCE(desc->status)) {
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = wait_event_interruptible_timeout(desc->wq,
|
||||||
|
desc->status, msecs_to_jiffies(timeout));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = wait_event_interruptible(desc->wq, desc->status);
|
ret = wait_event_interruptible(desc->wq, desc->status);
|
||||||
}
|
}
|
||||||
@ -211,6 +232,8 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
|||||||
case SCD_MSG_PROCFS_ANSWER:
|
case SCD_MSG_PROCFS_ANSWER:
|
||||||
case SCD_MSG_REMOTE_PAGE_FAULT_ANSWER:
|
case SCD_MSG_REMOTE_PAGE_FAULT_ANSWER:
|
||||||
case SCD_MSG_CPU_RW_REG_RESP:
|
case SCD_MSG_CPU_RW_REG_RESP:
|
||||||
|
case SCD_MSG_CLEANUP_PROCESS_RESP:
|
||||||
|
case SCD_MSG_CLEANUP_FD_RESP:
|
||||||
mcctrl_wakeup_cb(__os, pisp);
|
mcctrl_wakeup_cb(__os, pisp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@ -58,7 +58,8 @@
|
|||||||
#define SCD_MSG_SEND_SIGNAL 0x7
|
#define SCD_MSG_SEND_SIGNAL 0x7
|
||||||
#define SCD_MSG_SEND_SIGNAL_ACK 0x8
|
#define SCD_MSG_SEND_SIGNAL_ACK 0x8
|
||||||
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
||||||
#define SCD_MSG_GET_VDSO_INFO 0xa
|
#define SCD_MSG_CLEANUP_PROCESS_RESP 0xa
|
||||||
|
#define SCD_MSG_GET_VDSO_INFO 0xb
|
||||||
|
|
||||||
//#define SCD_MSG_GET_CPU_MAPPING 0xc
|
//#define SCD_MSG_GET_CPU_MAPPING 0xc
|
||||||
//#define SCD_MSG_REPLY_GET_CPU_MAPPING 0xd
|
//#define SCD_MSG_REPLY_GET_CPU_MAPPING 0xd
|
||||||
@ -104,6 +105,8 @@
|
|||||||
|
|
||||||
#define SCD_MSG_CPU_RW_REG 0x52
|
#define SCD_MSG_CPU_RW_REG 0x52
|
||||||
#define SCD_MSG_CPU_RW_REG_RESP 0x53
|
#define SCD_MSG_CPU_RW_REG_RESP 0x53
|
||||||
|
#define SCD_MSG_CLEANUP_FD 0x54
|
||||||
|
#define SCD_MSG_CLEANUP_FD_RESP 0x55
|
||||||
|
|
||||||
#define SCD_MSG_FUTEX_WAKE 0x60
|
#define SCD_MSG_FUTEX_WAKE 0x60
|
||||||
|
|
||||||
@ -556,4 +559,29 @@ struct uti_futex_resp {
|
|||||||
int done;
|
int done;
|
||||||
wait_queue_head_t wq;
|
wait_queue_head_t wq;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hash table to keep track of files and related processes
|
||||||
|
* and file descriptors.
|
||||||
|
* NOTE: Used for Tofu driver release handlers.
|
||||||
|
*/
|
||||||
|
#define MCCTRL_FILE_2_PIDFD_HASH_SHIFT 4
|
||||||
|
#define MCCTRL_FILE_2_PIDFD_HASH_SIZE (1 << MCCTRL_FILE_2_PIDFD_HASH_SHIFT)
|
||||||
|
#define MCCTRL_FILE_2_PIDFD_HASH_MASK (MCCTRL_FILE_2_PIDFD_HASH_SIZE - 1)
|
||||||
|
|
||||||
|
struct mcctrl_file_to_pidfd {
|
||||||
|
struct file *filp;
|
||||||
|
ihk_os_t os;
|
||||||
|
struct task_struct *group_leader;
|
||||||
|
int pid;
|
||||||
|
int fd;
|
||||||
|
struct list_head hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
int mcctrl_file_to_pidfd_hash_insert(struct file *filp,
|
||||||
|
ihk_os_t os, int pid, struct task_struct *group_leader, int fd);
|
||||||
|
struct mcctrl_file_to_pidfd *mcctrl_file_to_pidfd_hash_lookup(
|
||||||
|
struct file *filp, struct task_struct *group_leader);
|
||||||
|
int mcctrl_file_to_pidfd_hash_remove(struct file *filp,
|
||||||
|
ihk_os_t os, struct task_struct *group_leader, int fd);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1843,6 +1843,136 @@ static long pager_call(ihk_os_t os, struct syscall_request *req)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct list_head mcctrl_file_to_pidfd_hash[MCCTRL_FILE_2_PIDFD_HASH_SIZE];
|
||||||
|
spinlock_t mcctrl_file_to_pidfd_hash_lock;
|
||||||
|
|
||||||
|
void mcctrl_file_to_pidfd_hash_init(void)
|
||||||
|
{
|
||||||
|
int hash;
|
||||||
|
spin_lock_init(&mcctrl_file_to_pidfd_hash_lock);
|
||||||
|
|
||||||
|
for (hash = 0; hash < MCCTRL_FILE_2_PIDFD_HASH_SIZE; ++hash) {
|
||||||
|
INIT_LIST_HEAD(&mcctrl_file_to_pidfd_hash[hash]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mcctrl_file_to_pidfd_hash_insert(struct file *filp,
|
||||||
|
ihk_os_t os, int pid, struct task_struct *group_leader, int fd)
|
||||||
|
{
|
||||||
|
unsigned long irqflags;
|
||||||
|
struct mcctrl_file_to_pidfd *file2pidfd_iter;
|
||||||
|
struct mcctrl_file_to_pidfd *file2pidfd;
|
||||||
|
int hash = (int)((unsigned long)filp &
|
||||||
|
(unsigned long)MCCTRL_FILE_2_PIDFD_HASH_MASK);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
file2pidfd = kmalloc(sizeof(*file2pidfd), GFP_ATOMIC);
|
||||||
|
if (!file2pidfd)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
file2pidfd->filp = filp;
|
||||||
|
file2pidfd->os = os;
|
||||||
|
file2pidfd->pid = pid;
|
||||||
|
file2pidfd->group_leader = group_leader;
|
||||||
|
file2pidfd->fd = fd;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&mcctrl_file_to_pidfd_hash_lock, irqflags);
|
||||||
|
list_for_each_entry(file2pidfd_iter,
|
||||||
|
&mcctrl_file_to_pidfd_hash[hash], hash) {
|
||||||
|
if (file2pidfd_iter->filp == filp) {
|
||||||
|
printk("%s: WARNING: filp: %p, pid: %d, fd: %d exists\n",
|
||||||
|
__func__, filp, pid, fd);
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto free_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_add_tail(&file2pidfd->hash,
|
||||||
|
&mcctrl_file_to_pidfd_hash[hash]);
|
||||||
|
dprintk("%s: filp: %p, pid: %d, fd: %d added\n",
|
||||||
|
__func__, filp, pid, fd);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&mcctrl_file_to_pidfd_hash_lock, irqflags);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
free_out:
|
||||||
|
kfree(file2pidfd);
|
||||||
|
spin_unlock_irqrestore(&mcctrl_file_to_pidfd_hash_lock, irqflags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: lookup relies on group_leader to identify the process
|
||||||
|
* because PIDs might be different across name spaces (e.g.,
|
||||||
|
* when using Docker)
|
||||||
|
*/
|
||||||
|
struct mcctrl_file_to_pidfd *mcctrl_file_to_pidfd_hash_lookup(
|
||||||
|
struct file *filp, struct task_struct *group_leader)
|
||||||
|
{
|
||||||
|
unsigned long irqflags;
|
||||||
|
struct mcctrl_file_to_pidfd *file2pidfd_iter;
|
||||||
|
struct mcctrl_file_to_pidfd *file2pidfd = NULL;
|
||||||
|
int hash = (int)((unsigned long)filp &
|
||||||
|
(unsigned long)MCCTRL_FILE_2_PIDFD_HASH_MASK);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&mcctrl_file_to_pidfd_hash_lock, irqflags);
|
||||||
|
list_for_each_entry(file2pidfd_iter,
|
||||||
|
&mcctrl_file_to_pidfd_hash[hash], hash) {
|
||||||
|
if (file2pidfd_iter->filp == filp &&
|
||||||
|
file2pidfd_iter->group_leader == group_leader) {
|
||||||
|
file2pidfd = file2pidfd_iter;
|
||||||
|
dprintk("%s: filp: %p, pid: %d, fd: %d found\n",
|
||||||
|
__func__, filp, file2pidfd->pid, file2pidfd->fd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&mcctrl_file_to_pidfd_hash_lock, irqflags);
|
||||||
|
|
||||||
|
return file2pidfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mcctrl_file_to_pidfd_hash_remove(struct file *filp,
|
||||||
|
ihk_os_t os, struct task_struct *group_leader, int fd)
|
||||||
|
{
|
||||||
|
unsigned long irqflags;
|
||||||
|
struct mcctrl_file_to_pidfd *file2pidfd_iter;
|
||||||
|
int hash = (int)((unsigned long)filp &
|
||||||
|
(unsigned long)MCCTRL_FILE_2_PIDFD_HASH_MASK);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&mcctrl_file_to_pidfd_hash_lock, irqflags);
|
||||||
|
list_for_each_entry(file2pidfd_iter,
|
||||||
|
&mcctrl_file_to_pidfd_hash[hash], hash) {
|
||||||
|
if (file2pidfd_iter->filp != filp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (file2pidfd_iter->os != os)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (file2pidfd_iter->group_leader != group_leader)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (file2pidfd_iter->fd != fd)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
list_del(&file2pidfd_iter->hash);
|
||||||
|
dprintk("%s: filp: %p, pid: %d, fd: %d removed\n",
|
||||||
|
__func__, filp, file2pidfd_iter->pid, fd);
|
||||||
|
kfree(file2pidfd_iter);
|
||||||
|
goto unlock_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintk("%s: filp: %p, pid: %d, fd: %d couldn't be found\n",
|
||||||
|
__func__, filp, pid, fd);
|
||||||
|
ret = -ENOENT;
|
||||||
|
|
||||||
|
unlock_out:
|
||||||
|
spin_unlock_irqrestore(&mcctrl_file_to_pidfd_hash_lock, irqflags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void __return_syscall(ihk_os_t os, struct ikc_scd_packet *packet,
|
void __return_syscall(ihk_os_t os, struct ikc_scd_packet *packet,
|
||||||
long ret, int stid)
|
long ret, int stid)
|
||||||
{
|
{
|
||||||
@ -1874,18 +2004,14 @@ void __return_syscall(ihk_os_t os, struct ikc_scd_packet *packet,
|
|||||||
res->stid = stid;
|
res->stid = stid;
|
||||||
|
|
||||||
#ifdef ENABLE_TOFU
|
#ifdef ENABLE_TOFU
|
||||||
/* Record PDE_DATA after open()/ioctl() calls for Tofu driver */
|
/* Record PDE_DATA after open() calls for Tofu driver */
|
||||||
if ((packet->req.number == __NR_ioctl && ret == 0) ||
|
if (packet->req.number == __NR_openat && ret > 1) {
|
||||||
(packet->req.number == __NR_openat && ret > 1)) {
|
|
||||||
char *pathbuf, *fullpath;
|
char *pathbuf, *fullpath;
|
||||||
struct fd f;
|
struct fd f;
|
||||||
|
int fd;
|
||||||
|
|
||||||
if (packet->req.number == __NR_ioctl) {
|
fd = ret;
|
||||||
f = fdget(packet->req.args[0]);
|
f = fdget(fd);
|
||||||
}
|
|
||||||
else if (packet->req.number == __NR_openat) {
|
|
||||||
f = fdget(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!f.file) {
|
if (!f.file) {
|
||||||
goto out_notify;
|
goto out_notify;
|
||||||
@ -1903,12 +2029,11 @@ void __return_syscall(ihk_os_t os, struct ikc_scd_packet *packet,
|
|||||||
|
|
||||||
if (!strncmp("/proc/tofu/dev/", fullpath, 15)) {
|
if (!strncmp("/proc/tofu/dev/", fullpath, 15)) {
|
||||||
res->pde_data = PDE_DATA(file_inode(f.file));
|
res->pde_data = PDE_DATA(file_inode(f.file));
|
||||||
dprintk("%s: %s(): fd: %ld, path: %s, PDE_DATA: 0x%lx\n",
|
dprintk("%s: fd: %d, path: %s, PDE_DATA: 0x%lx\n",
|
||||||
__func__,
|
__func__,
|
||||||
packet->req.number == __NR_ioctl ? "ioctl" : "openat",
|
fd,
|
||||||
packet->req.args[0],
|
fullpath,
|
||||||
fullpath,
|
(unsigned long)res->pde_data);
|
||||||
(unsigned long)res->pde_data);
|
|
||||||
dprintk("%s: pgd_index: %ld, pmd_index: %ld, pte_index: %ld\n",
|
dprintk("%s: pgd_index: %ld, pmd_index: %ld, pte_index: %ld\n",
|
||||||
__func__,
|
__func__,
|
||||||
pgd_index((unsigned long)res->pde_data),
|
pgd_index((unsigned long)res->pde_data),
|
||||||
@ -1918,6 +2043,9 @@ void __return_syscall(ihk_os_t os, struct ikc_scd_packet *packet,
|
|||||||
dprintk("CONFIG_ARM64_VA_BITS: %d, PGDIR_SHIFT: %d\n",
|
dprintk("CONFIG_ARM64_VA_BITS: %d, PGDIR_SHIFT: %d\n",
|
||||||
CONFIG_ARM64_VA_BITS, PGDIR_SHIFT);
|
CONFIG_ARM64_VA_BITS, PGDIR_SHIFT);
|
||||||
#endif
|
#endif
|
||||||
|
mcctrl_file_to_pidfd_hash_insert(f.file, os,
|
||||||
|
task_tgid_vnr(current),
|
||||||
|
current->group_leader, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
@ -2330,6 +2458,26 @@ int __do_in_kernel_syscall(ihk_os_t os, struct ikc_scd_packet *packet)
|
|||||||
|
|
||||||
dprintk("%s: system call: %lx\n", __FUNCTION__, sc->args[0]);
|
dprintk("%s: system call: %lx\n", __FUNCTION__, sc->args[0]);
|
||||||
switch (sc->number) {
|
switch (sc->number) {
|
||||||
|
case __NR_close: {
|
||||||
|
struct fd f;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = (int)sc->args[0];
|
||||||
|
if (fd > 2) {
|
||||||
|
f = fdget(fd);
|
||||||
|
|
||||||
|
if (f.file) {
|
||||||
|
mcctrl_file_to_pidfd_hash_remove(f.file, os,
|
||||||
|
current->group_leader, fd);
|
||||||
|
fdput(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error = -ENOSYS;
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case __NR_mmap:
|
case __NR_mmap:
|
||||||
ret = pager_call(os, sc);
|
ret = pager_call(os, sc);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -778,12 +778,36 @@ out_remote_pf:
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCD_MSG_CLEANUP_PROCESS:
|
case SCD_MSG_CLEANUP_PROCESS: {
|
||||||
|
extern int process_cleanup_before_terminate(int pid);
|
||||||
dkprintf("SCD_MSG_CLEANUP_PROCESS pid=%d, thread=0x%llx\n",
|
dkprintf("SCD_MSG_CLEANUP_PROCESS pid=%d, thread=0x%llx\n",
|
||||||
packet->pid, packet->arg);
|
packet->pid, packet->arg);
|
||||||
|
|
||||||
|
pckt.msg = SCD_MSG_CLEANUP_PROCESS_RESP;
|
||||||
|
pckt.err = process_cleanup_before_terminate(packet->pid);
|
||||||
|
pckt.ref = packet->ref;
|
||||||
|
pckt.arg = packet->arg;
|
||||||
|
pckt.reply = packet->reply;
|
||||||
|
syscall_channel_send(resp_channel, &pckt);
|
||||||
terminate_host(packet->pid, (struct thread *)packet->arg);
|
terminate_host(packet->pid, (struct thread *)packet->arg);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SCD_MSG_CLEANUP_FD: {
|
||||||
|
extern int process_cleanup_fd(int pid, int fd);
|
||||||
|
pckt.msg = SCD_MSG_CLEANUP_FD_RESP;
|
||||||
|
pckt.err = process_cleanup_fd(packet->pid, packet->arg);
|
||||||
|
dkprintf("SCD_MSG_CLEANUP_FD pid=%d, fd=%d -> err: %d\n",
|
||||||
|
packet->pid, packet->arg, pckt.err);
|
||||||
|
|
||||||
|
pckt.ref = packet->ref;
|
||||||
|
pckt.arg = packet->arg;
|
||||||
|
pckt.reply = packet->reply;
|
||||||
|
syscall_channel_send(resp_channel, &pckt);
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SCD_MSG_DEBUG_LOG:
|
case SCD_MSG_DEBUG_LOG:
|
||||||
dkprintf("SCD_MSG_DEBUG_LOG code=%lx\n", packet->arg);
|
dkprintf("SCD_MSG_DEBUG_LOG code=%lx\n", packet->arg);
|
||||||
|
|||||||
@ -39,7 +39,8 @@
|
|||||||
#define SCD_MSG_SEND_SIGNAL 0x7
|
#define SCD_MSG_SEND_SIGNAL 0x7
|
||||||
#define SCD_MSG_SEND_SIGNAL_ACK 0x8
|
#define SCD_MSG_SEND_SIGNAL_ACK 0x8
|
||||||
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
#define SCD_MSG_CLEANUP_PROCESS 0x9
|
||||||
#define SCD_MSG_GET_VDSO_INFO 0xa
|
#define SCD_MSG_CLEANUP_PROCESS_RESP 0xa
|
||||||
|
#define SCD_MSG_GET_VDSO_INFO 0xb
|
||||||
|
|
||||||
#define SCD_MSG_GET_CPU_MAPPING 0xc
|
#define SCD_MSG_GET_CPU_MAPPING 0xc
|
||||||
#define SCD_MSG_REPLY_GET_CPU_MAPPING 0xd
|
#define SCD_MSG_REPLY_GET_CPU_MAPPING 0xd
|
||||||
@ -84,6 +85,8 @@
|
|||||||
|
|
||||||
#define SCD_MSG_CPU_RW_REG 0x52
|
#define SCD_MSG_CPU_RW_REG 0x52
|
||||||
#define SCD_MSG_CPU_RW_REG_RESP 0x53
|
#define SCD_MSG_CPU_RW_REG_RESP 0x53
|
||||||
|
#define SCD_MSG_CLEANUP_FD 0x54
|
||||||
|
#define SCD_MSG_CLEANUP_FD_RESP 0x55
|
||||||
|
|
||||||
#define SCD_MSG_FUTEX_WAKE 0x60
|
#define SCD_MSG_FUTEX_WAKE 0x60
|
||||||
|
|
||||||
|
|||||||
@ -1303,10 +1303,8 @@ void terminate(int rc, int sig)
|
|||||||
if (proc->enable_tofu && proc->fd_pde_data[fd]) {
|
if (proc->enable_tofu && proc->fd_pde_data[fd]) {
|
||||||
extern void tof_utofu_release_fd(struct process *proc, int fd);
|
extern void tof_utofu_release_fd(struct process *proc, int fd);
|
||||||
|
|
||||||
if (proc->fd_path[fd]) {
|
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
|
||||||
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
|
__func__, fd, proc->fd_path[fd]);
|
||||||
__func__, fd, proc->fd_path[fd]);
|
|
||||||
}
|
|
||||||
tof_utofu_release_fd(proc, fd);
|
tof_utofu_release_fd(proc, fd);
|
||||||
proc->fd_pde_data[fd] = NULL;
|
proc->fd_pde_data[fd] = NULL;
|
||||||
}
|
}
|
||||||
@ -1487,6 +1485,67 @@ void terminate(int rc, int sig)
|
|||||||
panic("panic");
|
panic("panic");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __process_cleanup_fd(struct process *proc, int fd)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
/* Tofu? */
|
||||||
|
if (proc->enable_tofu) {
|
||||||
|
extern void tof_utofu_release_fd(struct process *proc, int fd);
|
||||||
|
|
||||||
|
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
|
||||||
|
__func__, fd, proc->fd_path[fd]);
|
||||||
|
tof_utofu_release_fd(proc, fd);
|
||||||
|
proc->fd_pde_data[fd] = NULL;
|
||||||
|
|
||||||
|
if (proc->fd_path[fd]) {
|
||||||
|
kfree(proc->fd_path[fd]);
|
||||||
|
proc->fd_path[fd] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_cleanup_fd(int pid, int fd)
|
||||||
|
{
|
||||||
|
struct process *proc;
|
||||||
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
|
|
||||||
|
proc = find_process(pid, &lock);
|
||||||
|
if (!proc) {
|
||||||
|
/* This is normal behavior */
|
||||||
|
dkprintf("%s: PID %d couldn't be found\n", __func__, pid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__process_cleanup_fd(proc, fd);
|
||||||
|
|
||||||
|
process_unlock(proc, &lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_cleanup_before_terminate(int pid)
|
||||||
|
{
|
||||||
|
struct process *proc;
|
||||||
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
proc = find_process(pid, &lock);
|
||||||
|
if (!proc) {
|
||||||
|
/* This is normal behavior */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up PDE file descriptors */
|
||||||
|
for (fd = 2; fd < MAX_FD_PDE; ++fd) {
|
||||||
|
__process_cleanup_fd(proc, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
process_unlock(proc, &lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
terminate_host(int pid, struct thread *thread)
|
terminate_host(int pid, struct thread *thread)
|
||||||
{
|
{
|
||||||
@ -4032,15 +4091,14 @@ SYSCALL_DECLARE(close)
|
|||||||
|
|
||||||
#ifdef ENABLE_TOFU
|
#ifdef ENABLE_TOFU
|
||||||
/* Clear path and PDE data */
|
/* Clear path and PDE data */
|
||||||
if (fd >= 0 && fd < MAX_FD_PDE) {
|
if (thread->proc->enable_tofu &&
|
||||||
|
fd >= 0 && fd < MAX_FD_PDE) {
|
||||||
/* Tofu? */
|
/* Tofu? */
|
||||||
if (thread->proc->fd_pde_data[fd]) {
|
if (thread->proc->fd_pde_data[fd]) {
|
||||||
extern void tof_utofu_release_fd(struct process *proc, int fd);
|
extern void tof_utofu_release_fd(struct process *proc, int fd);
|
||||||
|
|
||||||
if (thread->proc->fd_path[fd]) {
|
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
|
||||||
dkprintf("%s: -> tof_utofu_release_fd() @ fd: %d (%s)\n",
|
__func__, fd, thread->proc->fd_path[fd]);
|
||||||
__func__, fd, thread->proc->fd_path[fd]);
|
|
||||||
}
|
|
||||||
tof_utofu_release_fd(thread->proc, fd);
|
tof_utofu_release_fd(thread->proc, fd);
|
||||||
thread->proc->fd_pde_data[fd] = NULL;
|
thread->proc->fd_pde_data[fd] = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -896,16 +896,18 @@ static void tof_utofu_trans_update(struct tof_utofu_cq *ucq, int stag, uintptr_t
|
|||||||
struct tof_trans_table ent;
|
struct tof_trans_table ent;
|
||||||
uint64_t atomic;
|
uint64_t atomic;
|
||||||
} tmp;
|
} tmp;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
tmp.ent.steering.bits.start = start >> PAGE_SHIFT;
|
tmp.ent.steering.bits.start = start >> PAGE_SHIFT;
|
||||||
tmp.ent.steering.bits.len = len >> PAGE_SHIFT;
|
tmp.ent.steering.bits.len = len >> PAGE_SHIFT;
|
||||||
tmp.ent.steering.bits.ps_code = (pgszbits == PAGE_SHIFT)? TOF_STAG_TRANS_PS_CODE_64KB:TOF_STAG_TRANS_PS_CODE_2MB;
|
tmp.ent.steering.bits.ps_code = (pgszbits == PAGE_SHIFT)? TOF_STAG_TRANS_PS_CODE_64KB:TOF_STAG_TRANS_PS_CODE_2MB;
|
||||||
//atomic64_set((atomic64_t *)&table[stag], tmp.atomic);
|
//atomic64_set((atomic64_t *)&table[stag], tmp.atomic);
|
||||||
ihk_atomic64_set((ihk_atomic64_t *)&table[stag], tmp.atomic);
|
ihk_atomic64_set((ihk_atomic64_t *)&table[stag], tmp.atomic);
|
||||||
|
|
||||||
linux_spin_lock(&ucq->trans.mru_lock);
|
linux_spin_lock_irqsave(&ucq->trans.mru_lock, flags);
|
||||||
tof_utofu_trans_mru_delete(ucq, stag);
|
tof_utofu_trans_mru_delete(ucq, stag);
|
||||||
tof_utofu_trans_mru_insert(ucq, stag, pgszbits, mbpt);
|
tof_utofu_trans_mru_insert(ucq, stag, pgszbits, mbpt);
|
||||||
linux_spin_unlock(&ucq->trans.mru_lock);
|
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1009,6 +1011,7 @@ static int tof_utofu_ioctl_alloc_stag(struct tof_utofu_device *dev, unsigned lon
|
|||||||
uint8_t pgszbits;
|
uint8_t pgszbits;
|
||||||
size_t pgsz;
|
size_t pgsz;
|
||||||
int ret = -ENOTSUPP;
|
int ret = -ENOTSUPP;
|
||||||
|
unsigned long irqflags;
|
||||||
|
|
||||||
ucq = container_of(dev, struct tof_utofu_cq, common);
|
ucq = container_of(dev, struct tof_utofu_cq, common);
|
||||||
if(!ucq->common.enabled){
|
if(!ucq->common.enabled){
|
||||||
@ -1054,9 +1057,9 @@ static int tof_utofu_ioctl_alloc_stag(struct tof_utofu_device *dev, unsigned lon
|
|||||||
#if 1
|
#if 1
|
||||||
/* normal stag */
|
/* normal stag */
|
||||||
int stag;
|
int stag;
|
||||||
linux_spin_lock(&ucq->trans.mru_lock);
|
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
|
||||||
stag = tof_utofu_trans_search(ucq, start, end, pgszbits, readonly);
|
stag = tof_utofu_trans_search(ucq, start, end, pgszbits, readonly);
|
||||||
linux_spin_unlock(&ucq->trans.mru_lock);
|
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
|
||||||
if(stag < 0){
|
if(stag < 0){
|
||||||
struct tof_utofu_mbpt *mbpt = NULL;
|
struct tof_utofu_mbpt *mbpt = NULL;
|
||||||
stag = tof_utofu_reserve_stag(ucq, readonly);
|
stag = tof_utofu_reserve_stag(ucq, readonly);
|
||||||
@ -1304,6 +1307,7 @@ static int tof_utofu_ioctl_free_stags(struct tof_utofu_device *dev, unsigned lon
|
|||||||
struct tof_free_stags req;
|
struct tof_free_stags req;
|
||||||
int i, no_free_cnt = 0, ret;
|
int i, no_free_cnt = 0, ret;
|
||||||
int stags[1024];
|
int stags[1024];
|
||||||
|
unsigned long irqflags;
|
||||||
|
|
||||||
ucq = container_of(dev, struct tof_utofu_cq, common);
|
ucq = container_of(dev, struct tof_utofu_cq, common);
|
||||||
|
|
||||||
@ -1325,9 +1329,9 @@ static int tof_utofu_ioctl_free_stags(struct tof_utofu_device *dev, unsigned lon
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < req.num; i++){
|
for(i = 0; i < req.num; i++){
|
||||||
linux_spin_lock(&ucq->trans.mru_lock);
|
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
|
||||||
ret = tof_utofu_free_stag(ucq, stags[i]);
|
ret = tof_utofu_free_stag(ucq, stags[i]);
|
||||||
linux_spin_unlock(&ucq->trans.mru_lock);
|
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
|
||||||
if(ret == 0){
|
if(ret == 0){
|
||||||
stags[i] = -1;
|
stags[i] = -1;
|
||||||
}
|
}
|
||||||
@ -1372,6 +1376,7 @@ void tof_utofu_release_cq(void *pde_data)
|
|||||||
struct tof_utofu_cq *ucq;
|
struct tof_utofu_cq *ucq;
|
||||||
int stag;
|
int stag;
|
||||||
struct tof_utofu_device *dev;
|
struct tof_utofu_device *dev;
|
||||||
|
unsigned long irqflags;
|
||||||
|
|
||||||
dev = (struct tof_utofu_device *)pde_data;
|
dev = (struct tof_utofu_device *)pde_data;
|
||||||
ucq = container_of(dev, struct tof_utofu_cq, common);
|
ucq = container_of(dev, struct tof_utofu_cq, common);
|
||||||
@ -1383,9 +1388,9 @@ void tof_utofu_release_cq(void *pde_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (stag = 0; stag < TOF_UTOFU_NUM_STAG(ucq->num_stag); stag++) {
|
for (stag = 0; stag < TOF_UTOFU_NUM_STAG(ucq->num_stag); stag++) {
|
||||||
linux_spin_lock(&ucq->trans.mru_lock);
|
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
|
||||||
tof_utofu_free_stag(ucq, stag);
|
tof_utofu_free_stag(ucq, stag);
|
||||||
linux_spin_unlock(&ucq->trans.mru_lock);
|
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
dkprintf("%s: UCQ (pde: %p) TNI %d, CQ %d\n",
|
dkprintf("%s: UCQ (pde: %p) TNI %d, CQ %d\n",
|
||||||
@ -1911,6 +1916,8 @@ static int tof_utofu_disable_bch(struct tof_utofu_bg *ubg){
|
|||||||
//tof_smmu_release_ipa_bg(ubg->tni, ubg->bgid, ubg->bch.iova, TOF_ICC_BCH_DMA_ALIGN);
|
//tof_smmu_release_ipa_bg(ubg->tni, ubg->bgid, ubg->bch.iova, TOF_ICC_BCH_DMA_ALIGN);
|
||||||
//put_page(ubg->bch.page);
|
//put_page(ubg->bch.page);
|
||||||
ubg->bch.enabled = false;
|
ubg->bch.enabled = false;
|
||||||
|
smp_mb();
|
||||||
|
dkprintf("%s: tni=%d bgid=%d\n", __func__, ubg->tni, ubg->bgid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2084,11 +2091,15 @@ void tof_utofu_release_fd(struct process *proc, int fd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstr((const char *)proc->fd_path, "cq")) {
|
if (strstr((const char *)proc->fd_path[fd], "cq")) {
|
||||||
|
dkprintf("%s: PID: %d, fd: %d -> release CQ\n",
|
||||||
|
__func__, proc->pid, fd);
|
||||||
tof_utofu_release_cq(proc->fd_pde_data[fd]);
|
tof_utofu_release_cq(proc->fd_pde_data[fd]);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strstr((const char *)proc->fd_path, "bch")) {
|
else if (strstr((const char *)proc->fd_path[fd], "bch")) {
|
||||||
|
dkprintf("%s: PID: %d, fd: %d -> release BCH\n",
|
||||||
|
__func__, proc->pid, fd);
|
||||||
tof_utofu_release_bch(proc->fd_pde_data[fd]);
|
tof_utofu_release_bch(proc->fd_pde_data[fd]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user