aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_debugfs.c
diff options
context:
space:
mode:
authorBen Widawsky <ben@bwidawsk.net>2011-04-25 14:25:56 -0400
committerKeith Packard <keithp@keithp.com>2011-05-10 16:56:48 -0400
commit6d794d4250284917fa394c550f054f5fd801f50f (patch)
treecaedd09d3bf580b703cc300a7b538e23d523601e /drivers/gpu/drm/i915/i915_debugfs.c
parent4912d04193733a825216b926ffd290fada88ab07 (diff)
drm/i915: debugfs interface for forcewake reference count
forcewake is controlled by the open and close of the debugfs file. This assures that buggy applications cannot cause the GT to stay on forever. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_debugfs.c')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 9069f284495f..c0ce5e44ac3a 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1217,6 +1217,18 @@ static int i915_context_status(struct seq_file *m, void *unused)
1217 return 0; 1217 return 0;
1218} 1218}
1219 1219
1220static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
1221{
1222 struct drm_info_node *node = (struct drm_info_node *) m->private;
1223 struct drm_device *dev = node->minor->dev;
1224 struct drm_i915_private *dev_priv = dev->dev_private;
1225
1226 seq_printf(m, "forcewake count = %d\n",
1227 atomic_read(&dev_priv->forcewake_count));
1228
1229 return 0;
1230}
1231
1220static int 1232static int
1221i915_wedged_open(struct inode *inode, 1233i915_wedged_open(struct inode *inode,
1222 struct file *filp) 1234 struct file *filp)
@@ -1319,6 +1331,67 @@ static int i915_wedged_create(struct dentry *root, struct drm_minor *minor)
1319 return drm_add_fake_info_node(minor, ent, &i915_wedged_fops); 1331 return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
1320} 1332}
1321 1333
1334static int i915_forcewake_open(struct inode *inode, struct file *file)
1335{
1336 struct drm_device *dev = inode->i_private;
1337 struct drm_i915_private *dev_priv = dev->dev_private;
1338 int ret;
1339
1340 if (!IS_GEN6(dev))
1341 return 0;
1342
1343 ret = mutex_lock_interruptible(&dev->struct_mutex);
1344 if (ret)
1345 return ret;
1346 gen6_gt_force_wake_get(dev_priv);
1347 mutex_unlock(&dev->struct_mutex);
1348
1349 return 0;
1350}
1351
1352int i915_forcewake_release(struct inode *inode, struct file *file)
1353{
1354 struct drm_device *dev = inode->i_private;
1355 struct drm_i915_private *dev_priv = dev->dev_private;
1356
1357 if (!IS_GEN6(dev))
1358 return 0;
1359
1360 /*
1361 * It's bad that we can potentially hang userspace if struct_mutex gets
1362 * forever stuck. However, if we cannot acquire this lock it means that
1363 * almost certainly the driver has hung, is not unload-able. Therefore
1364 * hanging here is probably a minor inconvenience not to be seen my
1365 * almost every user.
1366 */
1367 mutex_lock(&dev->struct_mutex);
1368 gen6_gt_force_wake_put(dev_priv);
1369 mutex_unlock(&dev->struct_mutex);
1370
1371 return 0;
1372}
1373
1374static const struct file_operations i915_forcewake_fops = {
1375 .owner = THIS_MODULE,
1376 .open = i915_forcewake_open,
1377 .release = i915_forcewake_release,
1378};
1379
1380static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor)
1381{
1382 struct drm_device *dev = minor->dev;
1383 struct dentry *ent;
1384
1385 ent = debugfs_create_file("i915_forcewake_user",
1386 S_IRWXU,
1387 root, dev,
1388 &i915_forcewake_fops);
1389 if (IS_ERR(ent))
1390 return PTR_ERR(ent);
1391
1392 return 0;
1393}
1394
1322static struct drm_info_list i915_debugfs_list[] = { 1395static struct drm_info_list i915_debugfs_list[] = {
1323 {"i915_capabilities", i915_capabilities, 0}, 1396 {"i915_capabilities", i915_capabilities, 0},
1324 {"i915_gem_objects", i915_gem_object_info, 0}, 1397 {"i915_gem_objects", i915_gem_object_info, 0},
@@ -1356,6 +1429,7 @@ static struct drm_info_list i915_debugfs_list[] = {
1356 {"i915_opregion", i915_opregion, 0}, 1429 {"i915_opregion", i915_opregion, 0},
1357 {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, 1430 {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
1358 {"i915_context_status", i915_context_status, 0}, 1431 {"i915_context_status", i915_context_status, 0},
1432 {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
1359}; 1433};
1360#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) 1434#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
1361 1435
@@ -1367,6 +1441,10 @@ int i915_debugfs_init(struct drm_minor *minor)
1367 if (ret) 1441 if (ret)
1368 return ret; 1442 return ret;
1369 1443
1444 ret = i915_forcewake_create(minor->debugfs_root, minor);
1445 if (ret)
1446 return ret;
1447
1370 return drm_debugfs_create_files(i915_debugfs_list, 1448 return drm_debugfs_create_files(i915_debugfs_list,
1371 I915_DEBUGFS_ENTRIES, 1449 I915_DEBUGFS_ENTRIES,
1372 minor->debugfs_root, minor); 1450 minor->debugfs_root, minor);
@@ -1376,6 +1454,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
1376{ 1454{
1377 drm_debugfs_remove_files(i915_debugfs_list, 1455 drm_debugfs_remove_files(i915_debugfs_list,
1378 I915_DEBUGFS_ENTRIES, minor); 1456 I915_DEBUGFS_ENTRIES, minor);
1457 drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops,
1458 1, minor);
1379 drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops, 1459 drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
1380 1, minor); 1460 1, minor);
1381} 1461}