summaryrefslogtreecommitdiff
path: root/mali_pixel/memory_group_manager.c
diff options
context:
space:
mode:
authorJack Diver <diverj@google.com>2023-02-08 15:37:57 +0000
committerJack Diver <diverj@google.com>2023-03-23 12:11:40 +0000
commit37d40a8fccf65c9a318e73b7146d46000f80019c (patch)
tree0c631311f3920e6c720bd0ce42b9b9e8e2087dd1 /mali_pixel/memory_group_manager.c
parentd84cb2e922d2f22438f5609f43abf54a2c74b8be (diff)
downloadgpu-37d40a8fccf65c9a318e73b7146d46000f80019c.tar.gz
mali_pixel: Add support for multi-partition groups.
The only way to 'resize' an SLC partition, is to mutate it using another partition. To support this in the memory group manager, we need to support multiple possible partitions per memory group, with a single active partition that can be mutated. Bug: 264990406 Test: Build mali_kbase, mali_pixel Test: Boot to home Change-Id: Ic9cb905405f82d4bdc86de5776b67c86a0b94b80 Signed-off-by: Jack Diver <diverj@google.com>
Diffstat (limited to 'mali_pixel/memory_group_manager.c')
-rw-r--r--mali_pixel/memory_group_manager.c157
1 files changed, 102 insertions, 55 deletions
diff --git a/mali_pixel/memory_group_manager.c b/mali_pixel/memory_group_manager.c
index 436404e..64cf692 100644
--- a/mali_pixel/memory_group_manager.c
+++ b/mali_pixel/memory_group_manager.c
@@ -24,6 +24,9 @@
#include <soc/google/pt.h>
+#include <uapi/gpu/arm/midgard/platform/pixel/pixel_memory_group_manager.h>
+
+
#define ORDER_SMALL_PAGE 0
#define ORDER_LARGE_PAGE 9
@@ -31,18 +34,6 @@
#define PBHA_BIT_MASK (0xf)
#define MGM_PBHA_DEFAULT 0
-#define GROUP_ID_TO_PT_IDX(x) ((x)-1)
-
-/* The Mali driver requires that allocations made on one of the groups
- * are not treated specially.
- */
-#define MGM_RESERVED_GROUP_ID 0
-
-/* Imported memory is handled by the allocator of the memory, and the Mali
- * DDK will request a group_id for such memory via mgm_get_import_memory_id().
- * We specify which group we want to use for this here.
- */
-#define MGM_IMPORTED_MEMORY_GROUP_ID (MEMORY_GROUP_MANAGER_NR_GROUPS - 1)
#define INVALID_GROUP_ID(group_id) \
(WARN_ON((group_id) < 0) || \
@@ -71,8 +62,12 @@ static inline vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma,
* @lp_size: The number of allocated large(2MB) pages
* @insert_pfn: The number of calls to map pages for CPU access.
* @update_gpu_pte: The number of calls to update GPU page table entries.
- * @ptid: The partition ID for this group
+ * @ptid: The active partition ID for this group
* @pbha: The PBHA bits assigned to this group,
+ * @base_pt: The base partition ID available to this group.
+ * @pt_num: The number of partitions available to this group.
+ * @active_pt_idx: The relative index for the partition backing the group.
+ * Different from the absolute ptid.
* @state: The lifecycle state of the partition associated with this group
* This structure allows page allocation information to be displayed via
* debugfs. Display is organized per group with small and large sized pages.
@@ -85,6 +80,10 @@ struct mgm_group {
ptid_t ptid;
ptpbha_t pbha;
+
+ u32 base_pt;
+ u32 pt_num;
+ u32 active_pt_idx;
enum {
MGM_GROUP_STATE_NEW = 0,
MGM_GROUP_STATE_ENABLED = 10,
@@ -98,6 +97,8 @@ struct mgm_group {
*
* @groups: To keep track of the number of allocated pages of all groups
* @ngroups: Number of groups actually used
+ * @npartitions: Number of partitions used by all groups combined
+ * @pt_sizes: The size of each partition
* @dev: device attached
* @pt_handle: Link to SLC partition data
* @kobj: &sruct kobject used for linking to pixel_stats_sysfs node
@@ -109,6 +110,8 @@ struct mgm_group {
struct mgm_groups {
struct mgm_group groups[MEMORY_GROUP_MANAGER_NR_GROUPS];
size_t ngroups;
+ size_t npartitions;
+ u32 *pt_sizes;
struct device *dev;
struct pt_handle *pt_handle;
struct kobject kobj;
@@ -357,6 +360,19 @@ static void mgm_sysfs_term(struct mgm_groups *data)
#endif /* CONFIG_MALI_PIXEL_STATS */
+static int group_pt_id(struct mgm_groups *data, enum pixel_mgm_group_id group_id, int pt_index)
+{
+ struct mgm_group *group = &data->groups[group_id];
+ if (WARN_ON_ONCE(pt_index >= group->pt_num))
+ return 0;
+
+ return group->base_pt + pt_index;
+}
+
+static int group_active_pt_id(struct mgm_groups *data, enum pixel_mgm_group_id group_id)
+{
+ return group_pt_id(data, group_id, data->groups[group_id].active_pt_idx);
+}
static atomic64_t total_gpu_pages = ATOMIC64_INIT(0);
@@ -400,6 +416,27 @@ static void update_size(struct memory_group_manager_device *mgm_dev, int
pr_warn("total_gpu_pages %lld\n", atomic64_read(&total_gpu_pages));
}
+static void enable_partition(struct mgm_groups* data, enum pixel_mgm_group_id group_id)
+{
+ int ptid, pbha;
+
+ ptid = pt_client_enable(data->pt_handle, group_active_pt_id(data, group_id));
+ if (ptid == -EINVAL)
+ dev_err(data->dev, "Failed to get partition for group: %d\n", group_id);
+ else
+ dev_info(data->dev, "pt_client_enable returned ptid=%d for group=%d", ptid, group_id);
+
+ pbha = pt_pbha(data->dev->of_node, group_active_pt_id(data, group_id));
+ if (pbha == PT_PBHA_INVALID)
+ dev_err(data->dev, "Failed to get PBHA for group: %d\n", group_id);
+ else
+ dev_info(data->dev, "pt_pbha returned PBHA=%d for group=%d", pbha, group_id);
+
+ data->groups[group_id].ptid = ptid;
+ data->groups[group_id].pbha = pbha;
+ data->groups[group_id].state = MGM_GROUP_STATE_ENABLED;
+}
+
static struct page *mgm_alloc_page(
struct memory_group_manager_device *mgm_dev, int group_id,
gfp_t gfp_mask, unsigned int order)
@@ -415,7 +452,7 @@ static struct page *mgm_alloc_page(
return NULL;
if (WARN_ON_ONCE((group_id != MGM_RESERVED_GROUP_ID) &&
- (GROUP_ID_TO_PT_IDX(group_id) >= data->ngroups)))
+ (group_active_pt_id(data, group_id) >= data->npartitions)))
return NULL;
/* We don't expect to be allocting pages into the group used for
@@ -428,38 +465,9 @@ static struct page *mgm_alloc_page(
* ensure that we have enabled the relevant partitions for it.
*/
if (group_id != MGM_RESERVED_GROUP_ID) {
- int ptid, pbha;
switch (data->groups[group_id].state) {
case MGM_GROUP_STATE_NEW:
- ptid = pt_client_enable(data->pt_handle,
- GROUP_ID_TO_PT_IDX(group_id));
- if (ptid == -EINVAL) {
- dev_err(data->dev,
- "Failed to get partition for group: "
- "%d\n", group_id);
- } else {
- dev_info(data->dev,
- "pt_client_enable returned ptid=%d for"
- " group=%d",
- ptid, group_id);
- }
-
- pbha = pt_pbha(data->dev->of_node,
- GROUP_ID_TO_PT_IDX(group_id));
- if (pbha == PT_PBHA_INVALID) {
- dev_err(data->dev,
- "Failed to get PBHA for group: %d\n",
- group_id);
- } else {
- dev_info(data->dev,
- "pt_pbha returned PBHA=%d for group=%d",
- pbha, group_id);
- }
-
- data->groups[group_id].ptid = ptid;
- data->groups[group_id].pbha = pbha;
- data->groups[group_id].state = MGM_GROUP_STATE_ENABLED;
-
+ enable_partition(data, group_id);
break;
case MGM_GROUP_STATE_ENABLED:
case MGM_GROUP_STATE_DISABLED_NOT_FREED:
@@ -579,7 +587,7 @@ static u64 mgm_update_gpu_pte(
}
static u64 mgm_pte_to_original_pte(struct memory_group_manager_device *mgm_dev, int group_id,
- int mmu_level, u64 pte)
+ int mmu_level, u64 pte)
{
struct mgm_groups *const data = mgm_dev->data;
u64 old_pte;
@@ -643,13 +651,29 @@ static int mgm_initialize_data(struct mgm_groups *mgm_data)
{
int i, ret;
- const int ngroups = of_property_count_strings(mgm_data->dev->of_node, "pt_id");
+ /* +1 to include the required default group */
+ const int ngroups = of_property_count_strings(mgm_data->dev->of_node, "groups") + 1;
if (WARN_ON(ngroups < 0) ||
WARN_ON(ngroups > MEMORY_GROUP_MANAGER_NR_GROUPS)) {
mgm_data->ngroups = 0;
} else {
mgm_data->ngroups = ngroups;
}
+ mgm_data->npartitions = of_property_count_strings(mgm_data->dev->of_node, "pt_id");
+
+ mgm_data->pt_sizes = kzalloc(mgm_data->npartitions * sizeof(*mgm_data), GFP_KERNEL);
+ if (mgm_data->pt_sizes == NULL) {
+ dev_err(mgm_data->dev, "failed to allocate space for pt_sizes");
+ ret = -ENOMEM;
+ goto out_err;
+ }
+
+ ret = of_property_read_u32_array(
+ mgm_data->dev->of_node, "pt_size", mgm_data->pt_sizes, mgm_data->npartitions);
+ if (ret) {
+ dev_err(mgm_data->dev, "failed to read pt_size");
+ goto out_err;
+ }
for (i = 0; i < MEMORY_GROUP_MANAGER_NR_GROUPS; i++) {
atomic_set(&mgm_data->groups[i].size, 0);
@@ -658,22 +682,42 @@ static int mgm_initialize_data(struct mgm_groups *mgm_data)
atomic_set(&mgm_data->groups[i].update_gpu_pte, 0);
mgm_data->groups[i].pbha = MGM_PBHA_DEFAULT;
+ mgm_data->groups[i].base_pt = 0;
+ mgm_data->groups[i].pt_num = 0;
+ mgm_data->groups[i].active_pt_idx = 0;
mgm_data->groups[i].state = MGM_GROUP_STATE_NEW;
}
+ /* Discover the partitions belonging to each memory group, skipping the reserved group */
+ for (i = 1; i < mgm_data->ngroups; i++) {
+ /* Device tree has no description for the reserved group */
+ int const dt_idx = i - 1;
+
+ int err = of_property_read_u32_index(
+ mgm_data->dev->of_node, "group_base_pt", dt_idx, &mgm_data->groups[i].base_pt);
+ if (err) {
+ dev_warn(mgm_data->dev, "failed to read base pt index for group %d", i);
+ continue;
+ }
+
+ err = of_property_read_u32_index(
+ mgm_data->dev->of_node, "group_pt_num", dt_idx, &mgm_data->groups[i].pt_num);
+ if (err)
+ dev_warn(mgm_data->dev, "failed to read pt number for group %d", i);
+ }
+
/*
* Initialize SLC partitions. We don't enable partitions until
* we actually allocate memory to the corresponding memory
* group
*/
- mgm_data->pt_handle = pt_client_register(
- mgm_data->dev->of_node,
- (void *)mgm_data, &mgm_resize_callback);
+ mgm_data->pt_handle =
+ pt_client_register(mgm_data->dev->of_node, (void*)mgm_data, &mgm_resize_callback);
if (IS_ERR(mgm_data->pt_handle)) {
ret = PTR_ERR(mgm_data->pt_handle);
dev_err(mgm_data->dev, "pt_client_register returned %d\n", ret);
- return ret;
+ goto out_err;
}
/* We don't use PBHA bits for the reserved memory group, and so
@@ -681,13 +725,16 @@ static int mgm_initialize_data(struct mgm_groups *mgm_data)
*/
mgm_data->groups[MGM_RESERVED_GROUP_ID].state = MGM_GROUP_STATE_ENABLED;
- ret = mgm_debugfs_init(mgm_data);
- if (ret)
- goto out;
+ if ((ret = mgm_debugfs_init(mgm_data)))
+ goto out_err;
- ret = mgm_sysfs_init(mgm_data);
+ if ((ret = mgm_sysfs_init(mgm_data)))
+ goto out_err;
+
+ return ret;
-out:
+out_err:
+ kfree(mgm_data->pt_sizes);
return ret;
}