soc: hab: recycle mmid from qcpe to video

Add new mmid for video and other minor logging
and efficiency fixes.

Change-Id: I0ebbfadff76e7efb7f9afff9896dadf1bd8df9a1
Signed-off-by: Shiju Mathew <shijum@codeaurora.org>
This commit is contained in:
Shiju Mathew 2018-10-03 20:18:58 -04:00
parent 2592658a93
commit 23beddbfdf
8 changed files with 155 additions and 53 deletions

View file

@ -21,7 +21,7 @@
.openlock = __SPIN_LOCK_UNLOCKED(&hab_devices[__num__].openlock)\
}
static const char hab_info_str[] = "Change: 16764735 Revision: #76";
static const char hab_info_str[] = "Change: 17280941 Revision: #81";
/*
* The following has to match habmm definitions, order does not matter if
@ -42,15 +42,13 @@ static struct hab_device hab_devices[] = {
HAB_DEVICE_CNSTR(DEVICE_DISP5_NAME, MM_DISP_5, 10),
HAB_DEVICE_CNSTR(DEVICE_GFX_NAME, MM_GFX, 11),
HAB_DEVICE_CNSTR(DEVICE_VID_NAME, MM_VID, 12),
HAB_DEVICE_CNSTR(DEVICE_MISC_NAME, MM_MISC, 13),
HAB_DEVICE_CNSTR(DEVICE_QCPE1_NAME, MM_QCPE_VM1, 14),
HAB_DEVICE_CNSTR(DEVICE_QCPE2_NAME, MM_QCPE_VM2, 15),
HAB_DEVICE_CNSTR(DEVICE_QCPE3_NAME, MM_QCPE_VM3, 16),
HAB_DEVICE_CNSTR(DEVICE_QCPE4_NAME, MM_QCPE_VM4, 17),
HAB_DEVICE_CNSTR(DEVICE_CLK1_NAME, MM_CLK_VM1, 18),
HAB_DEVICE_CNSTR(DEVICE_CLK2_NAME, MM_CLK_VM2, 19),
HAB_DEVICE_CNSTR(DEVICE_FDE1_NAME, MM_FDE_1, 20),
HAB_DEVICE_CNSTR(DEVICE_BUFFERQ1_NAME, MM_BUFFERQ_1, 21),
HAB_DEVICE_CNSTR(DEVICE_VID2_NAME, MM_VID_2, 13),
HAB_DEVICE_CNSTR(DEVICE_MISC_NAME, MM_MISC, 14),
HAB_DEVICE_CNSTR(DEVICE_QCPE1_NAME, MM_QCPE_VM1, 15),
HAB_DEVICE_CNSTR(DEVICE_CLK1_NAME, MM_CLK_VM1, 16),
HAB_DEVICE_CNSTR(DEVICE_CLK2_NAME, MM_CLK_VM2, 17),
HAB_DEVICE_CNSTR(DEVICE_FDE1_NAME, MM_FDE_1, 18),
HAB_DEVICE_CNSTR(DEVICE_BUFFERQ1_NAME, MM_BUFFERQ_1, 19),
};
struct hab_driver hab_driver = {
@ -1082,15 +1080,25 @@ static int hab_release(struct inode *inodep, struct file *filep)
/* notify remote side on vchan closing */
list_for_each_entry_safe(vchan, tmp, &ctx->vchannels, node) {
list_del(&vchan->node); /* vchan is not in this ctx anymore */
hab_vchan_stop_notify(vchan);
if (!vchan->closed) { /* locally hasn't closed yet */
if (!kref_get_unless_zero(&vchan->refcount)) {
pr_err("vchan %x %x refcnt %d mismanaged closed %d remote closed %d\n",
vchan->id,
vchan->otherend_id,
get_refcnt(vchan->refcount),
vchan->closed, vchan->otherend_closed);
continue; /* vchan is already being freed */
} else {
hab_vchan_stop_notify(vchan);
/* put for notify. shouldn't cause free */
hab_vchan_put(vchan);
}
} else
continue;
write_unlock(&ctx->ctx_lock);
if (!vchan->closed) {
pr_warn("potential leak vc %pK %x remote %x session %d refcnt %d\n",
vchan, vchan->id, vchan->otherend_id,
vchan->session_id,
get_refcnt(vchan->refcount));
hab_vchan_put(vchan); /* there is a lock inside */
}
hab_vchan_put(vchan); /* there is a lock inside */
write_lock(&ctx->ctx_lock);
}
@ -1324,7 +1332,6 @@ static int __init hab_init(void)
dev_t dev;
place_marker("M - HAB INIT Start");
result = alloc_chrdev_region(&hab_driver.major, 0, 1, "hab");
if (result < 0) {
@ -1379,11 +1386,8 @@ static int __init hab_init(void)
} else
set_dma_ops(hab_driver.dev, &hab_dma_ops);
}
hab_stat_init(&hab_driver);
place_marker("M - HAB INIT End");
return result;
err:

View file

@ -45,6 +45,7 @@
#include <linux/reboot.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/delay.h>
#include <soc/qcom/boot_stats.h>
enum hab_payload_type {
@ -81,11 +82,9 @@ enum hab_payload_type {
#define DEVICE_DISP5_NAME "hab_disp5"
#define DEVICE_GFX_NAME "hab_ogles"
#define DEVICE_VID_NAME "hab_vid"
#define DEVICE_VID2_NAME "hab_vid2"
#define DEVICE_MISC_NAME "hab_misc"
#define DEVICE_QCPE1_NAME "hab_qcpe_vm1"
#define DEVICE_QCPE2_NAME "hab_qcpe_vm2"
#define DEVICE_QCPE3_NAME "hab_qcpe_vm3"
#define DEVICE_QCPE4_NAME "hab_qcpe_vm4"
#define DEVICE_CLK1_NAME "hab_clock_vm1"
#define DEVICE_CLK2_NAME "hab_clock_vm2"
#define DEVICE_FDE1_NAME "hab_fde1"
@ -346,6 +345,8 @@ struct hab_driver {
};
struct virtual_channel {
struct list_head node; /* for ctx */
struct list_head pnode; /* for pchan */
/*
* refcount is used to track the references from hab core to the virtual
* channel such as references from physical channels,
@ -354,8 +355,6 @@ struct virtual_channel {
struct kref refcount;
struct physical_channel *pchan;
struct uhab_context *ctx;
struct list_head node; /* for ctx */
struct list_head pnode; /* for pchan */
struct list_head rx_list;
wait_queue_head_t rx_queue;
spinlock_t rx_lock;

View file

@ -14,6 +14,7 @@
#include "hab.h"
#include "hab_ghs.h"
#define GIPC_VM_SET_CNT 22
static const char * const dt_gipc_path_name[] = {
"testgipc1",
"testgipc2",
@ -39,12 +40,41 @@ static const char * const dt_gipc_path_name[] = {
"testgipc22",
};
/* same vmid assignment for all the vms. it should matches dt_gipc_path_name */
int mmid_order[GIPC_VM_SET_CNT] = {
MM_AUD_1,
MM_AUD_2,
MM_AUD_3,
MM_AUD_4,
MM_CAM_1,
MM_CAM_2,
MM_DISP_1,
MM_DISP_2,
MM_DISP_3,
MM_DISP_4,
MM_DISP_5,
MM_GFX,
MM_VID,
MM_MISC,
MM_QCPE_VM1,
MM_VID_2, /* newly recycled */
0,
0,
MM_CLK_VM1,
MM_CLK_VM2,
MM_FDE_1,
MM_BUFFERQ_1,
};
static struct ghs_vmm_plugin_info_s {
const char * const *dt_name;
int *mmid_dt_mapping;
int curr;
int probe_cnt;
} ghs_vmm_plugin_info = {
dt_gipc_path_name,
mmid_order,
0,
ARRAY_SIZE(dt_gipc_path_name),
};
@ -59,6 +89,33 @@ static void ghs_irq_handler(void *cookie)
tasklet_schedule(&dev->task);
}
static int get_dt_name_idx(int vmid_base, int mmid,
struct ghs_vmm_plugin_info_s *plugin_info)
{
int idx = -1;
int i;
if (vmid_base < 0 || vmid_base > plugin_info->probe_cnt /
GIPC_VM_SET_CNT) {
pr_err("vmid %d overflow expected max %d\n", vmid_base,
plugin_info->probe_cnt / GIPC_VM_SET_CNT);
return idx;
}
for (i = 0; i < GIPC_VM_SET_CNT; i++) {
if (mmid == plugin_info->mmid_dt_mapping[i]) {
idx = vmid_base * GIPC_VM_SET_CNT + i;
if (idx > plugin_info->probe_cnt) {
pr_err("dt name idx %d overflow max %d\n",
idx, plugin_info->probe_cnt);
idx = -1;
}
break;
}
}
return idx;
}
/* static struct physical_channel *habhyp_commdev_alloc(int id) */
int habhyp_commdev_alloc(void **commdev, int is_be, char *name, int vmid_remote,
struct hab_device *mmid_device)
@ -67,6 +124,7 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name, int vmid_remote,
struct physical_channel *pchan = NULL;
struct physical_channel **ppchan = (struct physical_channel **)commdev;
int ret = 0;
int dt_name_idx = 0;
if (ghs_vmm_plugin_info.curr > ghs_vmm_plugin_info.probe_cnt) {
pr_err("too many commdev alloc %d, supported is %d\n",
@ -101,13 +159,25 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name, int vmid_remote,
gvh_dn = of_find_node_by_path("/aliases");
if (gvh_dn) {
const char *ep_path = NULL;
struct device_node *ep_dn;
struct device_node *ep_dn = NULL;
dt_name_idx = get_dt_name_idx(vmid_remote,
mmid_device->id,
&ghs_vmm_plugin_info);
if (dt_name_idx < 0) {
pr_err("failed to find %s for vmid %d ret %d\n",
mmid_device->name,
mmid_device->id,
dt_name_idx);
ret = -ENOENT;
goto err;
}
ret = of_property_read_string(gvh_dn,
ghs_vmm_plugin_info.dt_name[ghs_vmm_plugin_info.curr],
&ep_path);
ghs_vmm_plugin_info.dt_name[dt_name_idx],
&ep_path);
if (ret)
pr_err("failed to read endpoint string ret %d\n",
pr_err("failed to read endpoint str ret %d\n",
ret);
of_node_put(gvh_dn);
@ -117,22 +187,23 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name, int vmid_remote,
of_node_put(ep_dn);
if (IS_ERR(dev->endpoint)) {
ret = PTR_ERR(dev->endpoint);
pr_err("KGIPC alloc failed id: %d, ret: %d\n",
ghs_vmm_plugin_info.curr, ret);
pr_err("alloc failed %d %s ret %d\n",
dt_name_idx, mmid_device->name,
ret);
goto err;
} else {
pr_debug("gipc ep found for %d\n",
ghs_vmm_plugin_info.curr);
pr_debug("gipc ep found for %d %s\n",
dt_name_idx, mmid_device->name);
}
} else {
pr_err("of_parse_phandle failed id: %d\n",
ghs_vmm_plugin_info.curr);
pr_err("of_parse_phandle failed id %d %s\n",
dt_name_idx, mmid_device->name);
ret = -ENOENT;
goto err;
}
} else {
pr_err("of_find_compatible_node failed id: %d\n",
ghs_vmm_plugin_info.curr);
pr_err("of_find_compatible_node failed id %d %s\n",
dt_name_idx, mmid_device->name);
ret = -ENOENT;
goto err;
}
@ -149,6 +220,7 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name, int vmid_remote,
pchan->hyp_data = (void *)dev;
pchan->is_be = is_be;
strlcpy(dev->name, name, sizeof(dev->name));
strlcpy(pchan->name, name, sizeof(pchan->name));
*ppchan = pchan;
dev->read_data = kmalloc(GIPC_RECV_BUFF_SIZE_BYTES, GFP_KERNEL);
if (!dev->read_data) {

View file

@ -124,8 +124,11 @@ void habmem_remove_export(struct export_desc *exp)
struct uhab_context *ctx;
if (!exp || !exp->ctx || !exp->pchan) {
pr_err("failed to find valid info in exp %pK ctx %pK pchan %pK\n",
if (exp)
pr_err("invalid info in exp %pK ctx %pK pchan %pK\n",
exp, exp->ctx, exp->pchan);
else
pr_err("invalid exp\n");
return;
}

View file

@ -76,8 +76,9 @@ hab_msg_dequeue(struct virtual_channel *vchan, struct hab_message **msg,
ret = 0;
*rsize = message->sizebytes;
} else {
pr_err("rcv buffer too small %d < %zd\n",
*rsize, message->sizebytes);
pr_err("vcid %x rcv buf too small %d < %zd\n",
vchan->id, *rsize,
message->sizebytes);
*rsize = message->sizebytes;
message = NULL;
ret = -EOVERFLOW; /* come back again */
@ -281,7 +282,13 @@ int hab_msg_recv(struct physical_channel *pchan,
break;
}
exp_desc->domid_local = pchan->dom_id;
if (pchan->vmid_local != exp_desc->domid_remote ||
pchan->vmid_remote != exp_desc->domid_local)
pr_err("corrupted vmid %d != %d %d != %d\n",
pchan->vmid_local, exp_desc->domid_remote,
pchan->vmid_remote, exp_desc->domid_local);
exp_desc->domid_remote = pchan->vmid_remote;
exp_desc->domid_local = pchan->vmid_local;
exp_desc->pchan = pchan;
hab_export_enqueue(vchan, exp_desc);

View file

@ -152,10 +152,13 @@ int hab_open_listen(struct uhab_context *ctx,
ret = wait_event_interruptible_timeout(dev->openq,
hab_open_request_find(ctx, dev, listen, recv_request),
ms_timeout);
if (!ret || (-ERESTARTSYS == ret)) {
if (!ret) {
pr_debug("%s timeout in open listen\n", dev->name);
ret = -EAGAIN; /* condition not met */
} else if (-ERESTARTSYS == ret) {
pr_warn("something failed in open listen ret %d\n",
ret);
ret = -EAGAIN; /* condition not met */
ret = -EINTR; /* condition not met */
} else if (ret > 0)
ret = 0; /* condition met */
} else { /* fe case */

View file

@ -87,7 +87,6 @@ hab_vchan_free(struct kref *ref)
/* the release vchan from ctx was done earlier in vchan close() */
hab_ctx_put(ctx); /* now ctx is not needed from this vchan's view */
vchan->ctx = NULL;
/* release vchan from pchan. no more msg for this vchan */
write_lock_bh(&pchan->vchans_lock);
@ -173,7 +172,10 @@ void hab_vchan_stop(struct virtual_channel *vchan)
if (vchan) {
vchan->otherend_closed = 1;
wake_up(&vchan->rx_queue);
wake_up_interruptible(&vchan->ctx->exp_wq);
if (vchan->ctx)
wake_up_interruptible(&vchan->ctx->exp_wq);
else
pr_err("NULL ctx for vchan %x\n", vchan->id);
}
}
@ -200,6 +202,18 @@ static int hab_vchans_per_pchan_empty(struct physical_channel *pchan)
read_lock(&pchan->vchans_lock);
empty = list_empty(&pchan->vchannels);
if (!empty) {
struct virtual_channel *vchan;
list_for_each_entry(vchan, &pchan->vchannels, pnode) {
pr_err("vchan %pK id %x remote id %x session %d ref %d closed %d remote close %d\n",
vchan, vchan->id, vchan->otherend_id,
vchan->session_id,
get_refcnt(vchan->refcount), vchan->closed,
vchan->otherend_closed);
}
}
read_unlock(&pchan->vchans_lock);
return empty;
@ -220,6 +234,8 @@ static int hab_vchans_empty(int vmid)
if (!hab_vchans_per_pchan_empty(pchan)) {
empty = 0;
spin_unlock_bh(&hab_dev->pchan_lock);
pr_info("vmid %d %s's vchans are not closed\n",
vmid, pchan->name);
break;
}
}
@ -239,7 +255,7 @@ void hab_vchans_empty_wait(int vmid)
pr_info("waiting for GVM%d's sockets closure\n", vmid);
while (!hab_vchans_empty(vmid))
schedule();
usleep_range(10000, 12000);
pr_info("all of GVM%d's sockets are closed\n", vmid);
}

View file

@ -29,7 +29,8 @@
#define MM_VID_START 500
#define MM_VID 501
#define MM_VID_END 502
#define MM_VID_2 502
#define MM_VID_END 503
#define MM_MISC_START 600
#define MM_MISC 601
@ -37,10 +38,7 @@
#define MM_QCPE_START 700
#define MM_QCPE_VM1 701
#define MM_QCPE_VM2 702
#define MM_QCPE_VM3 703
#define MM_QCPE_VM4 704
#define MM_QCPE_END 705
#define MM_QCPE_END 702
#define MM_CLK_START 800
#define MM_CLK_VM1 801