--- x/drivers/misc/vmw_vmci/vmci_context.c 2022-03-24 20:48:40.613297600 +0800 +++ y/drivers/misc/vmw_vmci/vmci_context.c 2022-03-24 21:12:11.482451200 +0800 @@ -416,14 +416,9 @@ struct vmci_ctx *vmci_ctx_get(u32 cid) return context; } -/* - * Deallocates all parts of a context data structure. This - * function doesn't lock the context, because it assumes that - * the caller was holding the last reference to context. - */ -static void ctx_free_ctx(struct kref *kref) +static void ctx_free_wfunc(struct work_struct *work) { - struct vmci_ctx *context = container_of(kref, struct vmci_ctx, kref); + struct vmci_ctx *context = container_of(work, struct vmci_ctx, free_work); struct vmci_datagram_queue_entry *dq_entry, *dq_entry_tmp; struct vmci_handle temp_handle; struct vmci_handle_list *notifier, *tmp; @@ -484,6 +479,19 @@ static void ctx_free_ctx(struct kref *kr } /* + * Deallocates all parts of a context data structure. This + * function doesn't lock the context, because it assumes that + * the caller was holding the last reference to context. + */ +static void ctx_free_ctx(struct kref *kref) +{ + struct vmci_ctx *context = container_of(kref, struct vmci_ctx, kref); + + INIT_WORK(&context->free_work, ctx_free_wfunc); + schedule_work(&context->free_work); +} + +/* * Drops reference to VMCI context. If this is the last reference to * the context it will be deallocated. A context is created with * a reference count of one, and on destroy, it is removed from --- x/drivers/misc/vmw_vmci/vmci_context.h 2022-03-24 20:47:25.859163300 +0800 +++ y/drivers/misc/vmw_vmci/vmci_context.h 2022-03-24 20:57:52.644149600 +0800 @@ -13,6 +13,7 @@ #include #include #include +#include #include "vmci_handle_array.h" #include "vmci_datagram.h" @@ -80,6 +81,7 @@ struct vmci_ctx { const struct cred *cred; bool *notify; /* Notify flag pointer - hosted only. */ struct page *notify_page; /* Page backing the notify UVA. */ + struct work_struct free_work; }; /* VMCINotifyAddRemoveInfo: Used to add/remove remote context notifications. */