Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_descrip.c
Show First 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | static MALLOC_DEFINE(M_FILEDESC_TO_LEADER, "filedesc_to_leader", | ||||
"file desc to leader structures"); | "file desc to leader structures"); | ||||
static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures"); | static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures"); | ||||
MALLOC_DEFINE(M_FILECAPS, "filecaps", "descriptor capabilities"); | MALLOC_DEFINE(M_FILECAPS, "filecaps", "descriptor capabilities"); | ||||
MALLOC_DECLARE(M_FADVISE); | MALLOC_DECLARE(M_FADVISE); | ||||
static __read_mostly uma_zone_t file_zone; | static __read_mostly uma_zone_t file_zone; | ||||
static __read_mostly uma_zone_t filedesc0_zone; | static __read_mostly uma_zone_t filedesc0_zone; | ||||
static __read_mostly uma_zone_t pwd_zone; | __read_mostly uma_zone_t pwd_zone; | ||||
static __read_mostly smr_t pwd_smr; | VFS_SMR_DECLARE; | ||||
static int closefp(struct filedesc *fdp, int fd, struct file *fp, | static int closefp(struct filedesc *fdp, int fd, struct file *fp, | ||||
struct thread *td, int holdleaders); | struct thread *td, int holdleaders); | ||||
static int fd_first_free(struct filedesc *fdp, int low, int size); | static int fd_first_free(struct filedesc *fdp, int low, int size); | ||||
static int fd_last_used(struct filedesc *fdp, int size); | static int fd_last_used(struct filedesc *fdp, int size); | ||||
static void fdgrowtable(struct filedesc *fdp, int nfd); | static void fdgrowtable(struct filedesc *fdp, int nfd); | ||||
static void fdgrowtable_exp(struct filedesc *fdp, int nfd); | static void fdgrowtable_exp(struct filedesc *fdp, int nfd); | ||||
static void fdunused(struct filedesc *fdp, int fd); | static void fdunused(struct filedesc *fdp, int fd); | ||||
▲ Show 20 Lines • Show All 3,226 Lines • ▼ Show 20 Lines | |||||
struct pwd * | struct pwd * | ||||
pwd_hold(struct thread *td) | pwd_hold(struct thread *td) | ||||
{ | { | ||||
struct filedesc *fdp; | struct filedesc *fdp; | ||||
struct pwd *pwd; | struct pwd *pwd; | ||||
fdp = td->td_proc->p_fd; | fdp = td->td_proc->p_fd; | ||||
smr_enter(pwd_smr); | vfs_smr_enter(); | ||||
for (;;) { | for (;;) { | ||||
pwd = smr_entered_load(&fdp->fd_pwd, pwd_smr); | pwd = smr_entered_load(&fdp->fd_pwd, VFS_SMR()); | ||||
MPASS(pwd != NULL); | MPASS(pwd != NULL); | ||||
if (refcount_acquire_if_not_zero(&pwd->pwd_refcount)) | if (refcount_acquire_if_not_zero(&pwd->pwd_refcount)) | ||||
break; | break; | ||||
kib: I am still surprised with such loops. Don't you need yield sometimes ? | |||||
Done Inline ActionsIf worrying about excessive looping, I think the right solution is to do the above once and in case of failure take the lock. mjg: If worrying about excessive looping, I think the right solution is to do the above once and in… | |||||
Not Done Inline ActionsMy concern that if we are on UP and mutator is preempted by this loop at the unlucky moment, system can be livelocked. kib: My concern that if we are on UP and mutator is preempted by this loop at the unlucky moment… | |||||
} | } | ||||
smr_exit(pwd_smr); | vfs_smr_exit(); | ||||
return (pwd); | return (pwd); | ||||
} | } | ||||
struct pwd * | |||||
pwd_get_smr(void) | |||||
{ | |||||
struct pwd *pwd; | |||||
pwd = smr_entered_load(&curproc->p_fd->fd_pwd, VFS_SMR()); | |||||
MPASS(pwd != NULL); | |||||
return (pwd); | |||||
} | |||||
static struct pwd * | static struct pwd * | ||||
pwd_alloc(void) | pwd_alloc(void) | ||||
{ | { | ||||
struct pwd *pwd; | struct pwd *pwd; | ||||
pwd = uma_zalloc_smr(pwd_zone, M_WAITOK); | pwd = uma_zalloc_smr(pwd_zone, M_WAITOK); | ||||
bzero(pwd, sizeof(*pwd)); | bzero(pwd, sizeof(*pwd)); | ||||
refcount_init(&pwd->pwd_refcount, 1); | refcount_init(&pwd->pwd_refcount, 1); | ||||
▲ Show 20 Lines • Show All 990 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
file_zone = uma_zcreate("Files", sizeof(struct file), NULL, NULL, | file_zone = uma_zcreate("Files", sizeof(struct file), NULL, NULL, | ||||
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); | NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); | ||||
filedesc0_zone = uma_zcreate("filedesc0", sizeof(struct filedesc0), | filedesc0_zone = uma_zcreate("filedesc0", sizeof(struct filedesc0), | ||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | ||||
pwd_zone = uma_zcreate("PWD", sizeof(struct pwd), NULL, NULL, | pwd_zone = uma_zcreate("PWD", sizeof(struct pwd), NULL, NULL, | ||||
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_SMR); | NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_SMR); | ||||
pwd_smr = uma_zone_get_smr(pwd_zone); | /* | ||||
* XXXMJG this is a temporary hack due to boot ordering issues against | |||||
* the vnode zone. | |||||
*/ | |||||
vfs_smr = uma_zone_get_smr(pwd_zone); | |||||
mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF); | mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF); | ||||
} | } | ||||
SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL); | SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL); | ||||
/*-------------------------------------------------------------------*/ | /*-------------------------------------------------------------------*/ | ||||
static int | static int | ||||
badfo_readwrite(struct file *fp, struct uio *uio, struct ucred *active_cred, | badfo_readwrite(struct file *fp, struct uio *uio, struct ucred *active_cred, | ||||
▲ Show 20 Lines • Show All 216 Lines • Show Last 20 Lines |
I am still surprised with such loops. Don't you need yield sometimes ?