summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2011-09-06 13:06:40 +0300
committerVarun Colbert <vcolbert@nvidia.com>2011-10-26 21:58:24 -0700
commit78886b008918786040a4a5957f2a0229345b0b84 (patch)
tree3499c97ba58fbaa205a9430840322e0a0d6dcf07
parentd0024f3ad1e4c6d4885355df3fda02435ccc471d (diff)
nvhost: Throttle low-priority tasks
Add interface for setting priority of a channel. When the priority is low, wait for channel to become empty before submitting it. Bug 864407 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/57237 (cherry picked from commit 75228616ee2c3073e391c529aecb3f82be3fc5a4) Change-Id: Ife8057586bfc3be02f772034bd2c497b2c59f7aa Reviewed-on: http://git-master/r/60391 Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
-rw-r--r--drivers/video/tegra/host/dev.c10
-rw-r--r--drivers/video/tegra/host/nvhost_channel.c37
-rw-r--r--drivers/video/tegra/host/nvhost_channel.h4
-rw-r--r--include/linux/nvhost_ioctl.h11
4 files changed, 57 insertions, 5 deletions
diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c
index 406ca7c1814a..3d0875dcb37e 100644
--- a/drivers/video/tegra/host/dev.c
+++ b/drivers/video/tegra/host/dev.c
@@ -66,6 +66,7 @@ struct nvhost_channel_userctx {
struct nvhost_waitchk waitchks[NVHOST_MAX_WAIT_CHECKS];
struct nvhost_waitchk *cur_waitchk;
struct nvhost_userctx_timeout timeout;
+ u32 priority;
};
struct nvhost_ctrl_userctx {
@@ -130,6 +131,7 @@ static int nvhost_channelopen(struct inode *inode, struct file *filp)
goto fail;
priv->hwctx->timeout = &priv->timeout;
}
+ priv->priority = NVHOST_PRIORITY_MEDIUM;
priv->gathers = nvmap_mmap(priv->gather_mem);
if (!priv->gathers)
@@ -324,14 +326,14 @@ static int nvhost_ioctl_channel_flush(
ctx->timeout.syncpt_id = ctx->hdr.syncpt_id;
/* context switch if needed, and submit user's gathers to the channel */
- BUG_ON(!channel_op(ctx->ch).submit);
- err = channel_op(ctx->ch).submit(ctx->ch, ctx->hwctx, ctx->nvmap,
+ err = nvhost_channel_submit(ctx->ch, ctx->hwctx, ctx->nvmap,
ctx->gathers, ctx->cur_gather,
ctx->waitchks, ctx->cur_waitchk,
ctx->hdr.waitchk_mask,
ctx->unpinarray, num_unpin,
ctx->hdr.syncpt_id, ctx->hdr.syncpt_incrs,
&ctx->timeout,
+ ctx->priority,
&args->value,
null_kickoff);
if (err)
@@ -473,6 +475,10 @@ static long nvhost_channelctl(struct file *filp,
((struct nvhost_get_param_args *)buf)->value =
priv->timeout.has_timedout;
break;
+ case NVHOST_IOCTL_CHANNEL_SET_PRIORITY:
+ priv->timeout.timeout =
+ (u32)((struct nvhost_set_priority_args *)buf)->priority;
+ break;
default:
err = -ENOTTY;
break;
diff --git a/drivers/video/tegra/host/nvhost_channel.c b/drivers/video/tegra/host/nvhost_channel.c
index 48f018cca4b2..64bc59ed4b9c 100644
--- a/drivers/video/tegra/host/nvhost_channel.c
+++ b/drivers/video/tegra/host/nvhost_channel.c
@@ -24,9 +24,46 @@
#include "dev.h"
#include "nvhost_hwctx.h"
#include <trace/events/nvhost.h>
+#include <linux/nvhost_ioctl.h>
#include <linux/platform_device.h>
+int nvhost_channel_submit(
+ struct nvhost_channel *channel,
+ struct nvhost_hwctx *hwctx,
+ struct nvmap_client *user_nvmap,
+ u32 *gather,
+ u32 *gather_end,
+ struct nvhost_waitchk *waitchk,
+ struct nvhost_waitchk *waitchk_end,
+ u32 waitchk_mask,
+ struct nvmap_handle **unpins,
+ int nr_unpins,
+ u32 syncpt_id,
+ u32 syncpt_incrs,
+ struct nvhost_userctx_timeout *timeout_ctx,
+ u32 priority,
+ u32 *syncpt_value,
+ bool null_kickoff)
+{
+ BUG_ON(!channel_op(channel).submit);
+
+ /* Low priority submits wait until sync queue is empty */
+ if (priority < NVHOST_PRIORITY_MEDIUM)
+ nvhost_cdma_wait(&channel->cdma, CDMA_EVENT_SYNC_QUEUE_EMPTY);
+
+ return channel_op(channel).submit(channel,
+ hwctx,
+ user_nvmap,
+ gather, gather_end,
+ waitchk, waitchk_end, waitchk_mask,
+ unpins, nr_unpins,
+ syncpt_id, syncpt_incrs,
+ timeout_ctx,
+ syncpt_value,
+ null_kickoff);
+}
+
struct nvhost_channel *nvhost_getchannel(struct nvhost_channel *ch)
{
int err = 0;
diff --git a/drivers/video/tegra/host/nvhost_channel.h b/drivers/video/tegra/host/nvhost_channel.h
index e4dc4e2d79e8..18e27a177f66 100644
--- a/drivers/video/tegra/host/nvhost_channel.h
+++ b/drivers/video/tegra/host/nvhost_channel.h
@@ -93,8 +93,8 @@ int nvhost_channel_submit(
int nr_unpins,
u32 syncpt_id,
u32 syncpt_incrs,
- u32 timeout,
- void *timeout_ctx,
+ struct nvhost_userctx_timeout *timeout_ctx,
+ u32 priority,
u32 *syncpt_value,
bool null_kickoff);
diff --git a/include/linux/nvhost_ioctl.h b/include/linux/nvhost_ioctl.h
index ef6685ea418f..31ff22f45fb9 100644
--- a/include/linux/nvhost_ioctl.h
+++ b/include/linux/nvhost_ioctl.h
@@ -34,6 +34,9 @@
#define NVHOST_NO_TIMEOUT (-1)
#define NVHOST_NO_CONTEXT 0x0
#define NVHOST_IOCTL_MAGIC 'H'
+#define NVHOST_PRIORITY_LOW 50
+#define NVHOST_PRIORITY_MEDIUM 100
+#define NVHOST_PRIORITY_HIGH 150
/* version 0 header (used with write() submit interface) */
struct nvhost_submit_hdr {
@@ -100,6 +103,10 @@ struct nvhost_set_timeout_args {
__u32 timeout;
};
+struct nvhost_set_priority_args {
+ __u32 priority;
+};
+
#define NVHOST_IOCTL_CHANNEL_FLUSH \
_IOR(NVHOST_IOCTL_MAGIC, 1, struct nvhost_get_param_args)
#define NVHOST_IOCTL_CHANNEL_GET_SYNCPOINTS \
@@ -124,8 +131,10 @@ struct nvhost_set_timeout_args {
_IOW(NVHOST_IOCTL_MAGIC, 11, struct nvhost_set_timeout_args)
#define NVHOST_IOCTL_CHANNEL_GET_TIMEDOUT \
_IOR(NVHOST_IOCTL_MAGIC, 12, struct nvhost_get_param_args)
+#define NVHOST_IOCTL_CHANNEL_SET_PRIORITY \
+ _IOW(NVHOST_IOCTL_MAGIC, 13, struct nvhost_set_priority_args)
#define NVHOST_IOCTL_CHANNEL_LAST \
- _IOC_NR(NVHOST_IOCTL_CHANNEL_GET_TIMEDOUT)
+ _IOC_NR(NVHOST_IOCTL_CHANNEL_SET_PRIORITY)
#define NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE sizeof(struct nvhost_submit_hdr_ext)
struct nvhost_ctrl_syncpt_read_args {