gpu: nvgpu: limit number of gpfifo entries

Limit number of gpfifo entries so that the size of gpfifo i.e.
num_entries * size of each entry fits in u32 data type.

Jira NVGPU-5846

Change-Id: I4d3560a6ed90044c88ee3a7acd2e6cb0591b7c5e
Signed-off-by: shashank singh <shashsingh@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2474118
(cherry picked from commit 02ab9e163f5b413b6eb9817ab8ac5581ce7ef427)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2483947
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: Dinesh T <dt@nvidia.com>
Reviewed-by: Ankur Kishore <ankkishore@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
shashank singh
2021-02-08 18:15:25 +05:30
committed by mobile promotions
parent ed739cdba1
commit 019641e88c
2 changed files with 75 additions and 0 deletions

View File

@@ -1344,11 +1344,43 @@ long gk20a_channel_ioctl(struct file *filp,
break; break;
} }
/*
* This restriction is because the last entry is kept empty and used to
* determine buffer empty or full condition. Additionally, kmd submit
* uses pre/post sync which need another entry.
*/
if ((setup_bind_args.flags &
NVGPU_CHANNEL_SETUP_BIND_FLAGS_USERMODE_SUPPORT) != 0U) {
if (setup_bind_args.num_gpfifo_entries < 2U) {
err = -EINVAL;
gk20a_idle(ch->g);
break;
}
} else {
if (setup_bind_args.num_gpfifo_entries < 4U) {
err = -EINVAL;
gk20a_idle(ch->g);
break;
}
}
if (!is_power_of_2(setup_bind_args.num_gpfifo_entries)) { if (!is_power_of_2(setup_bind_args.num_gpfifo_entries)) {
err = -EINVAL; err = -EINVAL;
gk20a_idle(ch->g); gk20a_idle(ch->g);
break; break;
} }
/*
* setup_bind_args.num_gpfifo_entries * nvgpu_get_gpfifo_entry_size() has
* to fit in u32.
*/
if (setup_bind_args.num_gpfifo_entries >
(U32_MAX / nvgpu_get_gpfifo_entry_size())) {
err = -EINVAL;
gk20a_idle(ch->g);
break;
}
err = nvgpu_channel_setup_bind(ch, &setup_bind_args); err = nvgpu_channel_setup_bind(ch, &setup_bind_args);
channel_setup_bind_args->work_submit_token = channel_setup_bind_args->work_submit_token =
setup_bind_args.work_submit_token; setup_bind_args.work_submit_token;
@@ -1371,11 +1403,44 @@ long gk20a_channel_ioctl(struct file *filp,
break; break;
} }
/*
* This restriction is because the last entry is kept empty and used to
* determine buffer empty or full condition. Additionally, kmd submit
* uses pre/post sync which need another entry.
*/
if ((alloc_gpfifo_ex_args->flags &
NVGPU_CHANNEL_SETUP_BIND_FLAGS_USERMODE_SUPPORT) != 0U) {
if (alloc_gpfifo_ex_args->num_entries < 2U) {
err = -EINVAL;
gk20a_idle(ch->g);
break;
}
} else {
if (alloc_gpfifo_ex_args->num_entries < 4U) {
err = -EINVAL;
gk20a_idle(ch->g);
break;
}
}
if (!is_power_of_2(alloc_gpfifo_ex_args->num_entries)) { if (!is_power_of_2(alloc_gpfifo_ex_args->num_entries)) {
err = -EINVAL; err = -EINVAL;
gk20a_idle(ch->g); gk20a_idle(ch->g);
break; break;
} }
/*
* alloc_gpfifo_ex_args->num_entries * nvgpu_get_gpfifo_entry_size() has
* to fit in u32.
*/
if (alloc_gpfifo_ex_args->num_entries >
(U32_MAX / nvgpu_get_gpfifo_entry_size())) {
err = -EINVAL;
gk20a_idle(ch->g);
break;
}
err = nvgpu_channel_setup_bind(ch, &setup_bind_args); err = nvgpu_channel_setup_bind(ch, &setup_bind_args);
gk20a_idle(ch->g); gk20a_idle(ch->g);
break; break;

View File

@@ -694,6 +694,16 @@ struct nvgpu_alloc_gpfifo_ex_args {
* Setup the channel and bind it (enable). * Setup the channel and bind it (enable).
*/ */
struct nvgpu_channel_setup_bind_args { struct nvgpu_channel_setup_bind_args {
/*
* Must be power of 2. Max value U32_MAX/8 (size of gpfifo entry) rounded of to
* nearest lower power of 2 i.e. 2^28. The lower limit is due to the fact that
* the last entry of gpfifo is kept empty and used to determine buffer empty or
* full condition. Additionally, kmd submit uses pre/post sync which needs
* another extra entry.
* Range: 2, 4, 8, ..., 2^28 when
* NVGPU_CHANNEL_SETUP_BIND_FLAGS_USERMODE_SUPPORT is set.
* Range: 4, 8, 16, ..., 2^28 otherwise.
*/
__u32 num_gpfifo_entries; __u32 num_gpfifo_entries;
__u32 num_inflight_jobs; __u32 num_inflight_jobs;
/* Set owner channel of this gpfifo as a vpr channel. */ /* Set owner channel of this gpfifo as a vpr channel. */