This patch will introduce 2 eppic scripts. One is for filtering out amdgpu
mm pages, the other is for printing all tasks VMAs. dwarf & btf eppic
extension should produce the same result for every eppic script, mainly
for test use.

Signed-off-by: Tao Liu <[email protected]>
---
 eppic_scripts/filter_amdgpu_mm_pages.c | 255 +++++++++++++++++++++++++
 eppic_scripts/print_all_vma.c          | 244 +++++++++++++++++++++++
 2 files changed, 499 insertions(+)
 create mode 100644 eppic_scripts/filter_amdgpu_mm_pages.c
 create mode 100644 eppic_scripts/print_all_vma.c

diff --git a/eppic_scripts/filter_amdgpu_mm_pages.c 
b/eppic_scripts/filter_amdgpu_mm_pages.c
new file mode 100644
index 0000000..8fe6d52
--- /dev/null
+++ b/eppic_scripts/filter_amdgpu_mm_pages.c
@@ -0,0 +1,255 @@
+enum {
+       maple_dense_enum,
+       maple_leaf_64_enum,
+       maple_range_64_enum,
+       maple_arange_64_enum,
+};
+
+#define MAPLE_NODE_MASK                255UL
+#define MAPLE_NODE_TYPE_MASK   0x0F
+#define MAPLE_NODE_TYPE_SHIFT  0x03
+#define XA_ZERO_ENTRY          xa_mk_internal(257)
+#define bool                   int
+
+unsigned long mt_max;
+
+static unsigned long xa_mk_internal(unsigned long v)
+{
+       return (v << 2) | 2;
+}
+
+static bool xa_is_internal(unsigned long entry)
+{
+       return (entry & 3) == 2;
+}
+
+static bool xa_is_node(unsigned long entry)
+{
+       return xa_is_internal(entry) && entry > 4096;
+}
+
+static bool xa_is_value(unsigned long entry)
+{
+       return entry & 1;
+}
+
+static bool xa_is_zero(unsigned long entry)
+{
+       return entry == XA_ZERO_ENTRY;
+}
+
+static unsigned long xa_to_internal(unsigned long entry)
+{
+       return entry >> 2;
+}
+
+static unsigned long xa_to_value(unsigned long entry)
+{
+       return entry >> 1;
+}
+
+static struct maple_node *mte_to_node(void *entry)
+{
+        return (struct maple_node *)((unsigned long)entry & ~MAPLE_NODE_MASK);
+}
+
+static unsigned long mte_node_type(unsigned long maple_enode_entry)
+{
+       return (maple_enode_entry >> MAPLE_NODE_TYPE_SHIFT) &
+               MAPLE_NODE_TYPE_MASK;
+}
+
+static unsigned long mt_slot(void **slots, unsigned char offset)
+{
+       return *((unsigned long *)slots + offset);
+}
+
+static bool ma_is_leaf(unsigned long type)
+{
+       return type < maple_range_64_enum;
+}
+
+static bool mte_is_leaf(unsigned long maple_enode_entry)
+{
+       return ma_is_leaf(mte_node_type(maple_enode_entry));
+}
+
+static void mt_dump_entry(unsigned long entry, unsigned long min,
+                       unsigned long max, unsigned int depth, unsigned long 
array_out)
+{
+       int i;
+       if (entry == 0)
+               return;
+       for (i in array_out) {
+               if (array_out[i] == 0) {
+                       array_out[i] = entry;
+                       return;
+               }
+       }
+       array_out[i + 1] = entry;
+}
+
+static void mt_dump_range64(void *entry, unsigned long min,
+                       unsigned long max, unsigned int depth, unsigned long 
array_out)
+{
+       struct maple_range_64 *node = &mte_to_node(entry)->mr64;
+
+       bool leaf = mte_is_leaf((unsigned long)entry);
+       unsigned long first = min;
+       int i;
+
+       for (i = 0; i < *((char *)(&mt_slots) + maple_range_64_enum); i++) {
+               unsigned long last = max;
+
+               if (i < (*((char *)(&mt_slots) + maple_range_64_enum) - 1))
+                       last  = *((unsigned long *)&(node->pivot) + i);
+               else if (!*((unsigned long *)&(node->slot) + i) &&
+                       max != mt_max[mte_node_type((unsigned long)entry)])
+                       break;
+               if (last == 0 && i > 0)
+                       break;
+               if (leaf)
+                       mt_dump_entry(mt_slot(&(node->slot), i),
+                                       first, last, depth + 1, array_out);
+               else if (*((unsigned long *)&(node->slot) + i))
+                       mt_dump_node(mt_slot(&(node->slot), i),
+                                       first, last, depth + 1, array_out);
+
+               if (last == max)
+                       break;
+               if (last > max) {
+                       printf("node %p last (%lu) > max (%lu) at pivot %d!\n",
+                               node, last, max, i);
+                       break;
+               }
+               first = last + 1;
+       }
+}
+
+static void mt_dump_arange64(void *entry, unsigned long min,
+                               unsigned long max, unsigned int depth, unsigned 
long array_out)
+{
+       struct maple_arange_64 *node = &mte_to_node(entry)->ma64;
+       unsigned long first = min;
+       int i;
+
+       for (i = 0; i < *((char *)(&mt_slots) + maple_arange_64_enum); i++) {
+               unsigned long last = max;
+               if (i < (*((char *)(&mt_slots) + maple_arange_64_enum) - 1))
+                       last  = *((unsigned long *)&(node->pivot) + i);
+               else if (!*((unsigned long *)&(node->slot) + i))
+                       break;
+               if (last == 0 && i > 0)
+                       break;
+               if (*((unsigned long *)&(node->slot) + i))
+                       mt_dump_node((void *)mt_slot(&(node->slot), i),
+                                       first, last, depth + 1, array_out);
+
+               if (last == max)
+                       break;
+               if (last > max) {
+                       printf("node %p last (%lu) > max (%lu) at pivot %d!\n",
+                               node, last, max, i);
+                       break;
+               }
+               first = last + 1;
+       }
+}
+
+static void mt_dump_node(void *entry, unsigned long min,
+                       unsigned long max, unsigned int depth, unsigned long 
array_out)
+{
+       struct maple_node *node = mte_to_node(entry);
+       unsigned int type = mte_node_type((unsigned long)entry);
+       unsigned int i;
+
+       switch (type) {
+       case maple_dense_enum:
+               for (i = 0; i < *((char *)(&mt_slots) + maple_dense_enum); i++) 
{
+                       if (min + i > max)
+                               printf("OUT OF RANGE: ");
+                       mt_dump_entry(mt_slot(&(node->slot), i),
+                                       min + i, min + i, depth, array_out);
+               }
+               break;
+       case maple_leaf_64_enum:
+       case maple_range_64_enum:
+               mt_dump_range64(entry, min, max, depth, array_out);
+               break;
+       case maple_arange_64_enum:
+               mt_dump_arange64(entry, min, max, depth, array_out);
+               break;
+
+       default:
+               printf(" UNKNOWN TYPE\n");
+       }
+}
+
+void mt_dump(const struct maple_tree *mt, unsigned long array_out)
+{
+       unsigned long entry = (unsigned long)(mt->ma_root);
+
+       /* init mt_max array */
+       mt_max[maple_dense_enum]           = *((char *)(&mt_slots) + 
maple_dense_enum);
+       mt_max[maple_leaf_64_enum]         = (unsigned long)(-1);
+       mt_max[maple_range_64_enum]        = (unsigned long)(-1);
+       mt_max[maple_arange_64_enum]       = (unsigned long)(-1);
+       /* done */
+
+       if (xa_is_node(entry))
+               mt_dump_node((void *)entry, 0, mt_max[mte_node_type(entry)], 0, 
array_out);
+       else if (entry)
+               mt_dump_entry((void *)entry, 0, 0, 0, array_out);
+       else
+               printf("(empty)\n");
+}
+
+int main()
+{
+       struct task_struct *p;
+       unsigned long p_off;
+       int i, c;
+       struct vm_area_struct *vma;
+       struct ttm_buffer_object *tbo;
+       unsigned long pfn, num;
+       struct maple_tree *mt;
+       unsigned long tmp;
+
+       p = (struct task_struct *)&init_task;
+       p_off = (unsigned long)&(p->tasks) - (unsigned long)p;
+
+       do {
+               unsigned long array_out;
+               array_out[0] = 0;
+
+               if (!(p->mm)) {
+                       p = (struct task_struct *)
+                               ((unsigned long)(p->tasks.next) - p_off);
+                       continue;
+               }
+
+               mt = &(p->mm->mm_mt);
+
+               mt_dump(mt, array_out);
+
+               for (i in array_out) {
+                       if (((struct vm_area_struct *)array_out[i])->vm_ops ==
+                           &amdgpu_gem_vm_ops) {
+                                   tbo = (struct ttm_buffer_object *)
+                                   (((struct vm_area_struct *)array_out[i])->
+                                   vm_private_data);
+                               if (tbo->ttm) {
+                                       num = (unsigned 
long)(tbo->ttm->num_pages);
+                                       pfn = ((unsigned 
long)(tbo->ttm->pages[0]) -
+                                               *(unsigned long 
*)&vmemmap_base) /
+                                             sizeof(struct page);
+                                       filter_pages(pfn, num);
+                               }
+                       }
+               }
+               p = (struct task_struct *)
+                       ((unsigned long)(p->tasks.next) - p_off);
+       } while(p != &init_task);
+
+       return 0;
+}
diff --git a/eppic_scripts/print_all_vma.c b/eppic_scripts/print_all_vma.c
new file mode 100644
index 0000000..f100c78
--- /dev/null
+++ b/eppic_scripts/print_all_vma.c
@@ -0,0 +1,244 @@
+enum {
+       maple_dense_enum,
+       maple_leaf_64_enum,
+       maple_range_64_enum,
+       maple_arange_64_enum,
+};
+
+#define MAPLE_NODE_MASK                255UL
+#define MAPLE_NODE_TYPE_MASK   0x0F
+#define MAPLE_NODE_TYPE_SHIFT  0x03
+#define XA_ZERO_ENTRY          xa_mk_internal(257)
+#define bool                   int
+
+unsigned long mt_max;
+
+static unsigned long xa_mk_internal(unsigned long v)
+{
+       return (v << 2) | 2;
+}
+
+static bool xa_is_internal(unsigned long entry)
+{
+       return (entry & 3) == 2;
+}
+
+static bool xa_is_node(unsigned long entry)
+{
+       return xa_is_internal(entry) && entry > 4096;
+}
+
+static bool xa_is_value(unsigned long entry)
+{
+       return entry & 1;
+}
+
+static bool xa_is_zero(unsigned long entry)
+{
+       return entry == XA_ZERO_ENTRY;
+}
+
+static unsigned long xa_to_internal(unsigned long entry)
+{
+       return entry >> 2;
+}
+
+static unsigned long xa_to_value(unsigned long entry)
+{
+       return entry >> 1;
+}
+
+static struct maple_node *mte_to_node(void *entry)
+{
+        return (struct maple_node *)((unsigned long)entry & ~MAPLE_NODE_MASK);
+}
+
+static unsigned long mte_node_type(unsigned long maple_enode_entry)
+{
+       return (maple_enode_entry >> MAPLE_NODE_TYPE_SHIFT) &
+               MAPLE_NODE_TYPE_MASK;
+}
+
+static unsigned long mt_slot(void **slots, unsigned char offset)
+{
+       return *((unsigned long *)slots + offset);
+}
+
+static bool ma_is_leaf(unsigned long type)
+{
+       return type < maple_range_64_enum;
+}
+
+static bool mte_is_leaf(unsigned long maple_enode_entry)
+{
+       return ma_is_leaf(mte_node_type(maple_enode_entry));
+}
+
+static void mt_dump_entry(unsigned long entry, unsigned long min,
+                       unsigned long max, unsigned int depth, unsigned long 
array_out)
+{
+       int i;
+       if (entry == 0)
+               return;
+       for (i in array_out) {
+               if (array_out[i] == 0) {
+                       array_out[i] = entry;
+                       return;
+               }
+       }
+       array_out[i + 1] = entry;
+}
+
+static void mt_dump_range64(void *entry, unsigned long min,
+                       unsigned long max, unsigned int depth, unsigned long 
array_out)
+{
+       struct maple_range_64 *node = &mte_to_node(entry)->mr64;
+
+       bool leaf = mte_is_leaf((unsigned long)entry);
+       unsigned long first = min;
+       int i;
+
+       for (i = 0; i < *((char *)(&mt_slots) + maple_range_64_enum); i++) {
+               unsigned long last = max;
+
+               if (i < (*((char *)(&mt_slots) + maple_range_64_enum) - 1))
+                       last  = *((unsigned long *)&(node->pivot) + i);
+               else if (!*((unsigned long *)&(node->slot) + i) &&
+                       max != mt_max[mte_node_type((unsigned long)entry)])
+                       break;
+               if (last == 0 && i > 0)
+                       break;
+               if (leaf)
+                       mt_dump_entry(mt_slot(&(node->slot), i),
+                                       first, last, depth + 1, array_out);
+               else if (*((unsigned long *)&(node->slot) + i))
+                       mt_dump_node(mt_slot(&(node->slot), i),
+                                       first, last, depth + 1, array_out);
+
+               if (last == max)
+                       break;
+               if (last > max) {
+                       printf("node %p last (%lu) > max (%lu) at pivot %d!\n",
+                               node, last, max, i);
+                       break;
+               }
+               first = last + 1;
+       }
+}
+
+static void mt_dump_arange64(void *entry, unsigned long min,
+                               unsigned long max, unsigned int depth, unsigned 
long array_out)
+{
+       struct maple_arange_64 *node = &mte_to_node(entry)->ma64;
+       unsigned long first = min;
+       int i;
+
+       for (i = 0; i < *((char *)(&mt_slots) + maple_arange_64_enum); i++) {
+               unsigned long last = max;
+               if (i < (*((char *)(&mt_slots) + maple_arange_64_enum) - 1))
+                       last  = *((unsigned long *)&(node->pivot) + i);
+               else if (!*((unsigned long *)&(node->slot) + i))
+                       break;
+               if (last == 0 && i > 0)
+                       break;
+               if (*((unsigned long *)&(node->slot) + i))
+                       mt_dump_node((void *)mt_slot(&(node->slot), i),
+                                       first, last, depth + 1, array_out);
+
+               if (last == max)
+                       break;
+               if (last > max) {
+                       printf("node %p last (%lu) > max (%lu) at pivot %d!\n",
+                               node, last, max, i);
+                       break;
+               }
+               first = last + 1;
+       }
+}
+
+static void mt_dump_node(void *entry, unsigned long min,
+                       unsigned long max, unsigned int depth, unsigned long 
array_out)
+{
+       struct maple_node *node = mte_to_node(entry);
+       unsigned int type = mte_node_type((unsigned long)entry);
+       unsigned int i;
+
+       switch (type) {
+       case maple_dense_enum:
+               for (i = 0; i < *((char *)(&mt_slots) + maple_dense_enum); i++) 
{
+                       if (min + i > max)
+                               printf("OUT OF RANGE: ");
+                       mt_dump_entry(mt_slot(&(node->slot), i),
+                                       min + i, min + i, depth, array_out);
+               }
+               break;
+       case maple_leaf_64_enum:
+       case maple_range_64_enum:
+               mt_dump_range64(entry, min, max, depth, array_out);
+               break;
+       case maple_arange_64_enum:
+               mt_dump_arange64(entry, min, max, depth, array_out);
+               break;
+
+       default:
+               printf(" UNKNOWN TYPE\n");
+       }
+}
+
+void mt_dump(const struct maple_tree *mt, unsigned long array_out)
+{
+       unsigned long entry = (unsigned long)(mt->ma_root);
+
+       /* init mt_max array */
+       mt_max[maple_dense_enum]           = *((char *)(&mt_slots) + 
maple_dense_enum);
+       mt_max[maple_leaf_64_enum]         = (unsigned long)(-1);
+       mt_max[maple_range_64_enum]        = (unsigned long)(-1);
+       mt_max[maple_arange_64_enum]       = (unsigned long)(-1);
+       /* done */
+
+       if (xa_is_node(entry))
+               mt_dump_node((void *)entry, 0, mt_max[mte_node_type(entry)], 0, 
array_out);
+       else if (entry)
+               mt_dump_entry((void *)entry, 0, 0, 0, array_out);
+       else
+               printf("(empty)\n");
+}
+
+int main()
+{
+       struct task_struct *p;
+       unsigned long p_off;
+       int i, c;
+       struct vm_area_struct *vma;
+       struct ttm_buffer_object *tbo;
+       unsigned long pfn, num;
+       struct maple_tree *mt;
+       unsigned long tmp;
+
+       p = (struct task_struct *)&init_task;
+       p_off = (unsigned long)&(p->tasks) - (unsigned long)p;
+
+       do {
+               unsigned long array_out;
+               array_out[0] = 0;
+
+               if (!(p->mm)) {
+                       p = (struct task_struct *)
+                               ((unsigned long)(p->tasks.next) - p_off);
+                       continue;
+               }
+
+               mt = &(p->mm->mm_mt);
+
+               mt_dump(mt, array_out);
+               printf("PID: %d\n", (int)(p->pid));
+
+               for (i in array_out) {
+                       printf("%lx\n", array_out[i]);
+               }
+               p = (struct task_struct *)
+                       ((unsigned long)(p->tasks.next) - p_off);
+       } while(p != &init_task);
+
+       return 0;
+}
-- 
2.47.0


Reply via email to