summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2017-11-06 07:25:47 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-11-06 15:27:35 -0500
commit8bdce5337ee5f4d1e1f6d4c7b2dc0abe4a532893 (patch)
tree26274011c5223478744127fe0edf60ca99bd1a35 /drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
parent1480afeb013decec1d5451fd0d3eeaffa8e17bb6 (diff)
gpu: nvgpu: support tuning per-ch deterministic opts
Add a new ioctl NVGPU_GPU_IOCTL_SET_DETERMINISTIC_OPTS to adjust deterministic options on a per-channel basis. Currently, the only supported option is to relax the no-railgating requirement on open deterministic channels. This also disallows submits on such channels, until the railgate option is reset. Bug 200327089 Change-Id: If4f0f51fd1d40ad7407d13638150d7402479aff0 Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1554563 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
index 73911717..08a831b9 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
@@ -161,6 +161,8 @@ static struct nvgpu_flags_mapping flags_mapping[] = {
161 NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_NO_JOBTRACKING}, 161 NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_NO_JOBTRACKING},
162 {NVGPU_GPU_FLAGS_SUPPORT_DETERMINISTIC_SUBMIT_FULL, 162 {NVGPU_GPU_FLAGS_SUPPORT_DETERMINISTIC_SUBMIT_FULL,
163 NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_FULL}, 163 NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_FULL},
164 {NVGPU_GPU_FLAGS_SUPPORT_DETERMINISTIC_OPTS,
165 NVGPU_SUPPORT_DETERMINISTIC_OPTS},
164 {NVGPU_GPU_FLAGS_SUPPORT_IO_COHERENCE, 166 {NVGPU_GPU_FLAGS_SUPPORT_IO_COHERENCE,
165 NVGPU_SUPPORT_IO_COHERENCE}, 167 NVGPU_SUPPORT_IO_COHERENCE},
166 {NVGPU_GPU_FLAGS_SUPPORT_RESCHEDULE_RUNLIST, 168 {NVGPU_GPU_FLAGS_SUPPORT_RESCHEDULE_RUNLIST,
@@ -1319,6 +1321,114 @@ static int nvgpu_gpu_set_therm_alert_limit(struct gk20a *g,
1319 return err; 1321 return err;
1320} 1322}
1321 1323
1324static int nvgpu_gpu_set_deterministic_ch_railgate(struct channel_gk20a *ch,
1325 u32 flags)
1326{
1327 int err = 0;
1328 bool allow;
1329 bool disallow;
1330
1331 allow = flags &
1332 NVGPU_GPU_SET_DETERMINISTIC_OPTS_FLAGS_ALLOW_RAILGATING;
1333
1334 disallow = flags &
1335 NVGPU_GPU_SET_DETERMINISTIC_OPTS_FLAGS_DISALLOW_RAILGATING;
1336
1337 /* Can't be both at the same time */
1338 if (allow && disallow)
1339 return -EINVAL;
1340
1341 /* Nothing to do */
1342 if (!allow && !disallow)
1343 return 0;
1344
1345 /*
1346 * Moving into explicit idle or back from it? A call that doesn't
1347 * change the status is a no-op.
1348 */
1349 if (!ch->deterministic_railgate_allowed &&
1350 allow) {
1351 gk20a_idle(ch->g);
1352 } else if (ch->deterministic_railgate_allowed &&
1353 !allow) {
1354 err = gk20a_busy(ch->g);
1355 if (err) {
1356 nvgpu_warn(ch->g,
1357 "cannot busy to restore deterministic ch");
1358 return err;
1359 }
1360 }
1361 ch->deterministic_railgate_allowed = allow;
1362
1363 return err;
1364}
1365
1366static int nvgpu_gpu_set_deterministic_ch(struct channel_gk20a *ch, u32 flags)
1367{
1368 if (!ch->deterministic)
1369 return -EINVAL;
1370
1371 return nvgpu_gpu_set_deterministic_ch_railgate(ch, flags);
1372}
1373
1374static int nvgpu_gpu_set_deterministic_opts(struct gk20a *g,
1375 struct nvgpu_gpu_set_deterministic_opts_args *args)
1376{
1377 int __user *user_channels;
1378 u32 i = 0;
1379 int err = 0;
1380
1381 gk20a_dbg_fn("");
1382
1383 user_channels = (int __user *)(uintptr_t)args->channels;
1384
1385 /* Upper limit; prevent holding deterministic_busy for long */
1386 if (args->num_channels > g->fifo.num_channels) {
1387 err = -EINVAL;
1388 goto out;
1389 }
1390
1391 /* Trivial sanity check first */
1392 if (!access_ok(VERIFY_READ, user_channels,
1393 args->num_channels * sizeof(int))) {
1394 err = -EFAULT;
1395 goto out;
1396 }
1397
1398 nvgpu_rwsem_down_read(&g->deterministic_busy);
1399
1400 /* note: we exit at the first failure */
1401 for (; i < args->num_channels; i++) {
1402 int ch_fd = 0;
1403 struct channel_gk20a *ch;
1404
1405 if (copy_from_user(&ch_fd, &user_channels[i], sizeof(int))) {
1406 /* User raced with above access_ok */
1407 err = -EFAULT;
1408 break;
1409 }
1410
1411 ch = gk20a_get_channel_from_file(ch_fd);
1412 if (!ch) {
1413 err = -EINVAL;
1414 break;
1415 }
1416
1417 err = nvgpu_gpu_set_deterministic_ch(ch, args->flags);
1418
1419 gk20a_channel_put(ch);
1420
1421 if (err)
1422 break;
1423 }
1424
1425 nvgpu_rwsem_up_read(&g->deterministic_busy);
1426
1427out:
1428 args->num_channels = i;
1429 return err;
1430}
1431
1322long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 1432long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1323{ 1433{
1324 struct gk20a_ctrl_priv *priv = filp->private_data; 1434 struct gk20a_ctrl_priv *priv = filp->private_data;
@@ -1633,6 +1743,11 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg
1633 (struct nvgpu_gpu_set_therm_alert_limit_args *)buf); 1743 (struct nvgpu_gpu_set_therm_alert_limit_args *)buf);
1634 break; 1744 break;
1635 1745
1746 case NVGPU_GPU_IOCTL_SET_DETERMINISTIC_OPTS:
1747 err = nvgpu_gpu_set_deterministic_opts(g,
1748 (struct nvgpu_gpu_set_deterministic_opts_args *)buf);
1749 break;
1750
1636 default: 1751 default:
1637 gk20a_dbg_info("unrecognized gpu ioctl cmd: 0x%x", cmd); 1752 gk20a_dbg_info("unrecognized gpu ioctl cmd: 0x%x", cmd);
1638 err = -ENOTTY; 1753 err = -ENOTTY;