Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be20bcb8 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: adsprpc: remove PM vote counter in fastrpc driver"

parents 62c8720d 5ff9f06b
Loading
Loading
Loading
Loading
+66 −18
Original line number Diff line number Diff line
@@ -224,6 +224,7 @@ struct smq_invoke_ctx {
	struct fastrpc_buf *lbuf;
	size_t used;
	struct fastrpc_file *fl;
	uint32_t handle;
	uint32_t sc;
	struct overlap *overs;
	struct overlap **overps;
@@ -231,6 +232,7 @@ struct smq_invoke_ctx {
	uint32_t *crc;
	unsigned int magic;
	uint64_t ctxid;
	bool pm_awake_voted;
};

struct fastrpc_ctx_lst {
@@ -308,6 +310,7 @@ struct fastrpc_apps {
	spinlock_t ctxlock;
	struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX];
	bool legacy_remote_heap;
	struct wakeup_source *wake_source;
};

struct fastrpc_mmap {
@@ -389,6 +392,8 @@ struct fastrpc_file {
	/* Identifies the device (MINOR_NUM_DEV / MINOR_NUM_SECURE_DEV) */
	int dev_minor;
	char *debug_buf;
	/* Flag to enable PM wake/relax voting for every remote invoke */
	int wake_enable;
};

static struct fastrpc_apps gfa;
@@ -446,6 +451,9 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = {
static int hlosvm[1] = {VMID_HLOS};
static int hlosvmperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};

static void fastrpc_pm_awake(int fl_wake_enable, bool *pm_awake_voted);
static void fastrpc_pm_relax(bool *pm_awake_voted);

static inline int64_t getnstimediff(struct timespec *start)
{
	int64_t ns;
@@ -1199,6 +1207,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
			goto bail;
	}
	ctx->crc = (uint32_t *)invokefd->crc;
	ctx->handle = invoke->handle;
	ctx->sc = invoke->sc;
	if (bufs) {
		VERIFY(err, 0 == context_build_overlap(ctx));
@@ -1210,6 +1219,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
	ctx->tgid = fl->tgid;
	init_completion(&ctx->work);
	ctx->magic = FASTRPC_CTX_MAGIC;
	ctx->pm_awake_voted = false;

	spin_lock(&fl->hlock);
	hlist_add_head(&ctx->hn, &clst->pending);
@@ -1280,6 +1290,7 @@ static void context_free(struct smq_invoke_ctx *ctx)
static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
{
	ctx->retval = retval;
	fastrpc_pm_awake(ctx->fl->wake_enable, &ctx->pm_awake_voted);
	complete(&ctx->work);
}

@@ -1872,7 +1883,25 @@ static void fastrpc_init(struct fastrpc_apps *me)
	me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL;
}

static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl);
static inline void fastrpc_pm_awake(int fl_wake_enable, bool *pm_awake_voted)
{
	struct fastrpc_apps *me = &gfa;

	if (!fl_wake_enable || *pm_awake_voted)
		return;
	__pm_stay_awake(me->wake_source);
	*pm_awake_voted = true;
}

static inline void fastrpc_pm_relax(bool *pm_awake_voted)
{
	struct fastrpc_apps *me = &gfa;

	if (!(*pm_awake_voted))
		return;
	__pm_relax(me->wake_source);
	*pm_awake_voted = false;
}

static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
				   uint32_t kernel,
@@ -1880,12 +1909,12 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
{
	struct smq_invoke_ctx *ctx = NULL;
	struct fastrpc_ioctl_invoke *invoke = &inv->inv;
	int cid = fl->cid;
	int interrupted = 0;
	int err = 0;
	int err = 0, interrupted = 0, cid = fl->cid;
	struct timespec invoket = {0};
	int64_t *perf_counter = getperfcounter(fl, PERF_COUNT);
	bool pm_awake_voted = false;

	fastrpc_pm_awake(fl->wake_enable, &pm_awake_voted);
	if (fl->profile)
		getnstimeofday(&invoket);

@@ -1900,7 +1929,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,

	VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS && fl->sctx != NULL);
	if (err) {
		pr_err("adsprpc: ERROR: %s: user application %s domain is not set\n",
		pr_err("adsprpc: ERROR: %s: kernel session not initialized yet for %s\n",
			__func__, current->comm);
		err = -EBADR;
		goto bail;
@@ -1946,14 +1975,16 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
	if (err)
		goto bail;
 wait:
	fastrpc_pm_relax(&pm_awake_voted);
	if (kernel)
		wait_for_completion(&ctx->work);
	else {
	else
		interrupted = wait_for_completion_interruptible(&ctx->work);

	pm_awake_voted = ctx->pm_awake_voted;
	VERIFY(err, 0 == (err = interrupted));
	if (err)
		goto bail;
	}

	PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS),
	inv_args(ctx);
@@ -1990,6 +2021,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
				*count = *count+1;
		}
	}
	fastrpc_pm_relax(&pm_awake_voted);
	return err;
}

@@ -2760,9 +2792,12 @@ static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan,
				break;
			}
		}
		VERIFY(err, idx < chan->sesscount);
		if (err)
		if (idx >= chan->sesscount) {
			err = -EUSERS;
			pr_err("adsprpc: ERROR %d: %s: max concurrent sessions limit (%d) already reached on %s\n",
				err, __func__, chan->sesscount, chan->subsys);
			goto bail;
		}
		chan->session[idx].smmu.faults = 0;
	} else {
		VERIFY(err, me->dev != NULL);
@@ -3218,7 +3253,7 @@ static int fastrpc_channel_open(struct fastrpc_file *fl)

	VERIFY(err, fl && fl->sctx && fl->cid >= 0 && fl->cid < NUM_CHANNELS);
	if (err) {
		pr_err("adsprpc: ERROR: %s: user application %s domain is not set\n",
		pr_err("adsprpc: ERROR: %s: kernel session not initialized yet for %s\n",
			__func__, current->comm);
		err = -EBADR;
		return err;
@@ -3361,8 +3396,8 @@ static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
		fl->cid = cid;
		fl->ssrcount = fl->apps->channel[cid].ssrcount;
		mutex_lock(&fl->apps->channel[cid].smd_mutex);
		VERIFY(err, !fastrpc_session_alloc_locked(
				&fl->apps->channel[cid], 0, &fl->sctx));
		err = fastrpc_session_alloc_locked(&fl->apps->channel[cid],
				0, &fl->sctx);
		mutex_unlock(&fl->apps->channel[cid].smd_mutex);
		if (err)
			goto bail;
@@ -3405,8 +3440,11 @@ static int fastrpc_internal_control(struct fastrpc_file *fl,
	case FASTRPC_CONTROL_KALLOC:
		cp->kalloc.kalloc_support = 1;
		break;
	case FASTRPC_CONTROL_WAKELOCK:
		fl->wake_enable = cp->wp.enable;
		break;
	default:
		err = -ENOTTY;
		err = -EBADRQC;
		break;
	}
bail:
@@ -4303,11 +4341,19 @@ static int __init fastrpc_device_init(void)

	err = register_rpmsg_driver(&fastrpc_rpmsg_client);
	if (err) {
		pr_err("adsprpc: register_rpmsg_driver: failed with err %d\n",
			err);
		pr_err("adsprpc: %s: register_rpmsg_driver failed with err %d\n",
			__func__, err);
		goto device_create_bail;
	}
	me->rpmsg_register = 1;

	me->wake_source = wakeup_source_register("adsprpc");
	VERIFY(err, !IS_ERR_OR_NULL(me->wake_source));
	if (err) {
		pr_err("adsprpc: Error: %s: wakeup_source_register failed with err %d\n",
					__func__, PTR_ERR(me->wake_source));
		goto device_create_bail;
	}
	return 0;
device_create_bail:
	for (i = 0; i < NUM_CHANNELS; i++) {
@@ -4356,6 +4402,8 @@ static void __exit fastrpc_device_exit(void)
	unregister_chrdev_region(me->dev_no, NUM_CHANNELS);
	if (me->rpmsg_register == 1)
		unregister_rpmsg_driver(&fastrpc_rpmsg_client);
	if (me->wake_source)
		wakeup_source_unregister(me->wake_source);
	debugfs_remove_recursive(debugfs_root);
}

+13 −3
Original line number Diff line number Diff line
@@ -241,22 +241,32 @@ struct fastrpc_ioctl_perf { /* kernel performance data */
	uintptr_t keys;
};

#define FASTRPC_CONTROL_LATENCY	(1)
enum fastrpc_control_type {
	FASTRPC_CONTROL_LATENCY		=	1,
	FASTRPC_CONTROL_SMMU		=	2,
	FASTRPC_CONTROL_KALLOC		=	3,
	FASTRPC_CONTROL_WAKELOCK	=	4,
};

struct fastrpc_ctrl_latency {
	uint32_t enable;	/* latency control enable */
	uint32_t level;		/* level of control */
};

#define FASTRPC_CONTROL_KALLOC	(3)
struct fastrpc_ctrl_kalloc {
	uint32_t kalloc_support;  /* Remote memory allocation from kernel */
};
/* FASTRPC_CONTROL value 2 is reserved in user space */

struct fastrpc_ctrl_wakelock {
	uint32_t enable;	/* wakelock control enable */
};

struct fastrpc_ioctl_control {
	uint32_t req;
	union {
		struct fastrpc_ctrl_latency lp;
		struct fastrpc_ctrl_kalloc kalloc;
		struct fastrpc_ctrl_wakelock wp;
	};
};