Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/src/linux_compat.c
Show First 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
#include <linux/uaccess.h> | #include <linux/uaccess.h> | ||||
#include <linux/list.h> | #include <linux/list.h> | ||||
#include <linux/kthread.h> | #include <linux/kthread.h> | ||||
#include <linux/kernel.h> | #include <linux/kernel.h> | ||||
#include <linux/compat.h> | #include <linux/compat.h> | ||||
#include <linux/poll.h> | #include <linux/poll.h> | ||||
#include <linux/smp.h> | #include <linux/smp.h> | ||||
#include <linux/wait_bit.h> | #include <linux/wait_bit.h> | ||||
#include <linux/rcupdate.h> | |||||
#if defined(__i386__) || defined(__amd64__) | #if defined(__i386__) || defined(__amd64__) | ||||
#include <asm/smp.h> | #include <asm/smp.h> | ||||
#endif | #endif | ||||
SYSCTL_NODE(_compat, OID_AUTO, linuxkpi, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | SYSCTL_NODE(_compat, OID_AUTO, linuxkpi, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | ||||
"LinuxKPI parameters"); | "LinuxKPI parameters"); | ||||
▲ Show 20 Lines • Show All 366 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void | void | ||||
linux_file_free(struct linux_file *filp) | linux_file_free(struct linux_file *filp) | ||||
{ | { | ||||
if (filp->_file == NULL) { | if (filp->_file == NULL) { | ||||
if (filp->f_shmem != NULL) | if (filp->f_shmem != NULL) | ||||
vm_object_deallocate(filp->f_shmem); | vm_object_deallocate(filp->f_shmem); | ||||
kfree(filp); | kfree_rcu(filp, rcu); | ||||
} else { | } else { | ||||
/* | /* | ||||
* The close method of the character device or file | * The close method of the character device or file | ||||
* will free the linux_file structure: | * will free the linux_file structure: | ||||
*/ | */ | ||||
_fdrop(filp->_file, curthread); | _fdrop(filp->_file, curthread); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,049 Lines • ▼ Show 20 Lines | if (release != NULL) | ||||
error = -OPW(file, td, release(filp->f_vnode, filp)); | error = -OPW(file, td, release(filp->f_vnode, filp)); | ||||
funsetown(&filp->f_sigio); | funsetown(&filp->f_sigio); | ||||
if (filp->f_vnode != NULL) | if (filp->f_vnode != NULL) | ||||
vdrop(filp->f_vnode); | vdrop(filp->f_vnode); | ||||
linux_drop_fop(ldev); | linux_drop_fop(ldev); | ||||
ldev = filp->f_cdev; | ldev = filp->f_cdev; | ||||
if (ldev != NULL) | if (ldev != NULL) | ||||
linux_cdev_deref(ldev); | linux_cdev_deref(ldev); | ||||
linux_synchronize_rcu(RCU_TYPE_REGULAR); | |||||
hselasky: Looking closer at this you need to call:
synchronize_rcu()
because the protection given by… | |||||
kfree(filp); | kfree(filp); | ||||
Not Done Inline ActionsI think the right place to put the barrier is right before kfree(), because the release function is important removing the file entry from the list which the DRM driver is iterating. Also you don't need a barrier on the SLEEPABLE type. hselasky: I think the right place to put the barrier is right before kfree(), because the release… | |||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
linux_file_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *cred, | linux_file_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *cred, | ||||
struct thread *td) | struct thread *td) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,142 Lines • Show Last 20 Lines |
Looking closer at this you need to call:
synchronize_rcu()
because the protection given by rcu_barrier is not strong enough.