* Re: [RFC PATCH v2 0/7] Use pageblock_order for cma and alloc_contig_range alignment.
From: Zi Yan @ 2021-12-10 15:30 UTC (permalink / raw)
To: Eric Ren
Cc: Mel Gorman, David Hildenbrand, linuxppc-dev, linux-kernel,
virtualization, linux-mm, iommu, Robin Murphy, Christoph Hellwig,
Vlastimil Babka, Marek Szyprowski
In-Reply-To: <07f11dfc-f491-3b08-a2cb-3c8f5a8102d3@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4035 bytes --]
On 10 Dec 2021, at 2:30, Eric Ren wrote:
> Hi Zi Yan,
>
> On 2021/12/10 07:04, Zi Yan wrote:
>> From: Zi Yan <ziy@nvidia.com>
>>
>> Hi all,
>>
>> This patchset tries to remove the MAX_ORDER - 1 alignment requirement for CMA
>> and alloc_contig_range(). It prepares for my upcoming changes to make MAX_ORDER
>> adjustable at boot time[1].
>>
>> The MAX_ORDER - 1 alignment requirement comes from that alloc_contig_range()
>> isolates pageblocks to remove free memory from buddy allocator but isolating
>> only a subset of pageblocks within a page spanning across multiple pageblocks
>> causes free page accounting issues. Isolated page might not be put into the
>> right free list, since the code assumes the migratetype of the first pageblock
>> as the whole free page migratetype. This is based on the discussion at [2].
>>
>> To remove the requirement, this patchset:
>> 1. still isolates pageblocks at MAX_ORDER - 1 granularity;
> Then, unplug fails if either pageblock of the MAX_ORDER - 1 page has unmovable page, right?
Right. One of the optimizations mentioned is targeting this by passing the actual
range instead of the MAX_ORDER-1 aligned range, so that has_unmovable_pages()
will not give false positive, minimizing the isolation failure rates.
>
> Thanks,
> Eric
>> 2. but saves the pageblock migratetypes outside the specified range of
>> alloc_contig_range() and restores them after all pages within the range
>> become free after __alloc_contig_migrate_range();
>> 3. splits free pages spanning multiple pageblocks at the beginning and the end
>> of the range and puts the split pages to the right migratetype free lists
>> based on the pageblock migratetypes;
>> 4. returns pages not in the range as it did before this patch.
>>
>> Isolation needs to happen at MAX_ORDER - 1 granularity, because otherwise
>> 1) extra code is needed to detect pages (free, PageHuge, THP, or PageCompound)
>> to make sure all pageblocks belonging to a single page are isolated together
>> and later pageblocks outside the range need to have their migratetypes restored;
>> or 2) extra logic will need to be added during page free time to split a free
>> page with multi-migratetype pageblocks.
>>
>> Two optimizations might come later:
>> 1. only check unmovable pages within the range instead of MAX_ORDER - 1 aligned
>> range during isolation to increase successful rate of alloc_contig_range().
^^^^^^^^^^^^^^
>> 2. make MIGRATE_ISOLATE a separate bit to avoid saving and restoring existing
>> migratetypes before and after isolation respectively.
>>
>> Feel free to give comments and suggestions. Thanks.
>>
>>
>> [1] https://lore.kernel.org/linux-mm/20210805190253.2795604-1-zi.yan@sent.com/
>> [2] https://lore.kernel.org/linux-mm/d19fb078-cb9b-f60f-e310-fdeea1b947d2@redhat.com/
>>
>>
>> Zi Yan (7):
>> mm: page_alloc: avoid merging non-fallbackable pageblocks with others.
>> mm: compaction: handle non-lru compound pages properly in
>> isolate_migratepages_block().
>> mm: migrate: allocate the right size of non hugetlb or THP compound
>> pages.
>> mm: make alloc_contig_range work at pageblock granularity
>> mm: cma: use pageblock_order as the single alignment
>> drivers: virtio_mem: use pageblock size as the minimum virtio_mem
>> size.
>> arch: powerpc: adjust fadump alignment to be pageblock aligned.
>>
>> arch/powerpc/include/asm/fadump-internal.h | 4 +-
>> drivers/virtio/virtio_mem.c | 6 +-
>> include/linux/mmzone.h | 11 +-
>> kernel/dma/contiguous.c | 2 +-
>> mm/cma.c | 6 +-
>> mm/compaction.c | 10 +-
>> mm/migrate.c | 8 +-
>> mm/page_alloc.c | 203 +++++++++++++++++----
>> 8 files changed, 196 insertions(+), 54 deletions(-)
>>
--
Best Regards,
Yan, Zi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 854 bytes --]
^ permalink raw reply
* Re: [RFC PATCH v2 1/7] mm: page_alloc: avoid merging non-fallbackable pageblocks with others.
From: Zi Yan @ 2021-12-10 15:39 UTC (permalink / raw)
To: Eric Ren
Cc: Mel Gorman, David Hildenbrand, linuxppc-dev, linux-kernel,
virtualization, linux-mm, iommu, Robin Murphy, Christoph Hellwig,
Vlastimil Babka, Marek Szyprowski
In-Reply-To: <2926b360-5204-45f5-e1a0-e260214f8dbf@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5820 bytes --]
Hi Eric,
Thanks for looking into my patch.
On 10 Dec 2021, at 2:43, Eric Ren wrote:
> Hi,
>
> On 2021/12/10 07:04, Zi Yan wrote:
>> From: Zi Yan <ziy@nvidia.com>
>>
>> This is done in addition to MIGRATE_ISOLATE pageblock merge avoidance.
>> It prepares for the upcoming removal of the MAX_ORDER-1 alignment
>> requirement for CMA and alloc_contig_range().
>>
>> MIGRARTE_HIGHATOMIC should not merge with other migratetypes like
>> MIGRATE_ISOLATE and MIGRARTE_CMA[1], so this commit prevents that too.
>> Also add MIGRARTE_HIGHATOMIC to fallbacks array for completeness.
>>
>> [1] https://lore.kernel.org/linux-mm/20211130100853.GP3366@techsingularity.net/
>>
>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>> ---
>> include/linux/mmzone.h | 6 ++++++
>> mm/page_alloc.c | 28 ++++++++++++++++++----------
>> 2 files changed, 24 insertions(+), 10 deletions(-)
>>
>> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
>> index 58e744b78c2c..b925431b0123 100644
>> --- a/include/linux/mmzone.h
>> +++ b/include/linux/mmzone.h
>> @@ -83,6 +83,12 @@ static inline bool is_migrate_movable(int mt)
>> return is_migrate_cma(mt) || mt == MIGRATE_MOVABLE;
>> }
>> +/* See fallbacks[MIGRATE_TYPES][3] in page_alloc.c */
>> +static inline bool migratetype_has_fallback(int mt)
>> +{
>> + return mt < MIGRATE_PCPTYPES;
>> +}
>> +
>
> I would suggest spliting the patch into 2 parts. The first part: no functioning change, just introduce migratetype_has_fallback()
> and replace where it applys to.
OK. I can do that.
>
>> #define for_each_migratetype_order(order, type) \
>> for (order = 0; order < MAX_ORDER; order++) \
>> for (type = 0; type < MIGRATE_TYPES; type++)
>> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
>> index edfd6c81af82..107a5f186d3b 100644
>> --- a/mm/page_alloc.c
>> +++ b/mm/page_alloc.c
>> @@ -1041,6 +1041,12 @@ buddy_merge_likely(unsigned long pfn, unsigned long buddy_pfn,
>> return page_is_buddy(higher_page, higher_buddy, order + 1);
>> }
>> +static inline bool has_non_fallback_pageblock(struct zone *zone)
>> +{
>> + return has_isolate_pageblock(zone) || zone_cma_pages(zone) != 0 ||
>> + zone->nr_reserved_highatomic != 0;
>
> Make zone->nr_reserved_highatomic != 0 a helper as zone_cma_pages()?
I am not sure. We have zone_cma_pages() because when CMA is not enabled, 0 can be
simply returned. But MIGRATE_HIGHATOMIC is always present, then an helper function
is not that useful.
>> +}
>> +
>> /*
>> * Freeing function for a buddy system allocator.
>> *
>> @@ -1116,14 +1122,15 @@ static inline void __free_one_page(struct page *page,
>> }
>> if (order < MAX_ORDER - 1) {
>> /* If we are here, it means order is >= pageblock_order.
>> - * We want to prevent merge between freepages on isolate
>> - * pageblock and normal pageblock. Without this, pageblock
>> - * isolation could cause incorrect freepage or CMA accounting.
>> + * We want to prevent merge between freepages on pageblock
>> + * without fallbacks and normal pageblock. Without this,
>> + * pageblock isolation could cause incorrect freepage or CMA
>> + * accounting or HIGHATOMIC accounting.
>> *
>> * We don't want to hit this code for the more frequent
>> * low-order merging.
>> */
>> - if (unlikely(has_isolate_pageblock(zone))) {
>> + if (unlikely(has_non_fallback_pageblock(zone))) {
> I'm not familiar with the code details, just wondering if this change would has side effects on cma
> pageblock merging as it the condition stronger?
No impact on cma pageblock merging, AFAICT.
>
> Thanks,
> Eric
>> int buddy_mt;
>> buddy_pfn = __find_buddy_pfn(pfn, order);
>> @@ -1131,8 +1138,8 @@ static inline void __free_one_page(struct page *page,
>> buddy_mt = get_pageblock_migratetype(buddy);
>> if (migratetype != buddy_mt
>> - && (is_migrate_isolate(migratetype) ||
>> - is_migrate_isolate(buddy_mt)))
>> + && (!migratetype_has_fallback(migratetype) ||
>> + !migratetype_has_fallback(buddy_mt)))
>> goto done_merging;
>> }
>> max_order = order + 1;
>> @@ -2483,6 +2490,7 @@ static int fallbacks[MIGRATE_TYPES][3] = {
>> [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_TYPES },
>> [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_TYPES },
>> [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_TYPES },
>> + [MIGRATE_HIGHATOMIC] = { MIGRATE_TYPES }, /* Never used */
>> #ifdef CONFIG_CMA
>> [MIGRATE_CMA] = { MIGRATE_TYPES }, /* Never used */
>> #endif
>> @@ -2794,8 +2802,8 @@ static void reserve_highatomic_pageblock(struct page *page, struct zone *zone,
>> /* Yoink! */
>> mt = get_pageblock_migratetype(page);
>> - if (!is_migrate_highatomic(mt) && !is_migrate_isolate(mt)
>> - && !is_migrate_cma(mt)) {
>> + /* Only reserve normal pageblock */
>> + if (migratetype_has_fallback(mt)) {
>> zone->nr_reserved_highatomic += pageblock_nr_pages;
>> set_pageblock_migratetype(page, MIGRATE_HIGHATOMIC);
>> move_freepages_block(zone, page, MIGRATE_HIGHATOMIC, NULL);
>> @@ -3544,8 +3552,8 @@ int __isolate_free_page(struct page *page, unsigned int order)
>> struct page *endpage = page + (1 << order) - 1;
>> for (; page < endpage; page += pageblock_nr_pages) {
>> int mt = get_pageblock_migratetype(page);
>> - if (!is_migrate_isolate(mt) && !is_migrate_cma(mt)
>> - && !is_migrate_highatomic(mt))
>> + /* Only change normal pageblock */
>> + if (migratetype_has_fallback(mt))
>> set_pageblock_migratetype(page,
>> MIGRATE_MOVABLE);
>> }
--
Best Regards,
Yan, Zi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 854 bytes --]
^ permalink raw reply
* Re: [RFC PATCH v2 3/7] mm: migrate: allocate the right size of non hugetlb or THP compound pages.
From: Zi Yan @ 2021-12-10 15:48 UTC (permalink / raw)
To: Eric Ren
Cc: Mel Gorman, David Hildenbrand, linuxppc-dev, linux-kernel,
virtualization, linux-mm, iommu, Robin Murphy, Christoph Hellwig,
Vlastimil Babka, Marek Szyprowski
In-Reply-To: <84807a03-f7d1-83cb-16df-bacc58de4529@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2669 bytes --]
On 10 Dec 2021, at 2:53, Eric Ren wrote:
> Hi,
>
> On 2021/12/10 07:04, Zi Yan wrote:
>> From: Zi Yan <ziy@nvidia.com>
>>
>> alloc_migration_target() is used by alloc_contig_range() and non-LRU
>> movable compound pages can be migrated. Current code does not allocate the
>> right page size for such pages. Check THP precisely using
>> is_transparent_huge() and add allocation support for non-LRU compound
>> pages.
> Could you elaborate on why the current code doesn't get the right size? how this patch fixes it.
The current code only check PageHuge() and PageTransHuge(). Non-LRU compound
pages will be regarded as PageTransHuge() and an order-9 page is always allocated
regardless of the actual page order. This patch makes the exact check for
THPs using is_transparent_huge() instead of PageTransHuge() and checks PageCompound()
after PageHuge() and is_transparent_huge() for non-LRU compound pages.
>
> The description sounds like it's an existing bug, if so, the patch subject should be changed to
> "Fixes ..."?
I have not seen any related bug report.
>
>>
>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>> ---
>> mm/migrate.c | 8 ++++++--
>> 1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/mm/migrate.c b/mm/migrate.c
>> index d487a399253b..2ce3c771b1de 100644
>> --- a/mm/migrate.c
>> +++ b/mm/migrate.c
>> @@ -1563,7 +1563,7 @@ struct page *alloc_migration_target(struct page *page, unsigned long private)
>> return alloc_huge_page_nodemask(h, nid, mtc->nmask, gfp_mask);
>> }
>> - if (PageTransHuge(page)) {
>> + if (is_transparent_hugepage(page)) {
>> /*
>> * clear __GFP_RECLAIM to make the migration callback
>> * consistent with regular THP allocations.
>> @@ -1572,13 +1572,17 @@ struct page *alloc_migration_target(struct page *page, unsigned long private)
> if (PageTransHuge(page)) { // just give more code context
> ...
>> gfp_mask |= GFP_TRANSHUGE;
>> order = HPAGE_PMD_ORDER;
> order assigned here
>> }
>> + if (PageCompound(page)) {
>> + gfp_mask |= __GFP_COMP;
>> + order = compound_order(page);
> re-assinged again as THP is a compound page?
Ah, you are right. Will use else if instead. Thanks.
> Thanks,
> Eric
>> + }
>> zidx = zone_idx(page_zone(page));
>> if (is_highmem_idx(zidx) || zidx == ZONE_MOVABLE)
>> gfp_mask |= __GFP_HIGHMEM;
>> new_page = __alloc_pages(gfp_mask, order, nid, mtc->nmask);
>> - if (new_page && PageTransHuge(new_page))
>> + if (new_page && is_transparent_hugepage(page))
>> prep_transhuge_page(new_page);
>> return new_page;
--
Best Regards,
Yan, Zi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 854 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] kdump: vmcore: move copy_to() from vmcore.c to uaccess.h
From: Andrew Morton @ 2021-12-10 16:59 UTC (permalink / raw)
To: Tiezhu Yang
Cc: linux-ia64, Baoquan He, linux-sh, linuxppc-dev, x86, kexec,
linux-mips, linux-kernel, Vivek Goyal, linux-fsdevel, linux-riscv,
Dave Young, linux-arm-kernel
In-Reply-To: <1639143361-17773-2-git-send-email-yangtiezhu@loongson.cn>
On Fri, 10 Dec 2021 21:36:00 +0800 Tiezhu Yang <yangtiezhu@loongson.cn> wrote:
> In arch/*/kernel/crash_dump*.c, there exist similar code about
> copy_oldmem_page(), move copy_to() from vmcore.c to uaccess.h,
> and then we can use copy_to() to simplify the related code.
>
> ...
>
> --- a/fs/proc/vmcore.c
> +++ b/fs/proc/vmcore.c
> @@ -238,20 +238,6 @@ copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
> return copy_oldmem_page(pfn, buf, csize, offset, userbuf);
> }
>
> -/*
> - * Copy to either kernel or user space
> - */
> -static int copy_to(void *target, void *src, size_t size, int userbuf)
> -{
> - if (userbuf) {
> - if (copy_to_user((char __user *) target, src, size))
> - return -EFAULT;
> - } else {
> - memcpy(target, src, size);
> - }
> - return 0;
> -}
> -
> #ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP
> static int vmcoredd_copy_dumps(void *dst, u64 start, size_t size, int userbuf)
> {
> diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
> index ac03940..4a6c3e4 100644
> --- a/include/linux/uaccess.h
> +++ b/include/linux/uaccess.h
> @@ -201,6 +201,20 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
> return n;
> }
>
> +/*
> + * Copy to either kernel or user space
> + */
> +static inline int copy_to(void *target, void *src, size_t size, int userbuf)
> +{
> + if (userbuf) {
> + if (copy_to_user((char __user *) target, src, size))
> + return -EFAULT;
> + } else {
> + memcpy(target, src, size);
> + }
> + return 0;
> +}
> +
Ordinarily I'd say "this is too large to be inlined". But the function
has only a single callsite per architecture so inlining it won't cause
bloat at present.
But hopefully copy_to() will get additional callers in the future, in
which case it shouldn't be inlined. So I'm thinking it would be best
to start out with this as a regular non-inlined function, in
lib/usercopy.c.
Also, copy_to() is a very poor name for a globally-visible helper
function. Better would be copy_to_user_or_kernel(), although that's
perhaps a bit long.
And the `userbuf' arg should have type bool, yes?
^ permalink raw reply
* Re: [PATCH v4 06/10] powerpc/mm: Use generic_get_unmapped_area() and call it from arch_get_unmapped_area()
From: Christophe Leroy @ 2021-12-10 17:47 UTC (permalink / raw)
To: Nicholas Piggin, alex@ghiti.fr, Benjamin Herrenschmidt,
Michael Ellerman, Paul Mackerras
Cc: linux-mm@kvack.org, akpm@linux-foundation.org,
linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
In-Reply-To: <1639042828.6q5z2bujam.astroid@bobo.none>
Le 09/12/2021 à 10:50, Nicholas Piggin a écrit :
> Excerpts from Christophe Leroy's message of December 9, 2021 3:18 am:
>> Use the generic version of arch_get_unmapped_area() which
>> is now available at all time instead of its copy
>> radix__arch_get_unmapped_area()
>>
>> Instead of setting mm->get_unmapped_area() to either
>> arch_get_unmapped_area() or generic_get_unmapped_area(),
>> always set it to arch_get_unmapped_area() and call
>> generic_get_unmapped_area() from there when radix is enabled.
>>
>> Do the same with radix__arch_get_unmapped_area_topdown()
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
>> ---
>> arch/powerpc/mm/mmap.c | 127 ++---------------------------------------
>> 1 file changed, 6 insertions(+), 121 deletions(-)
>>
>> diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
>> index 9b0d6e395bc0..46781d0103d1 100644
>> --- a/arch/powerpc/mm/mmap.c
>> +++ b/arch/powerpc/mm/mmap.c
>> @@ -81,115 +81,15 @@ static inline unsigned long mmap_base(unsigned long rnd,
>> }
>>
>> #ifdef HAVE_ARCH_UNMAPPED_AREA
>> -#ifdef CONFIG_PPC_RADIX_MMU
>> -/*
>> - * Same function as generic code used only for radix, because we don't need to overload
>> - * the generic one. But we will have to duplicate, because hash select
>> - * HAVE_ARCH_UNMAPPED_AREA
>> - */
>> -static unsigned long
>> -radix__arch_get_unmapped_area(struct file *filp, unsigned long addr,
>> - unsigned long len, unsigned long pgoff,
>> - unsigned long flags)
>> -{
>> - struct mm_struct *mm = current->mm;
>> - struct vm_area_struct *vma;
>> - int fixed = (flags & MAP_FIXED);
>> - unsigned long high_limit;
>> - struct vm_unmapped_area_info info;
>> -
>> - high_limit = DEFAULT_MAP_WINDOW;
>> - if (addr >= high_limit || (fixed && (addr + len > high_limit)))
>> - high_limit = TASK_SIZE;
>
> Does 64s radix need to define arch_get_mmap_end() to do the above now?
Sure, good point.
Seems like I got hypnotised by the comment "- * Same function as generic
code used only for radix", I didn't catch that little difference.
>
> Otherwise great to consolidate this with core code, nice patch.
>
> Thanks,
> Nick
>
^ permalink raw reply
* Re: [RFC PATCH v2 0/7] Use pageblock_order for cma and alloc_contig_range alignment.
From: David Hildenbrand @ 2021-12-10 18:36 UTC (permalink / raw)
To: Zi Yan, linux-mm
Cc: Mel Gorman, Robin Murphy, linux-kernel, iommu, Eric Ren,
virtualization, linuxppc-dev, Christoph Hellwig, Vlastimil Babka,
Marek Szyprowski
In-Reply-To: <20211209230414.2766515-1-zi.yan@sent.com>
On 10.12.21 00:04, Zi Yan wrote:
> From: Zi Yan <ziy@nvidia.com>
>
> Hi all,
Hi,
thanks for working on that!
>
> This patchset tries to remove the MAX_ORDER - 1 alignment requirement for CMA
> and alloc_contig_range(). It prepares for my upcoming changes to make MAX_ORDER
> adjustable at boot time[1].
>
> The MAX_ORDER - 1 alignment requirement comes from that alloc_contig_range()
> isolates pageblocks to remove free memory from buddy allocator but isolating
> only a subset of pageblocks within a page spanning across multiple pageblocks
> causes free page accounting issues. Isolated page might not be put into the
> right free list, since the code assumes the migratetype of the first pageblock
> as the whole free page migratetype. This is based on the discussion at [2].
>
> To remove the requirement, this patchset:
> 1. still isolates pageblocks at MAX_ORDER - 1 granularity;
> 2. but saves the pageblock migratetypes outside the specified range of
> alloc_contig_range() and restores them after all pages within the range
> become free after __alloc_contig_migrate_range();
> 3. splits free pages spanning multiple pageblocks at the beginning and the end
> of the range and puts the split pages to the right migratetype free lists
> based on the pageblock migratetypes;
> 4. returns pages not in the range as it did before this patch.
>
> Isolation needs to happen at MAX_ORDER - 1 granularity, because otherwise
> 1) extra code is needed to detect pages (free, PageHuge, THP, or PageCompound)
> to make sure all pageblocks belonging to a single page are isolated together
> and later pageblocks outside the range need to have their migratetypes restored;
> or 2) extra logic will need to be added during page free time to split a free
> page with multi-migratetype pageblocks.
>
> Two optimizations might come later:
> 1. only check unmovable pages within the range instead of MAX_ORDER - 1 aligned
> range during isolation to increase successful rate of alloc_contig_range().
The issue with virtio-mem is that we'll need that as soon as we change
the granularity to pageblocks, because otherwise, you can heavily
degrade unplug reliably in sane setups:
Previous:
* Try unplug free 4M range (2 pageblocks): succeeds
Now:
* Try unplug 2M range (first pageblock): succeeds.
* Try unplug next 2M range (second pageblock): fails because first
contains unmovable allcoations.
--
Thanks,
David / dhildenb
^ permalink raw reply
* Re: [RFC PATCH v2 0/7] Use pageblock_order for cma and alloc_contig_range alignment.
From: Zi Yan @ 2021-12-10 20:17 UTC (permalink / raw)
To: David Hildenbrand
Cc: Mel Gorman, linuxppc-dev, linux-kernel, virtualization, linux-mm,
iommu, Eric Ren, Robin Murphy, Christoph Hellwig, Vlastimil Babka,
Marek Szyprowski
In-Reply-To: <19404189-3bee-c02a-a596-2e5564e0f8f5@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2603 bytes --]
On 10 Dec 2021, at 13:36, David Hildenbrand wrote:
> On 10.12.21 00:04, Zi Yan wrote:
>> From: Zi Yan <ziy@nvidia.com>
>>
>> Hi all,
>
> Hi,
>
> thanks for working on that!
>
>>
>> This patchset tries to remove the MAX_ORDER - 1 alignment requirement for CMA
>> and alloc_contig_range(). It prepares for my upcoming changes to make MAX_ORDER
>> adjustable at boot time[1].
>>
>> The MAX_ORDER - 1 alignment requirement comes from that alloc_contig_range()
>> isolates pageblocks to remove free memory from buddy allocator but isolating
>> only a subset of pageblocks within a page spanning across multiple pageblocks
>> causes free page accounting issues. Isolated page might not be put into the
>> right free list, since the code assumes the migratetype of the first pageblock
>> as the whole free page migratetype. This is based on the discussion at [2].
>>
>> To remove the requirement, this patchset:
>> 1. still isolates pageblocks at MAX_ORDER - 1 granularity;
>> 2. but saves the pageblock migratetypes outside the specified range of
>> alloc_contig_range() and restores them after all pages within the range
>> become free after __alloc_contig_migrate_range();
>> 3. splits free pages spanning multiple pageblocks at the beginning and the end
>> of the range and puts the split pages to the right migratetype free lists
>> based on the pageblock migratetypes;
>> 4. returns pages not in the range as it did before this patch.
>>
>> Isolation needs to happen at MAX_ORDER - 1 granularity, because otherwise
>> 1) extra code is needed to detect pages (free, PageHuge, THP, or PageCompound)
>> to make sure all pageblocks belonging to a single page are isolated together
>> and later pageblocks outside the range need to have their migratetypes restored;
>> or 2) extra logic will need to be added during page free time to split a free
>> page with multi-migratetype pageblocks.
>>
>> Two optimizations might come later:
>> 1. only check unmovable pages within the range instead of MAX_ORDER - 1 aligned
>> range during isolation to increase successful rate of alloc_contig_range().
>
> The issue with virtio-mem is that we'll need that as soon as we change
> the granularity to pageblocks, because otherwise, you can heavily
> degrade unplug reliably in sane setups:
>
> Previous:
> * Try unplug free 4M range (2 pageblocks): succeeds
>
> Now:
> * Try unplug 2M range (first pageblock): succeeds.
> * Try unplug next 2M range (second pageblock): fails because first
> contains unmovable allcoations.
>
OK. Make sense. I will add it in the next version.
--
Best Regards,
Yan, Zi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 854 bytes --]
^ permalink raw reply
* Re: [PATCH] powerpc: Add set_memory_{p/np}() and remove set_memory_attr()
From: Maxime Bizon @ 2021-12-10 20:37 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Paul Mackerras, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <715cc0c2f801ef3b39b91233be44d328a91c30bc.1639123757.git.christophe.leroy@csgroup.eu>
On Friday 10 Dec 2021 à 08:09:42 (+0000), Christophe Leroy wrote:
Tested-by: Maxime Bizon <mbizon@freebox.fr>
--
Maxime
^ permalink raw reply
* Re: [PATCH 0/7] Cleanup after removal of configs
From: Alexandre Ghiti @ 2021-12-10 20:38 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Rich Felker, open list:DOCUMENTATION, Matti Vaittinen,
open list:BROADCOM NVRAM DRIVER, David Howells, Paul Mackerras,
Lee Jones, linux-cifs, Yoshinori Sato, Jonathan Corbet,
Linux-sh list, Russell King, linux-cachefs, Linux ARM,
Lukas Bulwahn, Guenter Roeck, Wim Van Sebroeck, Kalle Valo,
Thomas Bogendoerfer, Greg Kroah-Hartman, samba-technical,
Linux Kernel Mailing List, Ronnie Sahlberg, Steve French,
Luis Chamberlain, Jeff Layton, linuxppc-dev, linux-power
In-Reply-To: <CAK8P3a2AnLJgGNBFvjUQqXd-Az9vjgE7yJQXGDwCav5E0btSsg@mail.gmail.com>
On Fri, Nov 5, 2021 at 4:56 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Fri, Nov 5, 2021 at 4:43 PM Alexandre Ghiti
> <alexandre.ghiti@canonical.com> wrote:
> >
> > While bumping from 5.13 to 5.15, I found that a few deleted configs had
> > left some pieces here and there: this patchset cleans that.
> >
> > Alexandre Ghiti (7):
> > Documentation, arch: Remove leftovers from fscache/cachefiles
> > histograms
> > Documentation, arch: Remove leftovers from raw device
> > Documentation, arch: Remove leftovers from CIFS_WEAK_PW_HASH
> > arch: Remove leftovers from mandatory file locking
> > Documentation, arch, fs: Remove leftovers from fscache object list
> > include: mfd: Remove leftovers from bd70528 watchdog
> > arch: Remove leftovers from prism54 wireless driver
>
> Looks all good to me, thanks a lot for the cleanup!
>
> For arch/arm/configs:
>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
>
> assuming this goes through someone else's tree. Let me know if you need me
> to pick up the patches in the asm-generic tree for cross-architecture work.
Arnd, do you mind taking the whole series except patch 6 ("include:
mfd: Remove leftovers from bd70528 watchdog") as this will be handled
separately. I can ask Jonathan for the doc patches if needed.
Thanks,
Alex
>
> Arnd
^ permalink raw reply
* [patch V3 03/35] x86/apic/msi: Use PCI device MSI property
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
instead of fiddling with MSI descriptors.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
V3: Use pci_dev->msix_enabled - Jason
---
arch/x86/kernel/apic/msi.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -160,11 +160,8 @@ static struct irq_chip pci_msi_controlle
int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
msi_alloc_info_t *arg)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct msi_desc *desc = first_pci_msi_entry(pdev);
-
init_irq_alloc_info(arg, NULL);
- if (desc->pci.msi_attrib.is_msix) {
+ if (to_pci_dev(dev)->msix_enabled) {
arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSIX;
} else {
arg->type = X86_IRQ_ALLOC_TYPE_PCI_MSI;
^ permalink raw reply
* [patch V3 01/35] PCI/MSI: Set pci_dev::msi[x]_enabled early
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
There are quite some places which retrieve the first MSI descriptor to
evaluate whether the setup is for MSI or MSI-X. That's required because
pci_dev::msi[x]_enabled is only set when the setup completed successfully.
There is no real reason why msi[x]_enabled can't be set at the beginning of
the setup sequence and cleared in case of a failure.
Implement that so the MSI descriptor evaluations can be converted to simple
property queries.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
V3: New patch
---
drivers/pci/msi/msi.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -421,11 +421,18 @@ static int msi_capability_init(struct pc
struct msi_desc *entry;
int ret;
- pci_msi_set_enable(dev, 0); /* Disable MSI during set up */
+ /*
+ * Disable MSI during setup in the hardware, but mark it enabled
+ * so that setup code can evaluate it.
+ */
+ pci_msi_set_enable(dev, 0);
+ dev->msi_enabled = 1;
entry = msi_setup_entry(dev, nvec, affd);
- if (!entry)
- return -ENOMEM;
+ if (!entry) {
+ ret = -ENOMEM;
+ goto fail;
+ }
/* All MSIs are unmasked by default; mask them all */
pci_msi_mask(entry, msi_multi_mask(entry));
@@ -452,7 +459,6 @@ static int msi_capability_init(struct pc
/* Set MSI enabled bits */
pci_intx_for_msi(dev, 0);
pci_msi_set_enable(dev, 1);
- dev->msi_enabled = 1;
pcibios_free_irq(dev);
dev->irq = entry->irq;
@@ -461,6 +467,8 @@ static int msi_capability_init(struct pc
err:
pci_msi_unmask(entry, msi_multi_mask(entry));
free_msi_irqs(dev);
+fail:
+ dev->msi_enabled = 0;
return ret;
}
@@ -589,6 +597,9 @@ static int msix_capability_init(struct p
pci_msix_clear_and_set_ctrl(dev, 0, PCI_MSIX_FLAGS_MASKALL |
PCI_MSIX_FLAGS_ENABLE);
+ /* Mark it enabled so setup functions can query it */
+ dev->msix_enabled = 1;
+
pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
/* Request & Map MSI-X table region */
tsize = msix_table_size(control);
@@ -626,9 +637,8 @@ static int msix_capability_init(struct p
dev->msi_irq_groups = groups;
- /* Set MSI-X enabled bits and unmask the function */
+ /* Disable INTX and unmask MSI-X */
pci_intx_for_msi(dev, 0);
- dev->msix_enabled = 1;
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
pcibios_free_irq(dev);
@@ -638,6 +648,7 @@ static int msix_capability_init(struct p
free_msi_irqs(dev);
out_disable:
+ dev->msix_enabled = 0;
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
return ret;
^ permalink raw reply
* [patch V3 02/35] x86/pci/XEN: Use PCI device property
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
instead of fiddling with MSI descriptors.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Juergen Gross <jgross@suse.com>
Cc: xen-devel@lists.xenproject.org
---
V3: Use pci_dev->msix_enabled.
---
arch/x86/pci/xen.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -399,9 +399,7 @@ static void xen_teardown_msi_irqs(struct
static void xen_pv_teardown_msi_irqs(struct pci_dev *dev)
{
- struct msi_desc *msidesc = first_pci_msi_entry(dev);
-
- if (msidesc->pci.msi_attrib.is_msix)
+ if (dev->msix_enabled)
xen_pci_frontend_disable_msix(dev);
else
xen_pci_frontend_disable_msi(dev);
@@ -417,10 +415,7 @@ static int xen_msi_domain_alloc_irqs(str
if (WARN_ON_ONCE(!dev_is_pci(dev)))
return -EINVAL;
- if (first_msi_entry(dev)->pci.msi_attrib.is_msix)
- type = PCI_CAP_ID_MSIX;
- else
- type = PCI_CAP_ID_MSI;
+ type = to_pci_dev(dev)->msix_enabled ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
return xen_msi_ops.setup_msi_irqs(to_pci_dev(dev), nvec, type);
}
^ permalink raw reply
* [patch V3 00/35] genirq/msi, PCI/MSI: Spring cleaning - Part 2
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
This is the second part of [PCI]MSI refactoring which aims to provide the
ability of expanding MSI-X vectors after enabling MSI-X.
This is based on the first part of this work which can be found here:
https://lore.kernel.org/r/20211206210147.872865823@linutronix.de
and has been applied to:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/msi
This second part has the following important changes:
1) Cleanup of the MSI related data in struct device
struct device contains at the moment various MSI related parts. Some
of them (the irq domain pointer) cannot be moved out, but the rest
can be allocated on first use. This is in preparation of adding more
per device MSI data later on.
2) Consolidation of sysfs handling
As a first step this moves the sysfs pointer from struct msi_desc
into the new per device MSI data structure where it belongs.
Later changes will cleanup this code further, but that's not possible
at this point.
3) Use PCI device properties instead of looking up MSI descriptors and
analysing their data.
4) Provide a function to retrieve the Linux interrupt number for a given
MSI index similar to pci_irq_vector() and cleanup all open coded
variants.
It's also available from git:
git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v3-part-2
Part 3 of this effort is available on top
git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git msi-v3-part-3
Part 3 is not going to be reposted as there is no change vs. V2.
V2 of part 2 can be found here:
https://lore.kernel.org/r/20211206210307.625116253@linutronix.de
Changes versus V2:
- Use PCI device properties instead of creating a new set - Jason
- Picked up Reviewed/Tested/Acked-by tags as appropriate
Thanks,
tglx
---
arch/powerpc/platforms/cell/axon_msi.c | 5
arch/powerpc/platforms/pseries/msi.c | 38 +---
arch/x86/kernel/apic/msi.c | 5
arch/x86/pci/xen.c | 11 -
drivers/base/platform-msi.c | 152 ++++++++-----------
drivers/bus/fsl-mc/dprc-driver.c | 8 -
drivers/bus/fsl-mc/fsl-mc-allocator.c | 9 -
drivers/bus/fsl-mc/fsl-mc-msi.c | 26 +--
drivers/dma/mv_xor_v2.c | 16 --
drivers/dma/qcom/hidma.c | 44 ++---
drivers/dma/ti/k3-udma-private.c | 6
drivers/dma/ti/k3-udma.c | 14 -
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 23 --
drivers/irqchip/irq-mbigen.c | 4
drivers/irqchip/irq-mvebu-icu.c | 12 -
drivers/irqchip/irq-ti-sci-inta.c | 2
drivers/mailbox/bcm-flexrm-mailbox.c | 9 -
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4
drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c | 4
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 5
drivers/pci/msi/irqdomain.c | 20 ++
drivers/pci/msi/legacy.c | 6
drivers/pci/msi/msi.c | 133 ++++++----------
drivers/pci/xen-pcifront.c | 2
drivers/perf/arm_smmuv3_pmu.c | 5
drivers/soc/fsl/dpio/dpio-driver.c | 8 -
drivers/soc/ti/k3-ringacc.c | 6
drivers/soc/ti/ti_sci_inta_msi.c | 22 --
drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c | 4
include/linux/device.h | 25 ++-
include/linux/fsl/mc.h | 4
include/linux/msi.h | 95 ++++--------
include/linux/pci.h | 1
include/linux/soc/ti/ti_sci_inta_msi.h | 1
kernel/irq/msi.c | 158 +++++++++++++++-----
35 files changed, 429 insertions(+), 458 deletions(-)
^ permalink raw reply
* [patch V3 04/35] genirq/msi: Use PCI device property
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
to determine whether this is MSI or MSIX instead of consulting MSI
descriptors.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
V2: Use PCI device property - Jason
---
kernel/irq/msi.c | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -77,21 +77,8 @@ EXPORT_SYMBOL_GPL(get_cached_msi_msg);
static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct msi_desc *entry;
- bool is_msix = false;
- unsigned long irq;
- int retval;
-
- retval = kstrtoul(attr->attr.name, 10, &irq);
- if (retval)
- return retval;
-
- entry = irq_get_msi_desc(irq);
- if (!entry)
- return -ENODEV;
-
- if (dev_is_pci(dev))
- is_msix = entry->pci.msi_attrib.is_msix;
+ /* MSI vs. MSIX is per device not per interrupt */
+ bool is_msix = dev_is_pci(dev) ? to_pci_dev(dev)->msix_enabled : false;
return sysfs_emit(buf, "%s\n", is_msix ? "msix" : "msi");
}
^ permalink raw reply
* [patch V3 05/35] powerpc/cell/axon_msi: Use PCI device property
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
instead of fiddling with MSI descriptors.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: linuxppc-dev@lists.ozlabs.org
---
V3: Use pci_dev property - Jason
V2: Invoke the function with the correct number of arguments - Andy
---
arch/powerpc/platforms/cell/axon_msi.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -199,7 +199,6 @@ static struct axon_msic *find_msi_transl
static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
{
struct device_node *dn;
- struct msi_desc *entry;
int len;
const u32 *prop;
@@ -209,10 +208,8 @@ static int setup_msi_msg_address(struct
return -ENODEV;
}
- entry = first_pci_msi_entry(dev);
-
for (; dn; dn = of_get_next_parent(dn)) {
- if (entry->pci.msi_attrib.is_64) {
+ if (!dev->no_64bit_msi) {
prop = of_get_property(dn, "msi-address-64", &len);
if (prop)
break;
^ permalink raw reply
* [patch V3 06/35] powerpc/pseries/msi: Use PCI device properties
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
instead of fiddling with MSI descriptors.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
---
V3: Use pci_dev->msix_enabled - Jason
---
arch/powerpc/platforms/pseries/msi.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -448,8 +448,7 @@ static int pseries_msi_ops_prepare(struc
int nvec, msi_alloc_info_t *arg)
{
struct pci_dev *pdev = to_pci_dev(dev);
- struct msi_desc *desc = first_pci_msi_entry(pdev);
- int type = desc->pci.msi_attrib.is_msix ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
+ int type = pdev->msix_enabled ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
return rtas_prepare_msi_irqs(pdev, nvec, type, arg);
}
^ permalink raw reply
* [patch V3 07/35] device: Move MSI related data into a struct
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
The only unconditional part of MSI data in struct device is the irqdomain
pointer. Everything else can be allocated on demand. Create a data
structure and move the irqdomain pointer into it. The other MSI specific
parts are going to be removed from struct device in later steps.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/base/platform-msi.c | 12 ++++++------
drivers/dma/ti/k3-udma.c | 4 ++--
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +-
drivers/irqchip/irq-mvebu-icu.c | 6 +++---
drivers/soc/ti/k3-ringacc.c | 4 ++--
drivers/soc/ti/ti_sci_inta_msi.c | 2 +-
include/linux/device.h | 20 ++++++++++++++------
7 files changed, 29 insertions(+), 21 deletions(-)
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -210,10 +210,10 @@ platform_msi_alloc_priv_data(struct devi
* accordingly (which would impact the max number of MSI
* capable devices).
*/
- if (!dev->msi_domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
+ if (!dev->msi.domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS)
return ERR_PTR(-EINVAL);
- if (dev->msi_domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
+ if (dev->msi.domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) {
dev_err(dev, "Incompatible msi_domain, giving up\n");
return ERR_PTR(-EINVAL);
}
@@ -269,7 +269,7 @@ int platform_msi_domain_alloc_irqs(struc
if (err)
goto out_free_priv_data;
- err = msi_domain_alloc_irqs(dev->msi_domain, dev, nvec);
+ err = msi_domain_alloc_irqs(dev->msi.domain, dev, nvec);
if (err)
goto out_free_desc;
@@ -282,7 +282,7 @@ int platform_msi_domain_alloc_irqs(struc
return 0;
out_free_irqs:
- msi_domain_free_irqs(dev->msi_domain, dev);
+ msi_domain_free_irqs(dev->msi.domain, dev);
out_free_desc:
platform_msi_free_descs(dev, 0, nvec);
out_free_priv_data:
@@ -306,7 +306,7 @@ void platform_msi_domain_free_irqs(struc
platform_msi_free_priv_data(desc->platform.msi_priv_data);
}
- msi_domain_free_irqs(dev->msi_domain, dev);
+ msi_domain_free_irqs(dev->msi.domain, dev);
platform_msi_free_descs(dev, 0, MAX_DEV_MSIS);
}
EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs);
@@ -354,7 +354,7 @@ struct irq_domain *
return NULL;
data->host_data = host_data;
- domain = irq_domain_create_hierarchy(dev->msi_domain, 0,
+ domain = irq_domain_create_hierarchy(dev->msi.domain, 0,
is_tree ? 0 : nvec,
dev->fwnode, ops, data);
if (!domain)
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -5279,9 +5279,9 @@ static int udma_probe(struct platform_de
if (IS_ERR(ud->ringacc))
return PTR_ERR(ud->ringacc);
- dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
+ dev->msi.domain = of_msi_get_domain(dev, dev->of_node,
DOMAIN_BUS_TI_SCI_INTA_MSI);
- if (!dev->msi_domain) {
+ if (!dev->msi.domain) {
dev_err(dev, "Failed to get MSI domain\n");
return -EPROBE_DEFER;
}
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3170,7 +3170,7 @@ static void arm_smmu_setup_msis(struct a
if (!(smmu->features & ARM_SMMU_FEAT_MSI))
return;
- if (!dev->msi_domain) {
+ if (!dev->msi.domain) {
dev_info(smmu->dev, "msi_domain absent - falling back to wired irqs\n");
return;
}
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -314,12 +314,12 @@ static int mvebu_icu_subset_probe(struct
msi_data->subset_data = of_device_get_match_data(dev);
}
- dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
+ dev->msi.domain = of_msi_get_domain(dev, dev->of_node,
DOMAIN_BUS_PLATFORM_MSI);
- if (!dev->msi_domain)
+ if (!dev->msi.domain)
return -EPROBE_DEFER;
- msi_parent_dn = irq_domain_get_of_node(dev->msi_domain);
+ msi_parent_dn = irq_domain_get_of_node(dev->msi.domain);
if (!msi_parent_dn)
return -ENODEV;
--- a/drivers/soc/ti/k3-ringacc.c
+++ b/drivers/soc/ti/k3-ringacc.c
@@ -1356,9 +1356,9 @@ static int k3_ringacc_init(struct platfo
struct resource *res;
int ret, i;
- dev->msi_domain = of_msi_get_domain(dev, dev->of_node,
+ dev->msi.domain = of_msi_get_domain(dev, dev->of_node,
DOMAIN_BUS_TI_SCI_INTA_MSI);
- if (!dev->msi_domain) {
+ if (!dev->msi.domain) {
dev_err(dev, "Failed to get MSI domain\n");
return -EPROBE_DEFER;
}
--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -140,7 +140,7 @@ EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain
void ti_sci_inta_msi_domain_free_irqs(struct device *dev)
{
- msi_domain_free_irqs(dev->msi_domain, dev);
+ msi_domain_free_irqs(dev->msi.domain, dev);
ti_sci_inta_msi_free_descs(dev);
}
EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_free_irqs);
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -372,6 +372,16 @@ struct dev_links_info {
};
/**
+ * struct dev_msi_info - Device data related to MSI
+ * @domain: The MSI interrupt domain associated to the device
+ */
+struct dev_msi_info {
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+ struct irq_domain *domain;
+#endif
+};
+
+/**
* struct device - The basic device structure
* @parent: The device's "parent" device, the device to which it is attached.
* In most cases, a parent device is some sort of bus or host
@@ -407,8 +417,8 @@ struct dev_links_info {
* @em_pd: device's energy model performance domain
* @pins: For device pin management.
* See Documentation/driver-api/pin-control.rst for details.
+ * @msi: MSI related data
* @msi_list: Hosts MSI descriptors
- * @msi_domain: The generic MSI domain this device is using.
* @numa_node: NUMA node this device is close to.
* @dma_ops: DMA mapping operations for this device.
* @dma_mask: Dma mask (if dma'ble device).
@@ -500,12 +510,10 @@ struct device {
struct em_perf_domain *em_pd;
#endif
-#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
- struct irq_domain *msi_domain;
-#endif
#ifdef CONFIG_PINCTRL
struct dev_pin_info *pins;
#endif
+ struct dev_msi_info msi;
#ifdef CONFIG_GENERIC_MSI_IRQ
struct list_head msi_list;
#endif
@@ -666,7 +674,7 @@ static inline void set_dev_node(struct d
static inline struct irq_domain *dev_get_msi_domain(const struct device *dev)
{
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
- return dev->msi_domain;
+ return dev->msi.domain;
#else
return NULL;
#endif
@@ -675,7 +683,7 @@ static inline struct irq_domain *dev_get
static inline void dev_set_msi_domain(struct device *dev, struct irq_domain *d)
{
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
- dev->msi_domain = d;
+ dev->msi.domain = d;
#endif
}
^ permalink raw reply
* [patch V3 08/35] device: Add device:: Msi_data pointer and struct msi_device_data
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Create struct msi_device_data and add a pointer of that type to struct
dev_msi_info, which is part of struct device. Provide an allocator function
which can be invoked from the MSI interrupt allocation code pathes.
Add a properties field to the data structure as a first member so the
allocation size is not zero bytes. The field will be uses later on.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
---
include/linux/device.h | 5 +++++
include/linux/msi.h | 18 ++++++++++++++++++
kernel/irq/msi.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+)
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -45,6 +45,7 @@ struct iommu_ops;
struct iommu_group;
struct dev_pin_info;
struct dev_iommu;
+struct msi_device_data;
/**
* struct subsys_interface - interfaces to device functions
@@ -374,11 +375,15 @@ struct dev_links_info {
/**
* struct dev_msi_info - Device data related to MSI
* @domain: The MSI interrupt domain associated to the device
+ * @data: Pointer to MSI device data
*/
struct dev_msi_info {
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
struct irq_domain *domain;
#endif
+#ifdef CONFIG_GENERIC_MSI_IRQ
+ struct msi_device_data *data;
+#endif
};
/**
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -171,6 +171,16 @@ struct msi_desc {
};
};
+/**
+ * msi_device_data - MSI per device data
+ * @properties: MSI properties which are interesting to drivers
+ */
+struct msi_device_data {
+ unsigned long properties;
+};
+
+int msi_setup_device_data(struct device *dev);
+
/* Helpers to hide struct msi_desc implementation details */
#define msi_desc_to_dev(desc) ((desc)->dev)
#define dev_to_msi_list(dev) (&(dev)->msi_list)
@@ -233,10 +243,16 @@ void pci_msi_mask_irq(struct irq_data *d
void pci_msi_unmask_irq(struct irq_data *data);
#ifdef CONFIG_SYSFS
+int msi_device_populate_sysfs(struct device *dev);
+void msi_device_destroy_sysfs(struct device *dev);
+
const struct attribute_group **msi_populate_sysfs(struct device *dev);
void msi_destroy_sysfs(struct device *dev,
const struct attribute_group **msi_irq_groups);
#else
+static inline int msi_device_populate_sysfs(struct device *dev) { return 0; }
+static inline void msi_device_destroy_sysfs(struct device *dev) { }
+
static inline const struct attribute_group **msi_populate_sysfs(struct device *dev)
{
return NULL;
@@ -384,6 +400,8 @@ enum {
MSI_FLAG_MUST_REACTIVATE = (1 << 5),
/* Is level-triggered capable, using two messages */
MSI_FLAG_LEVEL_CAPABLE = (1 << 6),
+ /* Populate sysfs on alloc() and destroy it on free() */
+ MSI_FLAG_DEV_SYSFS = (1 << 7),
};
int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -73,6 +73,38 @@ void get_cached_msi_msg(unsigned int irq
}
EXPORT_SYMBOL_GPL(get_cached_msi_msg);
+static void msi_device_data_release(struct device *dev, void *res)
+{
+ WARN_ON_ONCE(!list_empty(&dev->msi_list));
+ dev->msi.data = NULL;
+}
+
+/**
+ * msi_setup_device_data - Setup MSI device data
+ * @dev: Device for which MSI device data should be set up
+ *
+ * Return: 0 on success, appropriate error code otherwise
+ *
+ * This can be called more than once for @dev. If the MSI device data is
+ * already allocated the call succeeds. The allocated memory is
+ * automatically released when the device is destroyed.
+ */
+int msi_setup_device_data(struct device *dev)
+{
+ struct msi_device_data *md;
+
+ if (dev->msi.data)
+ return 0;
+
+ md = devres_alloc(msi_device_data_release, sizeof(*md), GFP_KERNEL);
+ if (!md)
+ return -ENOMEM;
+
+ dev->msi.data = md;
+ devres_add(dev, md);
+ return 0;
+}
+
#ifdef CONFIG_SYSFS
static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
^ permalink raw reply
* [patch V3 09/35] PCI/MSI: Allocate MSI device data on first use
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Allocate MSI device data on first use, i.e. when a PCI driver invokes one
of the PCI/MSI enablement functions.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/msi/msi.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -900,10 +900,12 @@ static int __pci_enable_msi_range(struct
/* deprecated, don't use */
int pci_enable_msi(struct pci_dev *dev)
{
- int rc = __pci_enable_msi_range(dev, 1, 1, NULL);
- if (rc < 0)
- return rc;
- return 0;
+ int rc = msi_setup_device_data(&dev->dev);
+
+ if (!rc)
+ rc = __pci_enable_msi_range(dev, 1, 1, NULL);
+
+ return rc < 0 ? rc : 0;
}
EXPORT_SYMBOL(pci_enable_msi);
@@ -958,7 +960,11 @@ static int __pci_enable_msix_range(struc
int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
int minvec, int maxvec)
{
- return __pci_enable_msix_range(dev, entries, minvec, maxvec, NULL, 0);
+ int ret = msi_setup_device_data(&dev->dev);
+
+ if (!ret)
+ ret = __pci_enable_msix_range(dev, entries, minvec, maxvec, NULL, 0);
+ return ret;
}
EXPORT_SYMBOL(pci_enable_msix_range);
@@ -985,8 +991,12 @@ int pci_alloc_irq_vectors_affinity(struc
struct irq_affinity *affd)
{
struct irq_affinity msi_default_affd = {0};
+ int ret = msi_setup_device_data(&dev->dev);
int nvecs = -ENOSPC;
+ if (ret)
+ return ret;
+
if (flags & PCI_IRQ_AFFINITY) {
if (!affd)
affd = &msi_default_affd;
^ permalink raw reply
* [patch V3 10/35] platform-msi: Allocate MSI device data on first use
From: Thomas Gleixner @ 2021-12-10 22:18 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Allocate the MSI device data on first invocation of the allocation function
for platform MSI private data.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/base/platform-msi.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -204,6 +204,8 @@ platform_msi_alloc_priv_data(struct devi
irq_write_msi_msg_t write_msi_msg)
{
struct platform_msi_priv_data *datap;
+ int err;
+
/*
* Limit the number of interrupts to 2048 per device. Should we
* need to bump this up, DEV_ID_SHIFT should be adjusted
@@ -218,6 +220,10 @@ platform_msi_alloc_priv_data(struct devi
return ERR_PTR(-EINVAL);
}
+ err = msi_setup_device_data(dev);
+ if (err)
+ return ERR_PTR(err);
+
/* Already had a helping of MSI? Greed... */
if (!list_empty(dev_to_msi_list(dev)))
return ERR_PTR(-EBUSY);
@@ -229,7 +235,7 @@ platform_msi_alloc_priv_data(struct devi
datap->devid = ida_simple_get(&platform_msi_devid_ida,
0, 1 << DEV_ID_SHIFT, GFP_KERNEL);
if (datap->devid < 0) {
- int err = datap->devid;
+ err = datap->devid;
kfree(datap);
return ERR_PTR(err);
}
^ permalink raw reply
* [patch V3 11/35] bus: fsl-mc-msi: Allocate MSI device data on first use
From: Thomas Gleixner @ 2021-12-10 22:19 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Allocate the MSI device data on first invocation of the allocation function.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Cc: Stuart Yoder <stuyoder@gmail.com>
Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com>
---
drivers/bus/fsl-mc/fsl-mc-msi.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -253,6 +253,14 @@ int fsl_mc_msi_domain_alloc_irqs(struct
struct irq_domain *msi_domain;
int error;
+ msi_domain = dev_get_msi_domain(dev);
+ if (!msi_domain)
+ return -EINVAL;
+
+ error = msi_setup_device_data(dev);
+ if (error)
+ return error;
+
if (!list_empty(dev_to_msi_list(dev)))
return -EINVAL;
@@ -260,12 +268,6 @@ int fsl_mc_msi_domain_alloc_irqs(struct
if (error < 0)
return error;
- msi_domain = dev_get_msi_domain(dev);
- if (!msi_domain) {
- error = -EINVAL;
- goto cleanup_msi_descs;
- }
-
/*
* NOTE: Calling this function will trigger the invocation of the
* its_fsl_mc_msi_prepare() callback
^ permalink raw reply
* [patch V3 12/35] soc: ti: ti_sci_inta_msi: Allocate MSI device data on first use
From: Thomas Gleixner @ 2021-12-10 22:19 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Allocate the MSI device data on first invocation of the allocation function.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: Tero Kristo <kristo@kernel.org>
Cc: Santosh Shilimkar <ssantosh@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
---
drivers/soc/ti/ti_sci_inta_msi.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/soc/ti/ti_sci_inta_msi.c
+++ b/drivers/soc/ti/ti_sci_inta_msi.c
@@ -120,6 +120,10 @@ int ti_sci_inta_msi_domain_alloc_irqs(st
if (pdev->id < 0)
return -ENODEV;
+ ret = msi_setup_device_data(dev);
+ if (ret)
+ return ret;
+
nvec = ti_sci_inta_msi_alloc_descs(dev, res);
if (nvec <= 0)
return nvec;
^ permalink raw reply
* [patch V3 13/35] genirq/msi: Provide msi_device_populate/destroy_sysfs()
From: Thomas Gleixner @ 2021-12-10 22:19 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Add new allocation functions which can be activated by domain info
flags. They store the groups pointer in struct msi_device_data.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
---
include/linux/msi.h | 4 ++++
kernel/irq/msi.c | 42 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 44 insertions(+), 2 deletions(-)
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -56,6 +56,8 @@ struct irq_data;
struct msi_desc;
struct pci_dev;
struct platform_msi_priv_data;
+struct attribute_group;
+
void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
#ifdef CONFIG_GENERIC_MSI_IRQ
void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);
@@ -174,9 +176,11 @@ struct msi_desc {
/**
* msi_device_data - MSI per device data
* @properties: MSI properties which are interesting to drivers
+ * @attrs: Pointer to the sysfs attribute group
*/
struct msi_device_data {
unsigned long properties;
+ const struct attribute_group **attrs;
};
int msi_setup_device_data(struct device *dev);
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -200,6 +200,20 @@ const struct attribute_group **msi_popul
}
/**
+ * msi_device_populate_sysfs - Populate msi_irqs sysfs entries for a device
+ * @dev: The device (PCI, platform etc) which will get sysfs entries
+ */
+int msi_device_populate_sysfs(struct device *dev)
+{
+ const struct attribute_group **group = msi_populate_sysfs(dev);
+
+ if (IS_ERR(group))
+ return PTR_ERR(group);
+ dev->msi.data->attrs = group;
+ return 0;
+}
+
+/**
* msi_destroy_sysfs - Destroy msi_irqs sysfs entries for devices
* @dev: The device(PCI, platform etc) who will remove sysfs entries
* @msi_irq_groups: attribute_group for device msi_irqs entries
@@ -225,6 +239,17 @@ void msi_destroy_sysfs(struct device *de
kfree(msi_irq_groups);
}
}
+
+/**
+ * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device
+ * @dev: The device (PCI, platform etc) for which to remove
+ * sysfs entries
+ */
+void msi_device_destroy_sysfs(struct device *dev)
+{
+ msi_destroy_sysfs(dev, dev->msi.data->attrs);
+ dev->msi.data->attrs = NULL;
+}
#endif
#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
@@ -672,8 +697,19 @@ int msi_domain_alloc_irqs(struct irq_dom
{
struct msi_domain_info *info = domain->host_data;
struct msi_domain_ops *ops = info->ops;
+ int ret;
- return ops->domain_alloc_irqs(domain, dev, nvec);
+ ret = ops->domain_alloc_irqs(domain, dev, nvec);
+ if (ret)
+ return ret;
+
+ if (!(info->flags & MSI_FLAG_DEV_SYSFS))
+ return 0;
+
+ ret = msi_device_populate_sysfs(dev);
+ if (ret)
+ msi_domain_free_irqs(domain, dev);
+ return ret;
}
void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
@@ -712,7 +748,9 @@ void msi_domain_free_irqs(struct irq_dom
struct msi_domain_info *info = domain->host_data;
struct msi_domain_ops *ops = info->ops;
- return ops->domain_free_irqs(domain, dev);
+ if (info->flags & MSI_FLAG_DEV_SYSFS)
+ msi_device_destroy_sysfs(dev);
+ ops->domain_free_irqs(domain, dev);
}
/**
^ permalink raw reply
* [patch V3 14/35] PCI/MSI: Let the irq code handle sysfs groups
From: Thomas Gleixner @ 2021-12-10 22:19 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Set the domain info flag which makes the core code handle sysfs groups and
put an explicit invocation into the legacy code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/msi/irqdomain.c | 2 +-
drivers/pci/msi/legacy.c | 6 +++++-
drivers/pci/msi/msi.c | 23 -----------------------
include/linux/pci.h | 1 -
4 files changed, 6 insertions(+), 26 deletions(-)
--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -159,7 +159,7 @@ struct irq_domain *pci_msi_create_irq_do
if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
pci_msi_domain_update_chip_ops(info);
- info->flags |= MSI_FLAG_ACTIVATE_EARLY;
+ info->flags |= MSI_FLAG_ACTIVATE_EARLY | MSI_FLAG_DEV_SYSFS;
if (IS_ENABLED(CONFIG_GENERIC_IRQ_RESERVATION_MODE))
info->flags |= MSI_FLAG_MUST_REACTIVATE;
--- a/drivers/pci/msi/legacy.c
+++ b/drivers/pci/msi/legacy.c
@@ -70,10 +70,14 @@ int pci_msi_legacy_setup_msi_irqs(struct
{
int ret = arch_setup_msi_irqs(dev, nvec, type);
- return pci_msi_setup_check_result(dev, type, ret);
+ ret = pci_msi_setup_check_result(dev, type, ret);
+ if (!ret)
+ ret = msi_device_populate_sysfs(&dev->dev);
+ return ret;
}
void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev)
{
+ msi_device_destroy_sysfs(&dev->dev);
arch_teardown_msi_irqs(dev);
}
--- a/drivers/pci/msi/msi.c
+++ b/drivers/pci/msi/msi.c
@@ -233,11 +233,6 @@ static void free_msi_irqs(struct pci_dev
for (i = 0; i < entry->nvec_used; i++)
BUG_ON(irq_has_action(entry->irq + i));
- if (dev->msi_irq_groups) {
- msi_destroy_sysfs(&dev->dev, dev->msi_irq_groups);
- dev->msi_irq_groups = NULL;
- }
-
pci_msi_teardown_msi_irqs(dev);
list_for_each_entry_safe(entry, tmp, msi_list, list) {
@@ -417,7 +412,6 @@ static int msi_verify_entries(struct pci
static int msi_capability_init(struct pci_dev *dev, int nvec,
struct irq_affinity *affd)
{
- const struct attribute_group **groups;
struct msi_desc *entry;
int ret;
@@ -448,14 +442,6 @@ static int msi_capability_init(struct pc
if (ret)
goto err;
- groups = msi_populate_sysfs(&dev->dev);
- if (IS_ERR(groups)) {
- ret = PTR_ERR(groups);
- goto err;
- }
-
- dev->msi_irq_groups = groups;
-
/* Set MSI enabled bits */
pci_intx_for_msi(dev, 0);
pci_msi_set_enable(dev, 1);
@@ -584,7 +570,6 @@ static void msix_mask_all(void __iomem *
static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
int nvec, struct irq_affinity *affd)
{
- const struct attribute_group **groups;
void __iomem *base;
int ret, tsize;
u16 control;
@@ -629,14 +614,6 @@ static int msix_capability_init(struct p
msix_update_entries(dev, entries);
- groups = msi_populate_sysfs(&dev->dev);
- if (IS_ERR(groups)) {
- ret = PTR_ERR(groups);
- goto out_free;
- }
-
- dev->msi_irq_groups = groups;
-
/* Disable INTX and unmask MSI-X */
pci_intx_for_msi(dev, 0);
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -475,7 +475,6 @@ struct pci_dev {
#ifdef CONFIG_PCI_MSI
void __iomem *msix_base;
raw_spinlock_t msi_lock;
- const struct attribute_group **msi_irq_groups;
#endif
struct pci_vpd vpd;
#ifdef CONFIG_PCIE_DPC
^ permalink raw reply
* [patch V3 15/35] platform-msi: Let the core code handle sysfs groups
From: Thomas Gleixner @ 2021-12-10 22:19 UTC (permalink / raw)
To: LKML
Cc: Nishanth Menon, Mark Rutland, Stuart Yoder, Will Deacon,
Ashok Raj, Joerg Roedel, Jassi Brar, Sinan Kaya, iommu,
Peter Ujfalusi, Bjorn Helgaas, linux-arm-kernel, Jason Gunthorpe,
linux-pci, xen-devel, Kevin Tian, Arnd Bergmann, Robin Murphy,
Alex Williamson, Cedric Le Goater, Santosh Shilimkar,
Bjorn Helgaas, Megha Dey, Laurentiu Tudor, Juergen Gross,
Tero Kristo, Greg Kroah-Hartman, Vinod Koul, Marc Zygnier,
dmaengine, linuxppc-dev
In-Reply-To: <20211210221642.869015045@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Set the domain info flag and remove the local sysfs code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/base/platform-msi.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -23,7 +23,6 @@
struct platform_msi_priv_data {
struct device *dev;
void *host_data;
- const struct attribute_group **msi_irq_groups;
msi_alloc_info_t arg;
irq_write_msi_msg_t write_msg;
int devid;
@@ -191,6 +190,7 @@ struct irq_domain *platform_msi_create_i
platform_msi_update_dom_ops(info);
if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
platform_msi_update_chip_ops(info);
+ info->flags |= MSI_FLAG_DEV_SYSFS;
domain = msi_create_irq_domain(fwnode, info, parent);
if (domain)
@@ -279,16 +279,8 @@ int platform_msi_domain_alloc_irqs(struc
if (err)
goto out_free_desc;
- priv_data->msi_irq_groups = msi_populate_sysfs(dev);
- if (IS_ERR(priv_data->msi_irq_groups)) {
- err = PTR_ERR(priv_data->msi_irq_groups);
- goto out_free_irqs;
- }
-
return 0;
-out_free_irqs:
- msi_domain_free_irqs(dev->msi.domain, dev);
out_free_desc:
platform_msi_free_descs(dev, 0, nvec);
out_free_priv_data:
@@ -308,7 +300,6 @@ void platform_msi_domain_free_irqs(struc
struct msi_desc *desc;
desc = first_msi_entry(dev);
- msi_destroy_sysfs(dev, desc->platform.msi_priv_data->msi_irq_groups);
platform_msi_free_priv_data(desc->platform.msi_priv_data);
}
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox