dm: apply new mevent API to avoid race issue in mei

Pass teardown callback when add mevent in mei mediator code.
Which could avoid run_callback calling after the related data
structure is freed.

Tracked-On: #1877
Signed-off-by: Yin Fengwei <fengwei.yin@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Yin Fengwei 2018-11-26 16:12:13 +08:00 committed by wenlingz
parent 64d9c59aa1
commit 7fce2462a0
2 changed files with 26 additions and 13 deletions

View File

@ -254,8 +254,6 @@ mevent_add(int tfd, enum ev_type type,
return mevp; return mevp;
} else { } else {
if (mevp->teardown)
mevp->teardown(mevp->teardown_param);
free(mevp); free(mevp);
return NULL; return NULL;
} }
@ -347,6 +345,9 @@ mevent_delete_event(struct mevent *evp, int closefd)
if (evp->closefd) { if (evp->closefd) {
close(evp->me_fd); close(evp->me_fd);
} }
if (evp->teardown)
evp->teardown(evp->teardown_param);
free(evp); free(evp);
} }
return 0; return 0;

View File

@ -378,7 +378,6 @@ vmei_host_client_destroy(const struct refcnt *ref)
{ {
struct vmei_host_client *hclient; struct vmei_host_client *hclient;
struct vmei_me_client *mclient; struct vmei_me_client *mclient;
unsigned int i;
hclient = container_of(ref, struct vmei_host_client, ref); hclient = container_of(ref, struct vmei_host_client, ref);
@ -390,6 +389,14 @@ vmei_host_client_destroy(const struct refcnt *ref)
if (hclient->rx_mevp) if (hclient->rx_mevp)
mevent_delete(hclient->rx_mevp); mevent_delete(hclient->rx_mevp);
}
static void
vmei_rx_teardown(void *param)
{
unsigned int i;
struct vmei_host_client *hclient = param;
if (hclient->client_fd > -1) if (hclient->client_fd > -1)
close(hclient->client_fd); close(hclient->client_fd);
for (i = 0; i < VMEI_IOBUFS_MAX; i++) for (i = 0; i < VMEI_IOBUFS_MAX; i++)
@ -955,12 +962,21 @@ vmei_reset(void *vth)
virtio_reset_dev(&vmei->base); virtio_reset_dev(&vmei->base);
} }
static void
vmei_reset_teardown(void *param)
{
struct virtio_mei *vmei = param;
vmei->reset_mevp = NULL;
pthread_mutex_destroy(&vmei->mutex);
free(vmei->config);
free(vmei);
}
static void vmei_del_reset_event(struct virtio_mei *vmei) static void vmei_del_reset_event(struct virtio_mei *vmei)
{ {
if (vmei->reset_mevp) if (vmei->reset_mevp)
mevent_delete_close(vmei->reset_mevp); mevent_delete_close(vmei->reset_mevp);
vmei->reset_mevp = NULL;
} }
static void vmei_rx_callback(int fd, enum ev_type type, void *param); static void vmei_rx_callback(int fd, enum ev_type type, void *param);
@ -1017,7 +1033,7 @@ vmei_host_client_native_connect(struct vmei_host_client *hclient)
/* add READ event into mevent */ /* add READ event into mevent */
hclient->rx_mevp = mevent_add(hclient->client_fd, EVF_READ, hclient->rx_mevp = mevent_add(hclient->client_fd, EVF_READ,
vmei_rx_callback, hclient, NULL, NULL); vmei_rx_callback, hclient, vmei_rx_teardown, hclient);
if (!hclient->rx_mevp) if (!hclient->rx_mevp)
return MEI_HBM_REJECTED; return MEI_HBM_REJECTED;
@ -1951,7 +1967,7 @@ vmei_start(struct virtio_mei *vmei, bool do_rescan)
hclient->client_fd = pipefd[0]; hclient->client_fd = pipefd[0];
hclient->rx_mevp = mevent_add(hclient->client_fd, EVF_READ, hclient->rx_mevp = mevent_add(hclient->client_fd, EVF_READ,
vmei_rx_callback, hclient, NULL, NULL); vmei_rx_callback, hclient, vmei_rx_teardown, hclient);
vmei->hbm_fd = pipefd[1]; vmei->hbm_fd = pipefd[1];
if (do_rescan) { if (do_rescan) {
@ -2051,7 +2067,7 @@ static int vmei_add_reset_event(struct virtio_mei *vmei)
vmei->dev_state_first = true; vmei->dev_state_first = true;
vmei->reset_mevp = mevent_add(dev_state_fd, EVF_READ_ET, vmei->reset_mevp = mevent_add(dev_state_fd, EVF_READ_ET,
vmei_reset_callback, vmei, NULL, NULL); vmei_reset_callback, vmei, vmei_reset_teardown, vmei);
if (!vmei->reset_mevp) { if (!vmei->reset_mevp) {
close(dev_state_fd); close(dev_state_fd);
return -ENOMEM; return -ENOMEM;
@ -2336,12 +2352,8 @@ vmei_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
if (!vmei) if (!vmei)
return; return;
vmei_del_reset_event(vmei);
vmei_stop(vmei); vmei_stop(vmei);
vmei_del_reset_event(vmei);
pthread_mutex_destroy(&vmei->mutex);
free(vmei->config);
free(vmei);
} }
const struct pci_vdev_ops pci_ops_vmei = { const struct pci_vdev_ops pci_ops_vmei = {