diff options
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo.c')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 69 |
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 | ||
46 | static void ttm_bo_global_kobj_release(struct kobject *kobj); | 46 | static void ttm_bo_global_kobj_release(struct kobject *kobj); |
47 | 47 | ||
48 | /** | ||
49 | * ttm_global_mutex - protecting the global BO state | ||
50 | */ | ||
51 | DEFINE_MUTEX(ttm_global_mutex); | ||
52 | struct ttm_bo_global ttm_bo_glob = { | ||
53 | .use_count = 0 | ||
54 | }; | ||
55 | |||
48 | static struct attribute ttm_bo_count = { | 56 | static 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 | ||
1525 | void ttm_bo_global_release(struct drm_global_reference *ref) | 1532 | static 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); | ||
1543 | out: | ||
1544 | mutex_unlock(&ttm_global_mutex); | ||
1531 | } | 1545 | } |
1532 | EXPORT_SYMBOL(ttm_bo_global_release); | ||
1533 | 1546 | ||
1534 | int ttm_bo_global_init(struct drm_global_reference *ref) | 1547 | static 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; | 1580 | out: |
1563 | out_no_drp: | 1581 | mutex_unlock(&ttm_global_mutex); |
1564 | kfree(glob); | ||
1565 | return ret; | 1582 | return ret; |
1566 | } | 1583 | } |
1567 | EXPORT_SYMBOL(ttm_bo_global_init); | ||
1568 | |||
1569 | 1584 | ||
1570 | int ttm_bo_device_release(struct ttm_bo_device *bdev) | 1585 | int 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 | } |
1609 | EXPORT_SYMBOL(ttm_bo_device_release); | 1627 | EXPORT_SYMBOL(ttm_bo_device_release); |
1610 | 1628 | ||
1611 | int ttm_bo_device_init(struct ttm_bo_device *bdev, | 1629 | int 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; |
1644 | out_no_sys: | 1666 | out_no_sys: |
1667 | ttm_bo_global_release(); | ||
1645 | return ret; | 1668 | return ret; |
1646 | } | 1669 | } |
1647 | EXPORT_SYMBOL(ttm_bo_device_init); | 1670 | EXPORT_SYMBOL(ttm_bo_device_init); |