Defer freeing a kevent list until after dropping kqueue locks.
LOR: 185 Submitted by: Matthew Fleming @ Isilon MFC after: 1 week
This commit is contained in:
parent
495072defa
commit
7e3d78ae6d
@ -1218,7 +1218,7 @@ static int
|
||||
kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
|
||||
int waitok)
|
||||
{
|
||||
struct klist *list, *tmp_knhash;
|
||||
struct klist *list, *tmp_knhash, *to_free;
|
||||
u_long tmp_knhashmask;
|
||||
int size;
|
||||
int fd;
|
||||
@ -1226,6 +1226,7 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
|
||||
|
||||
KQ_NOTOWNED(kq);
|
||||
|
||||
to_free = NULL;
|
||||
if (fops->f_isfd) {
|
||||
fd = ident;
|
||||
if (kq->kq_knlistsize <= fd) {
|
||||
@ -1237,13 +1238,13 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
|
||||
return ENOMEM;
|
||||
KQ_LOCK(kq);
|
||||
if (kq->kq_knlistsize > fd) {
|
||||
free(list, M_KQUEUE);
|
||||
to_free = list;
|
||||
list = NULL;
|
||||
} else {
|
||||
if (kq->kq_knlist != NULL) {
|
||||
bcopy(kq->kq_knlist, list,
|
||||
kq->kq_knlistsize * sizeof(*list));
|
||||
free(kq->kq_knlist, M_KQUEUE);
|
||||
to_free = kq->kq_knlist;
|
||||
kq->kq_knlist = NULL;
|
||||
}
|
||||
bzero((caddr_t)list +
|
||||
@ -1265,11 +1266,12 @@ kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident,
|
||||
kq->kq_knhash = tmp_knhash;
|
||||
kq->kq_knhashmask = tmp_knhashmask;
|
||||
} else {
|
||||
free(tmp_knhash, M_KQUEUE);
|
||||
to_free = tmp_knhash;
|
||||
}
|
||||
KQ_UNLOCK(kq);
|
||||
}
|
||||
}
|
||||
free(to_free, M_KQUEUE);
|
||||
|
||||
KQ_NOTOWNED(kq);
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user