vhost: try to shrink pfdset when fdset_add fails
fdset_add increments pfdset->num, but fdset_del doesn't decrement
pfdset->num, so if we call fdset_add then fdset_del in a loop without
calling fdset_shrink, we can easily exceed MAX_FDS with only a few
number of fds used.
So my solution is simply to call fdset_shrink in fdset_add when it
exceeds MAX_FDS.
Because fdset_shrink and fdset_add locks pfdset->fd_mutex we can't
call fdset_shrink inside fdset_add because that would cause a dead
lock, so this patch split fdset_shrink in two, fdset_shrink and
fdset_shrink_nolock.
Fixes: 59317cef24
("vhost: allow many vhost-user ports")
Cc: stable@dpdk.org
Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com>
This commit is contained in:
parent
6e2ea132ab
commit
1b815b8959
@ -65,17 +65,12 @@ fdset_move(struct fdset *pfdset, int dst, int src)
|
||||
pfdset->rwfds[dst] = pfdset->rwfds[src];
|
||||
}
|
||||
|
||||
/*
|
||||
* Find deleted fd entries and remove them
|
||||
*/
|
||||
static void
|
||||
fdset_shrink(struct fdset *pfdset)
|
||||
fdset_shrink_nolock(struct fdset *pfdset)
|
||||
{
|
||||
int i;
|
||||
int last_valid_idx = get_last_valid_idx(pfdset, pfdset->num - 1);
|
||||
|
||||
pthread_mutex_lock(&pfdset->fd_mutex);
|
||||
|
||||
for (i = 0; i < last_valid_idx; i++) {
|
||||
if (pfdset->fd[i].fd != -1)
|
||||
continue;
|
||||
@ -84,7 +79,16 @@ fdset_shrink(struct fdset *pfdset)
|
||||
last_valid_idx = get_last_valid_idx(pfdset, last_valid_idx - 1);
|
||||
}
|
||||
pfdset->num = last_valid_idx + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find deleted fd entries and remove them
|
||||
*/
|
||||
static void
|
||||
fdset_shrink(struct fdset *pfdset)
|
||||
{
|
||||
pthread_mutex_lock(&pfdset->fd_mutex);
|
||||
fdset_shrink_nolock(pfdset);
|
||||
pthread_mutex_unlock(&pfdset->fd_mutex);
|
||||
}
|
||||
|
||||
@ -151,8 +155,12 @@ fdset_add(struct fdset *pfdset, int fd, fd_cb rcb, fd_cb wcb, void *dat)
|
||||
pthread_mutex_lock(&pfdset->fd_mutex);
|
||||
i = pfdset->num < MAX_FDS ? pfdset->num++ : -1;
|
||||
if (i == -1) {
|
||||
pthread_mutex_unlock(&pfdset->fd_mutex);
|
||||
return -2;
|
||||
fdset_shrink_nolock(pfdset);
|
||||
i = pfdset->num < MAX_FDS ? pfdset->num++ : -1;
|
||||
if (i == -1) {
|
||||
pthread_mutex_unlock(&pfdset->fd_mutex);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
fdset_add_fd(pfdset, i, fd, rcb, wcb, dat);
|
||||
|
Loading…
Reference in New Issue
Block a user