diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2011-09-06 13:06:40 +0300 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-10-26 21:58:24 -0700 |
commit | 78886b008918786040a4a5957f2a0229345b0b84 (patch) | |
tree | 3499c97ba58fbaa205a9430840322e0a0d6dcf07 | |
parent | d0024f3ad1e4c6d4885355df3fda02435ccc471d (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.c | 10 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_channel.c | 37 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_channel.h | 4 | ||||
-rw-r--r-- | include/linux/nvhost_ioctl.h | 11 |
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 { |