aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ttm/ttm_bo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo.c')
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c69
1 files changed, 46 insertions, 23 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 83b4657ffb10..d87935bf8e30 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -45,6 +45,14 @@
45 45
46static void ttm_bo_global_kobj_release(struct kobject *kobj); 46static void ttm_bo_global_kobj_release(struct kobject *kobj);
47 47
48/**
49 * ttm_global_mutex - protecting the global BO state
50 */
51DEFINE_MUTEX(ttm_global_mutex);
52struct ttm_bo_global ttm_bo_glob = {
53 .use_count = 0
54};
55
48static struct attribute ttm_bo_count = { 56static struct attribute ttm_bo_count = {
49 .name = "bo_count", 57 .name = "bo_count",
50 .mode = S_IRUGO 58 .mode = S_IRUGO
@@ -1519,35 +1527,45 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj)
1519 container_of(kobj, struct ttm_bo_global, kobj); 1527 container_of(kobj, struct ttm_bo_global, kobj);
1520 1528
1521 __free_page(glob->dummy_read_page); 1529 __free_page(glob->dummy_read_page);
1522 kfree(glob);
1523} 1530}
1524 1531
1525void ttm_bo_global_release(struct drm_global_reference *ref) 1532static void ttm_bo_global_release(void)
1526{ 1533{
1527 struct ttm_bo_global *glob = ref->object; 1534 struct ttm_bo_global *glob = &ttm_bo_glob;
1535
1536 mutex_lock(&ttm_global_mutex);
1537 if (--glob->use_count > 0)
1538 goto out;
1528 1539
1529 kobject_del(&glob->kobj); 1540 kobject_del(&glob->kobj);
1530 kobject_put(&glob->kobj); 1541 kobject_put(&glob->kobj);
1542 ttm_mem_global_release(&ttm_mem_glob);
1543out:
1544 mutex_unlock(&ttm_global_mutex);
1531} 1545}
1532EXPORT_SYMBOL(ttm_bo_global_release);
1533 1546
1534int ttm_bo_global_init(struct drm_global_reference *ref) 1547static int ttm_bo_global_init(void)
1535{ 1548{
1536 struct ttm_bo_global_ref *bo_ref = 1549 struct ttm_bo_global *glob = &ttm_bo_glob;
1537 container_of(ref, struct ttm_bo_global_ref, ref); 1550 int ret = 0;
1538 struct ttm_bo_global *glob = ref->object;
1539 int ret;
1540 unsigned i; 1551 unsigned i;
1541 1552
1542 mutex_init(&glob->device_list_mutex); 1553 mutex_lock(&ttm_global_mutex);
1554 if (++glob->use_count > 1)
1555 goto out;
1556
1557 ret = ttm_mem_global_init(&ttm_mem_glob);
1558 if (ret)
1559 goto out;
1560
1543 spin_lock_init(&glob->lru_lock); 1561 spin_lock_init(&glob->lru_lock);
1544 glob->mem_glob = bo_ref->mem_glob; 1562 glob->mem_glob = &ttm_mem_glob;
1545 glob->mem_glob->bo_glob = glob; 1563 glob->mem_glob->bo_glob = glob;
1546 glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); 1564 glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);
1547 1565
1548 if (unlikely(glob->dummy_read_page == NULL)) { 1566 if (unlikely(glob->dummy_read_page == NULL)) {
1549 ret = -ENOMEM; 1567 ret = -ENOMEM;
1550 goto out_no_drp; 1568 goto out;
1551 } 1569 }
1552 1570
1553 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) 1571 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
@@ -1559,13 +1577,10 @@ int ttm_bo_global_init(struct drm_global_reference *ref)
1559 &glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects"); 1577 &glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects");
1560 if (unlikely(ret != 0)) 1578 if (unlikely(ret != 0))
1561 kobject_put(&glob->kobj); 1579 kobject_put(&glob->kobj);
1562 return ret; 1580out:
1563out_no_drp: 1581 mutex_unlock(&ttm_global_mutex);
1564 kfree(glob);
1565 return ret; 1582 return ret;
1566} 1583}
1567EXPORT_SYMBOL(ttm_bo_global_init);
1568
1569 1584
1570int ttm_bo_device_release(struct ttm_bo_device *bdev) 1585int ttm_bo_device_release(struct ttm_bo_device *bdev)
1571{ 1586{
@@ -1587,9 +1602,9 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev)
1587 } 1602 }
1588 } 1603 }
1589 1604
1590 mutex_lock(&glob->device_list_mutex); 1605 mutex_lock(&ttm_global_mutex);
1591 list_del(&bdev->device_list); 1606 list_del(&bdev->device_list);
1592 mutex_unlock(&glob->device_list_mutex); 1607 mutex_unlock(&ttm_global_mutex);
1593 1608
1594 cancel_delayed_work_sync(&bdev->wq); 1609 cancel_delayed_work_sync(&bdev->wq);
1595 1610
@@ -1604,18 +1619,25 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev)
1604 1619
1605 drm_vma_offset_manager_destroy(&bdev->vma_manager); 1620 drm_vma_offset_manager_destroy(&bdev->vma_manager);
1606 1621
1622 if (!ret)
1623 ttm_bo_global_release();
1624
1607 return ret; 1625 return ret;
1608} 1626}
1609EXPORT_SYMBOL(ttm_bo_device_release); 1627EXPORT_SYMBOL(ttm_bo_device_release);
1610 1628
1611int ttm_bo_device_init(struct ttm_bo_device *bdev, 1629int ttm_bo_device_init(struct ttm_bo_device *bdev,
1612 struct ttm_bo_global *glob,
1613 struct ttm_bo_driver *driver, 1630 struct ttm_bo_driver *driver,
1614 struct address_space *mapping, 1631 struct address_space *mapping,
1615 uint64_t file_page_offset, 1632 uint64_t file_page_offset,
1616 bool need_dma32) 1633 bool need_dma32)
1617{ 1634{
1618 int ret = -EINVAL; 1635 struct ttm_bo_global *glob = &ttm_bo_glob;
1636 int ret;
1637
1638 ret = ttm_bo_global_init();
1639 if (ret)
1640 return ret;
1619 1641
1620 bdev->driver = driver; 1642 bdev->driver = driver;
1621 1643
@@ -1636,12 +1658,13 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev,
1636 bdev->dev_mapping = mapping; 1658 bdev->dev_mapping = mapping;
1637 bdev->glob = glob; 1659 bdev->glob = glob;
1638 bdev->need_dma32 = need_dma32; 1660 bdev->need_dma32 = need_dma32;
1639 mutex_lock(&glob->device_list_mutex); 1661 mutex_lock(&ttm_global_mutex);
1640 list_add_tail(&bdev->device_list, &glob->device_list); 1662 list_add_tail(&bdev->device_list, &glob->device_list);
1641 mutex_unlock(&glob->device_list_mutex); 1663 mutex_unlock(&ttm_global_mutex);
1642 1664
1643 return 0; 1665 return 0;
1644out_no_sys: 1666out_no_sys:
1667 ttm_bo_global_release();
1645 return ret; 1668 return ret;
1646} 1669}
1647EXPORT_SYMBOL(ttm_bo_device_init); 1670EXPORT_SYMBOL(ttm_bo_device_init);