Re: [PATCH] mm/cma: export total and free number of pages for CMA areas

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 9, 2024 at 9:31 AM Frank van der Linden <fvdl@xxxxxxxxxx> wrote:
>
> In addition to the number of allocations and releases, system
> management software may like to be aware of the size of CMA
> areas, and how many pages are available in it. This information
> is currently not available, so export it in total_page and
> available_pages, respectively.
>
> The name 'available_pages' was picked over 'free_pages' because
> 'free' implies that the pages are unused. But they might not
> be, they just haven't been used by cma_alloc
>
> The number of available pages is tracked regardless of
> CONFIG_CMA_SYSFS, allowing for a few minor shortcuts in
> the code, avoiding bitmap operations.
>
> Signed-off-by: Frank van der Linden <fvdl@xxxxxxxxxx>
> ---
>  Documentation/ABI/testing/sysfs-kernel-mm-cma | 13 ++++++++++++
>  mm/cma.c                                      | 18 +++++++++++------
>  mm/cma.h                                      |  1 +
>  mm/cma_debug.c                                |  5 +----
>  mm/cma_sysfs.c                                | 20 +++++++++++++++++++
>  5 files changed, 47 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-cma b/Documentation/ABI/testing/sysfs-kernel-mm-cma
> index dfd755201142..aaf2a5d8b13b 100644
> --- a/Documentation/ABI/testing/sysfs-kernel-mm-cma
> +++ b/Documentation/ABI/testing/sysfs-kernel-mm-cma
> @@ -29,3 +29,16 @@ Date:                Feb 2024
>  Contact:       Anshuman Khandual <anshuman.khandual@xxxxxxx>
>  Description:
>                 the number of pages CMA API succeeded to release
> +
> +What:          /sys/kernel/mm/cma/<cma-heap-name>/total_pages
> +Date:          Jun 2024
> +Contact:       Frank van der Linden <fvdl@xxxxxxxxxx>
> +Description:
> +               The size of the CMA area in pages.
> +
> +What:          /sys/kernel/mm/cma/<cma-heap-name>/available_pages
> +Date:          Jun 2024
> +Contact:       Frank van der Linden <fvdl@xxxxxxxxxx>
> +Description:
> +               The number of pages in the CMA area that are still
> +               available for CMA allocation.
> diff --git a/mm/cma.c b/mm/cma.c
> index 3e9724716bad..727e8c04d53a 100644
> --- a/mm/cma.c
> +++ b/mm/cma.c
> @@ -86,6 +86,7 @@ static void cma_clear_bitmap(struct cma *cma, unsigned long pfn,
>
>         spin_lock_irqsave(&cma->lock, flags);
>         bitmap_clear(cma->bitmap, bitmap_no, bitmap_count);
> +       cma->available_count += count;
>         spin_unlock_irqrestore(&cma->lock, flags);
>  }
>
> @@ -133,7 +134,7 @@ static void __init cma_activate_area(struct cma *cma)
>                         free_reserved_page(pfn_to_page(pfn));
>         }
>         totalcma_pages -= cma->count;
> -       cma->count = 0;
> +       cma->available_count = cma->count = 0;
>         pr_err("CMA area %s could not be activated\n", cma->name);
>         return;
>  }
> @@ -198,7 +199,7 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
>                 snprintf(cma->name, CMA_MAX_NAME,  "cma%d\n", cma_area_count);
>
>         cma->base_pfn = PFN_DOWN(base);
> -       cma->count = size >> PAGE_SHIFT;
> +       cma->available_count = cma->count = size >> PAGE_SHIFT;
>         cma->order_per_bit = order_per_bit;
>         *res_cma = cma;
>         cma_area_count++;
> @@ -382,7 +383,7 @@ static void cma_debug_show_areas(struct cma *cma)
>  {
>         unsigned long next_zero_bit, next_set_bit, nr_zero;
>         unsigned long start = 0;
> -       unsigned long nr_part, nr_total = 0;
> +       unsigned long nr_part;
>         unsigned long nbits = cma_bitmap_maxno(cma);
>
>         spin_lock_irq(&cma->lock);
> @@ -394,12 +395,12 @@ static void cma_debug_show_areas(struct cma *cma)
>                 next_set_bit = find_next_bit(cma->bitmap, nbits, next_zero_bit);
>                 nr_zero = next_set_bit - next_zero_bit;
>                 nr_part = nr_zero << cma->order_per_bit;
> -               pr_cont("%s%lu@%lu", nr_total ? "+" : "", nr_part,
> +               pr_cont("%s%lu@%lu", start ? "+" : "", nr_part,
>                         next_zero_bit);
> -               nr_total += nr_part;
>                 start = next_zero_bit + nr_zero;
>         }
> -       pr_cont("=> %lu free of %lu total pages\n", nr_total, cma->count);
> +       pr_cont("=> %lu free of %lu total pages\n", cma->available_count,
> +                       cma->count);
>         spin_unlock_irq(&cma->lock);
>  }
>
> @@ -446,6 +447,10 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
>
>         for (;;) {
>                 spin_lock_irq(&cma->lock);
> +               if (count > cma->available_count) {
> +                       spin_unlock_irq(&cma->lock);
> +                       break;
> +               }
>                 bitmap_no = bitmap_find_next_zero_area_off(cma->bitmap,
>                                 bitmap_maxno, start, bitmap_count, mask,
>                                 offset);
> @@ -454,6 +459,7 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
>                         break;
>                 }
>                 bitmap_set(cma->bitmap, bitmap_no, bitmap_count);
> +               cma->available_count -= count;
>                 /*
>                  * It's safe to drop the lock here. We've marked this region for
>                  * our exclusive use. If the migration fails we will take the
> diff --git a/mm/cma.h b/mm/cma.h
> index ad61cc6dd439..d111f3d51868 100644
> --- a/mm/cma.h
> +++ b/mm/cma.h
> @@ -13,6 +13,7 @@ struct cma_kobject {
>  struct cma {
>         unsigned long   base_pfn;
>         unsigned long   count;
> +       unsigned long   available_count;
>         unsigned long   *bitmap;
>         unsigned int order_per_bit; /* Order of pages represented by one bit */
>         spinlock_t      lock;
> diff --git a/mm/cma_debug.c b/mm/cma_debug.c
> index 602fff89b15f..89236f22230a 100644
> --- a/mm/cma_debug.c
> +++ b/mm/cma_debug.c
> @@ -34,13 +34,10 @@ DEFINE_DEBUGFS_ATTRIBUTE(cma_debugfs_fops, cma_debugfs_get, NULL, "%llu\n");
>  static int cma_used_get(void *data, u64 *val)
>  {
>         struct cma *cma = data;
> -       unsigned long used;
>
>         spin_lock_irq(&cma->lock);
> -       /* pages counter is smaller than sizeof(int) */
> -       used = bitmap_weight(cma->bitmap, (int)cma_bitmap_maxno(cma));
> +       *val = cma->count - cma->available_count;
>         spin_unlock_irq(&cma->lock);
> -       *val = (u64)used << cma->order_per_bit;
>
>         return 0;
>  }
> diff --git a/mm/cma_sysfs.c b/mm/cma_sysfs.c
> index f50db3973171..97acd3e5a6a5 100644
> --- a/mm/cma_sysfs.c
> +++ b/mm/cma_sysfs.c
> @@ -62,6 +62,24 @@ static ssize_t release_pages_success_show(struct kobject *kobj,
>  }
>  CMA_ATTR_RO(release_pages_success);
>
> +static ssize_t total_pages_show(struct kobject *kobj,
> +                                         struct kobj_attribute *attr, char *buf)
> +{
> +       struct cma *cma = cma_from_kobj(kobj);
> +
> +       return sysfs_emit(buf, "%lu\n", cma->count);
> +}
> +CMA_ATTR_RO(total_pages);
> +
> +static ssize_t available_pages_show(struct kobject *kobj,
> +                                         struct kobj_attribute *attr, char *buf)
> +{
> +       struct cma *cma = cma_from_kobj(kobj);
> +
> +       return sysfs_emit(buf, "%lu\n", cma->available_count);
> +}
> +CMA_ATTR_RO(available_pages);
> +
>  static void cma_kobj_release(struct kobject *kobj)
>  {
>         struct cma *cma = cma_from_kobj(kobj);
> @@ -75,6 +93,8 @@ static struct attribute *cma_attrs[] = {
>         &alloc_pages_success_attr.attr,
>         &alloc_pages_fail_attr.attr,
>         &release_pages_success_attr.attr,
> +       &total_pages_attr.attr,
> +       &available_pages_attr.attr,
>         NULL,
>  };
>  ATTRIBUTE_GROUPS(cma);
> --
> 2.45.2.803.g4e1b14247a-goog
>

I realize that this isn't the most exciting patch, but.. any comments? :)

- Frank





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux