clear-pkgs-linux-iot-lts2018/0777-kernel-VHM-Add-the-vm-...

132 lines
3.8 KiB
Diff
Raw Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zhao Yakui <yakui.zhao@intel.com>
Date: Tue, 18 Dec 2018 09:37:04 +0800
Subject: [PATCH] kernel/VHM: Add the vm owner for each ioreq_client to release
vhm_vm after releasing client
Currently it will use the ioreq_client->vmid to find the corresponding vm.
But if the corresponding vmid is removed from the acrn_vm_list, it will
fail. And the lock is also acquired to get the corresponding vm from vmid.
So the vm_owner is added for ioreq_client so that it can get the
vm_owner directly for each client.
When the ioreq_client needs to be released, it will try to decrease
the refcnt of vhm_vm.
Tracked-On: projectacrn/acrn-hypervisor#2085
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Reviewed-by: Shuo Liu <shuo.a.liu@intel.com>
Tracked-On: PKT-1617
---
drivers/vhm/vhm_ioreq.c | 34 +++++++++-------------------------
1 file changed, 9 insertions(+), 25 deletions(-)
diff --git a/drivers/vhm/vhm_ioreq.c b/drivers/vhm/vhm_ioreq.c
2020-10-27 02:14:06 +08:00
index 2f37ef958094..3f8bd4abe757 100644
--- a/drivers/vhm/vhm_ioreq.c
+++ b/drivers/vhm/vhm_ioreq.c
@@ -132,6 +132,8 @@ struct ioreq_client {
int pci_dev;
int pci_func;
atomic_t refcnt;
+ /* Add the vhm_vm that contains the ioreq_client */
+ struct vhm_vm *ref_vm;
};
#define MAX_CLIENT 1024
@@ -192,9 +194,11 @@ static struct ioreq_client *acrn_ioreq_get_client(int client_id)
static void acrn_ioreq_put_client(struct ioreq_client *client)
{
if (atomic_dec_and_test(&client->refcnt)) {
+ struct vhm_vm *ref_vm = client->ref_vm;
/* The client should be released when refcnt = 0 */
/* TBD: Do we need to free the other resources? */
kfree(client);
+ put_vm(ref_vm);
}
}
@@ -242,6 +246,7 @@ int acrn_ioreq_create_client(unsigned long vmid, ioreq_handler_t handler,
}
client->vmid = vmid;
+ client->ref_vm = vm;
if (name)
strncpy(client->name, name, sizeof(client->name) - 1);
spin_lock_init(&client->range_lock);
@@ -380,12 +385,10 @@ static void acrn_ioreq_destroy_client_pervm(struct ioreq_client *client,
vm->ioreq_fallback_client = -1;
acrn_ioreq_put_client(client);
- put_vm(vm);
}
void acrn_ioreq_destroy_client(int client_id)
{
- struct vhm_vm *vm;
struct ioreq_client *client;
if (client_id < 0 || client_id >= MAX_CLIENT) {
@@ -403,18 +406,8 @@ void acrn_ioreq_destroy_client(int client_id)
might_sleep();
- vm = find_get_vm(client->vmid);
- if (unlikely(vm == NULL)) {
- pr_err("vhm-ioreq: failed to find vm from vmid %ld\n",
- client->vmid);
- acrn_ioreq_put_client(client);
- return;
- }
-
- acrn_ioreq_destroy_client_pervm(client, vm);
+ acrn_ioreq_destroy_client_pervm(client, client->ref_vm);
acrn_ioreq_put_client(client);
-
- put_vm(vm);
}
EXPORT_SYMBOL_GPL(acrn_ioreq_destroy_client);
@@ -552,19 +545,11 @@ struct vhm_request *acrn_ioreq_get_reqbuf(int client_id)
pr_err("vhm-ioreq: no client for id %d\n", client_id);
return NULL;
}
- vm = find_get_vm(client->vmid);
- if (unlikely(vm == NULL)) {
- pr_err("vhm-ioreq: failed to find vm from vmid %ld\n",
- client->vmid);
- acrn_ioreq_put_client(client);
- return NULL;
- }
-
- if (vm->req_buf == NULL) {
+ vm = client->ref_vm;
+ if (unlikely(vm == NULL || vm->req_buf == NULL)) {
pr_warn("vhm-ioreq: the req buf page not ready yet "
"for vmid %ld\n", client->vmid);
}
- put_vm(vm);
acrn_ioreq_put_client(client);
return (struct vhm_request *)vm->req_buf;
}
@@ -581,7 +566,7 @@ static int ioreq_client_thread(void *data)
if (!client)
return 0;
- vm = find_get_vm(client->vmid);
+ vm = client->ref_vm;
if (unlikely(vm == NULL)) {
pr_err("vhm-ioreq: failed to find vm from vmid %ld\n",
client->vmid);
@@ -614,7 +599,6 @@ static int ioreq_client_thread(void *data)
set_bit(IOREQ_CLIENT_EXIT, &client->flags);
acrn_ioreq_put_client(client);
- put_vm(vm);
return 0;
}
--
https://clearlinux.org