Re: [PATCH] percpu: improve percpu_alloc_percpu_fail event trace

2024-01-24 Thread Dennis Zhou
Hello,

On Mon, Jan 22, 2024 at 08:55:39PM -0500, Steven Rostedt wrote:
> On Tue, 23 Jan 2024 09:44:43 +0800
> George Guo  wrote:
> 
> > There are two reasons of percpu_alloc failed without warnings: 
> > 
> > 1. do_warn is false
> > 2. do_warn is true and warn_limit is reached the limit.
> 
> Yes I know the reasons.
> 
> > 
> > Showing do_warn and warn_limit makes things simple, maybe dont need
> > kprobe again.
> 
> It's up to the maintainers of that code to decide if it's worth it or not,
> but honestly, my opinion it is not.
> 

I agree, I don't think this is a worthwhile change. If we do change
this, I'd like it to be more actionable in some way and as a result
something we can fix or tune accordingly.

George is this a common problem you're seeing?

> The trace event in question is to trace that percpu_alloc failed and why.
> It's not there to determine why it did not produce a printk message.
> 
> -- Steve

Thanks,
Dennis



Re: [PATCH v4 0/4] percpu: partial chunk depopulation

2021-04-20 Thread Dennis Zhou
On Tue, Apr 20, 2021 at 04:37:02PM +0530, Pratik Sampat wrote:
> 
> On 20/04/21 4:27 am, Dennis Zhou wrote:
> > On Mon, Apr 19, 2021 at 10:50:43PM +, Dennis Zhou wrote:
> > > Hello,
> > > 
> > > This series is a continuation of Roman's series in [1]. It aims to solve
> > > chunks holding onto free pages by adding a reclaim process to the percpu
> > > balance work item.
> > > 
> > > The main difference is that the nr_empty_pop_pages is now managed at
> > > time of isolation instead of intermixed. This helps with deciding which
> > > chunks to free instead of having to interleave returning chunks to
> > > active duty.
> > > 
> > > The allocation priority is as follows:
> > >1) appropriate chunk slot increasing until fit
> > >2) sidelined chunks
> > >3) full free chunks
> > > 
> > > The last slot for to_depopulate is never used for allocations.
> > > 
> > > A big thanks to Roman for initiating the work and being available for
> > > iterating on these ideas.
> > > 
> > > This patchset contains the following 4 patches:
> > >0001-percpu-factor-out-pcpu_check_block_hint.patch
> > >0002-percpu-use-pcpu_free_slot-instead-of-pcpu_nr_slots-1.patch
> > >0003-percpu-implement-partial-chunk-depopulation.patch
> > >0004-percpu-use-reclaim-threshold-instead-of-running-for-.patch
> > > 
> > > 0001 and 0002 are clean ups. 0003 implement partial chunk depopulation
> > > initially from Roman. 0004 adds a reclaim threshold so we do not need to
> > > schedule for every page freed.
> > > 
> > > This series is on top of percpu$for-5.14 67c2669d69fb.
> > > 
> > > diffstats below:
> > > 
> > > Dennis Zhou (2):
> > >percpu: use pcpu_free_slot instead of pcpu_nr_slots - 1
> > >percpu: use reclaim threshold instead of running for every page
> > > 
> > > Roman Gushchin (2):
> > >percpu: factor out pcpu_check_block_hint()
> > >percpu: implement partial chunk depopulation
> > > 
> > >   mm/percpu-internal.h |   5 +
> > >   mm/percpu-km.c   |   5 +
> > >   mm/percpu-stats.c|  20 ++--
> > >   mm/percpu-vm.c   |  30 ++
> > >   mm/percpu.c  | 252 ++-
> > >   5 files changed, 278 insertions(+), 34 deletions(-)
> > > 
> > > Thanks,
> > > Dennis
> > Hello Pratik,
> > 
> > Do you mind testing this series again on POWER9? The base is available
> > here:
> > https://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git/log/?h=for-5.14
> > 
> > Thanks,
> > Dennis
> 
> Hello Dennis, I have tested this patchset on POWER9.
> 
> I have tried variations of the percpu_test in the top level and nested cgroups
> creation as the test with 1000:10 didn't show any benefits.

This is most likely because the 1 in every 11 still pins every page
while 1 in 50 does not. Can you try the patch below on top? I think it
may show slightly better perf as well. If it doesn't I'll just drop it.

> 
> The following example shows more consistent benefits with the de-allocation
> strategy.
> Outer: 1000
> Inner: 50
> # ./percpu_test.sh
> Percpu: 6912 kB
> Percpu:   532736 kB
> Percpu:   278784 kB
> 
> I believe it could be a result of bulk freeing within 
> "free_unref_page_commit",
> where pages are only free'd if pcp->count >= pcp->high. As POWER has a larger
> page size it would end up creating lesser number of pages but with the
> effects of fragmentation.

This is unrelated to per cpu pages in slab/slub. Percpu is a separate
memory allocator.

> 
> Having said that, the patchset and its behavior does look good to me.

Thanks, can I throw the following on the appropriate patches? In the
future it's good to be explicit about this because some prefer to credit
different emails.

Tested-by: Pratik Sampat 

Thanks,
Dennis

The following may do a little better on power9:
---
>From a1464c4d5900cca68fd95b935178d72bb74837d5 Mon Sep 17 00:00:00 2001
From: Dennis Zhou 
Date: Tue, 20 Apr 2021 14:25:20 +
Subject: [PATCH] percpu: convert free page float to bytes

The percpu memory allocator keeps around a minimum number of free pages
to ensure we can satisfy atomic allocations. However, we've always kept
this number in terms of pages. On certain architectures like arm and
powerpc, the default page size could be 64k instead of 4k. So, start
with a target number of free bytes and then co

Re: [PATCH v4 0/4] percpu: partial chunk depopulation

2021-04-19 Thread Dennis Zhou
On Mon, Apr 19, 2021 at 10:50:43PM +, Dennis Zhou wrote:
> Hello,
> 
> This series is a continuation of Roman's series in [1]. It aims to solve
> chunks holding onto free pages by adding a reclaim process to the percpu
> balance work item.
> 
> The main difference is that the nr_empty_pop_pages is now managed at
> time of isolation instead of intermixed. This helps with deciding which
> chunks to free instead of having to interleave returning chunks to
> active duty.
> 
> The allocation priority is as follows:
>   1) appropriate chunk slot increasing until fit
>   2) sidelined chunks
>   3) full free chunks
> 
> The last slot for to_depopulate is never used for allocations.
> 
> A big thanks to Roman for initiating the work and being available for
> iterating on these ideas.
> 
> This patchset contains the following 4 patches:
>   0001-percpu-factor-out-pcpu_check_block_hint.patch
>   0002-percpu-use-pcpu_free_slot-instead-of-pcpu_nr_slots-1.patch
>   0003-percpu-implement-partial-chunk-depopulation.patch
>   0004-percpu-use-reclaim-threshold-instead-of-running-for-.patch
> 
> 0001 and 0002 are clean ups. 0003 implement partial chunk depopulation
> initially from Roman. 0004 adds a reclaim threshold so we do not need to
> schedule for every page freed.
> 
> This series is on top of percpu$for-5.14 67c2669d69fb.
> 
> diffstats below:
> 
> Dennis Zhou (2):
>   percpu: use pcpu_free_slot instead of pcpu_nr_slots - 1
>   percpu: use reclaim threshold instead of running for every page
> 
> Roman Gushchin (2):
>   percpu: factor out pcpu_check_block_hint()
>   percpu: implement partial chunk depopulation
> 
>  mm/percpu-internal.h |   5 +
>  mm/percpu-km.c   |   5 +
>  mm/percpu-stats.c|  20 ++--
>  mm/percpu-vm.c   |  30 ++
>  mm/percpu.c  | 252 ++-
>  5 files changed, 278 insertions(+), 34 deletions(-)
> 
> Thanks,
> Dennis

Hello Pratik,

Do you mind testing this series again on POWER9? The base is available
here:
https://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git/log/?h=for-5.14

Thanks,
Dennis


Re: [PATCH v4 0/4] percpu: partial chunk depopulation

2021-04-19 Thread Dennis Zhou
On Mon, Apr 19, 2021 at 10:50:43PM +, Dennis Zhou wrote:
> Hello,
> 
> This series is a continuation of Roman's series in [1]. It aims to solve
> chunks holding onto free pages by adding a reclaim process to the percpu
> balance work item.
> 

And I forgot to link [1]...
[1] https://lore.kernel.org/lkml/20210408035736.883861-1-g...@fb.com/

> The main difference is that the nr_empty_pop_pages is now managed at
> time of isolation instead of intermixed. This helps with deciding which
> chunks to free instead of having to interleave returning chunks to
> active duty.
> 
> The allocation priority is as follows:
>   1) appropriate chunk slot increasing until fit
>   2) sidelined chunks
>   3) full free chunks
> 
> The last slot for to_depopulate is never used for allocations.
> 
> A big thanks to Roman for initiating the work and being available for
> iterating on these ideas.
> 
> This patchset contains the following 4 patches:
>   0001-percpu-factor-out-pcpu_check_block_hint.patch
>   0002-percpu-use-pcpu_free_slot-instead-of-pcpu_nr_slots-1.patch
>   0003-percpu-implement-partial-chunk-depopulation.patch
>   0004-percpu-use-reclaim-threshold-instead-of-running-for-.patch
> 
> 0001 and 0002 are clean ups. 0003 implement partial chunk depopulation
> initially from Roman. 0004 adds a reclaim threshold so we do not need to
> schedule for every page freed.
> 
> This series is on top of percpu$for-5.14 67c2669d69fb.
> 
> diffstats below:
> 
> Dennis Zhou (2):
>   percpu: use pcpu_free_slot instead of pcpu_nr_slots - 1
>   percpu: use reclaim threshold instead of running for every page
> 
> Roman Gushchin (2):
>   percpu: factor out pcpu_check_block_hint()
>   percpu: implement partial chunk depopulation
> 
>  mm/percpu-internal.h |   5 +
>  mm/percpu-km.c   |   5 +
>  mm/percpu-stats.c|  20 ++--
>  mm/percpu-vm.c   |  30 ++
>  mm/percpu.c  | 252 ++-
>  5 files changed, 278 insertions(+), 34 deletions(-)
> 
> Thanks,
> Dennis


[PATCH 3/4] percpu: implement partial chunk depopulation

2021-04-19 Thread Dennis Zhou
From: Roman Gushchin 

This patch implements partial depopulation of percpu chunks.

As of now, a chunk can be depopulated only as a part of the final
destruction, if there are no more outstanding allocations. However
to minimize a memory waste it might be useful to depopulate a
partially filed chunk, if a small number of outstanding allocations
prevents the chunk from being fully reclaimed.

This patch implements the following depopulation process: it scans
over the chunk pages, looks for a range of empty and populated pages
and performs the depopulation. To avoid races with new allocations,
the chunk is previously isolated. After the depopulation the chunk is
sidelined to a special list or freed. New allocations prefer using
active chunks to sidelined chunks. If a sidelined chunk is used, it is
reintegrated to the active lists.

The depopulation is scheduled on the free path if the chunk is all of
the following:
  1) has more than 1/4 of total pages free and populated
  2) the system has enough free percpu pages aside of this chunk
  3) isn't the reserved chunk
  4) isn't the first chunk
If it's already depopulated but got free populated pages, it's a good
target too. The chunk is moved to a special slot,
pcpu_to_depopulate_slot, chunk->isolated is set, and the balance work
item is scheduled. On isolation, these pages are removed from the
pcpu_nr_empty_pop_pages. It is constantly replaced to the
to_depopulate_slot when it meets these qualifications.

pcpu_reclaim_populated() iterates over the to_depopulate_slot until it
becomes empty. The depopulation is performed in the reverse direction to
keep populated pages close to the beginning. Depopulated chunks are
sidelined to preferentially avoid them for new allocations. When no
active chunk can suffice a new allocation, sidelined chunks are first
checked before creating a new chunk.

Signed-off-by: Roman Gushchin 
Co-developed-by: Dennis Zhou 
Signed-off-by: Dennis Zhou 
---
 mm/percpu-internal.h |   4 +
 mm/percpu-km.c   |   5 ++
 mm/percpu-stats.c|  12 +--
 mm/percpu-vm.c   |  30 
 mm/percpu.c  | 180 +++
 5 files changed, 211 insertions(+), 20 deletions(-)

diff --git a/mm/percpu-internal.h b/mm/percpu-internal.h
index 095d7eaa0db4..10604dce806f 100644
--- a/mm/percpu-internal.h
+++ b/mm/percpu-internal.h
@@ -67,6 +67,8 @@ struct pcpu_chunk {
 
void*data;  /* chunk data */
boolimmutable;  /* no [de]population allowed */
+   boolisolated;   /* isolated from active chunk
+  slots */
int start_offset;   /* the overlap with the previous
   region to have a page aligned
   base_addr */
@@ -87,6 +89,8 @@ extern spinlock_t pcpu_lock;
 
 extern struct list_head *pcpu_chunk_lists;
 extern int pcpu_nr_slots;
+extern int pcpu_sidelined_slot;
+extern int pcpu_to_depopulate_slot;
 extern int pcpu_nr_empty_pop_pages[];
 
 extern struct pcpu_chunk *pcpu_first_chunk;
diff --git a/mm/percpu-km.c b/mm/percpu-km.c
index 35c9941077ee..c84a9f781a6c 100644
--- a/mm/percpu-km.c
+++ b/mm/percpu-km.c
@@ -118,3 +118,8 @@ static int __init pcpu_verify_alloc_info(const struct 
pcpu_alloc_info *ai)
 
return 0;
 }
+
+static bool pcpu_should_reclaim_chunk(struct pcpu_chunk *chunk)
+{
+   return false;
+}
diff --git a/mm/percpu-stats.c b/mm/percpu-stats.c
index f6026dbcdf6b..2125981acfb9 100644
--- a/mm/percpu-stats.c
+++ b/mm/percpu-stats.c
@@ -219,13 +219,15 @@ static int percpu_stats_show(struct seq_file *m, void *v)
for (slot = 0; slot < pcpu_nr_slots; slot++) {
list_for_each_entry(chunk, &pcpu_chunk_list(type)[slot],
list) {
-   if (chunk == pcpu_first_chunk) {
+   if (chunk == pcpu_first_chunk)
seq_puts(m, "Chunk: <- First Chunk\n");
-   chunk_map_stats(m, chunk, buffer);
-   } else {
+   else if (slot == pcpu_to_depopulate_slot)
+   seq_puts(m, "Chunk (to_depopulate)\n");
+   else if (slot == pcpu_sidelined_slot)
+   seq_puts(m, "Chunk (sidelined):\n");
+   else
seq_puts(m, "Chunk:\n");
-   chunk_map_stats(m, chunk, buffer);
-   }
+   chunk_map_stats(m, chunk, buffer);
}
}
}
diff --git a/mm/perc

[PATCH 4/4] percpu: use reclaim threshold instead of running for every page

2021-04-19 Thread Dennis Zhou
The last patch implements reclaim by adding 2 additional lists where a
chunk's lifecycle is:
  active_slot -> to_depopulate_slot -> sidelined_slot

This worked great because we're able to nicely converge paths into
isolation. However, it's a bit aggressive to run for every free page.
Let's accumulate a few free pages before we do this. To do this, the new
lifecycle is:
  active_slot -> sidelined_slot -> to_depopulate_slot -> sidelined_slot

The transition from sidelined_slot -> to_depopulate_slot occurs on a
threshold instead of before where it directly went to the
to_depopulate_slot. pcpu_nr_isolated_empty_pop_pages[] is introduced to
aid with this.

Suggested-by: Roman Gushchin 
Signed-off-by: Dennis Zhou 
---
 mm/percpu-internal.h |  1 +
 mm/percpu-stats.c|  8 ++--
 mm/percpu.c  | 44 +---
 3 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/mm/percpu-internal.h b/mm/percpu-internal.h
index 10604dce806f..b3e43b016276 100644
--- a/mm/percpu-internal.h
+++ b/mm/percpu-internal.h
@@ -92,6 +92,7 @@ extern int pcpu_nr_slots;
 extern int pcpu_sidelined_slot;
 extern int pcpu_to_depopulate_slot;
 extern int pcpu_nr_empty_pop_pages[];
+extern int pcpu_nr_isolated_empty_pop_pages[];
 
 extern struct pcpu_chunk *pcpu_first_chunk;
 extern struct pcpu_chunk *pcpu_reserved_chunk;
diff --git a/mm/percpu-stats.c b/mm/percpu-stats.c
index 2125981acfb9..facc804eb86c 100644
--- a/mm/percpu-stats.c
+++ b/mm/percpu-stats.c
@@ -145,7 +145,7 @@ static int percpu_stats_show(struct seq_file *m, void *v)
int slot, max_nr_alloc;
int *buffer;
enum pcpu_chunk_type type;
-   int nr_empty_pop_pages;
+   int nr_empty_pop_pages, nr_isolated_empty_pop_pages;
 
 alloc_buffer:
spin_lock_irq(&pcpu_lock);
@@ -167,8 +167,11 @@ static int percpu_stats_show(struct seq_file *m, void *v)
}
 
nr_empty_pop_pages = 0;
-   for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++)
+   nr_isolated_empty_pop_pages = 0;
+   for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++) {
nr_empty_pop_pages += pcpu_nr_empty_pop_pages[type];
+   nr_isolated_empty_pop_pages += 
pcpu_nr_isolated_empty_pop_pages[type];
+   }
 
 #define PL(X)  \
seq_printf(m, "  %-20s: %12lld\n", #X, (long long int)pcpu_stats_ai.X)
@@ -202,6 +205,7 @@ static int percpu_stats_show(struct seq_file *m, void *v)
PU(min_alloc_size);
PU(max_alloc_size);
P("empty_pop_pages", nr_empty_pop_pages);
+   P("iso_empty_pop_pages", nr_isolated_empty_pop_pages);
seq_putc(m, '\n');
 
 #undef PU
diff --git a/mm/percpu.c b/mm/percpu.c
index 79eebc80860d..ba13e683d022 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -110,6 +110,9 @@
 #define PCPU_EMPTY_POP_PAGES_LOW   2
 #define PCPU_EMPTY_POP_PAGES_HIGH  4
 
+/* only schedule reclaim if there are at least N empty pop pages sidelined */
+#define PCPU_EMPTY_POP_RECLAIM_THRESHOLD   4
+
 #ifdef CONFIG_SMP
 /* default addr <-> pcpu_ptr mapping, override in asm/percpu.h if necessary */
 #ifndef __addr_to_pcpu_ptr
@@ -183,6 +186,7 @@ static LIST_HEAD(pcpu_map_extend_chunks);
  * The reserved chunk doesn't contribute to the count.
  */
 int pcpu_nr_empty_pop_pages[PCPU_NR_CHUNK_TYPES];
+int pcpu_nr_isolated_empty_pop_pages[PCPU_NR_CHUNK_TYPES];
 
 /*
  * The number of populated pages in use by the allocator, protected by
@@ -582,8 +586,10 @@ static void pcpu_isolate_chunk(struct pcpu_chunk *chunk)
if (!chunk->isolated) {
chunk->isolated = true;
pcpu_nr_empty_pop_pages[type] -= chunk->nr_empty_pop_pages;
+   pcpu_nr_isolated_empty_pop_pages[type] +=
+   chunk->nr_empty_pop_pages;
+   list_move(&chunk->list, &pcpu_slot[pcpu_sidelined_slot]);
}
-   list_move(&chunk->list, &pcpu_slot[pcpu_to_depopulate_slot]);
 }
 
 static void pcpu_reintegrate_chunk(struct pcpu_chunk *chunk)
@@ -595,6 +601,8 @@ static void pcpu_reintegrate_chunk(struct pcpu_chunk *chunk)
if (chunk->isolated) {
chunk->isolated = false;
pcpu_nr_empty_pop_pages[type] += chunk->nr_empty_pop_pages;
+   pcpu_nr_isolated_empty_pop_pages[type] -=
+   chunk->nr_empty_pop_pages;
pcpu_chunk_relocate(chunk, -1);
}
 }
@@ -610,9 +618,15 @@ static void pcpu_reintegrate_chunk(struct pcpu_chunk 
*chunk)
  */
 static inline void pcpu_update_empty_pages(struct pcpu_chunk *chunk, int nr)
 {
+   enum pcpu_chunk_type type = pcpu_chunk_type(chunk);
+
chunk->nr_empty_pop_pages += nr;
-   if (chunk != pcpu_reserved_chunk && !chunk->isolated)
-   pcpu_nr_empty_pop_pages[pcpu_chunk_typ

[PATCH 2/4] percpu: use pcpu_free_slot instead of pcpu_nr_slots - 1

2021-04-19 Thread Dennis Zhou
This prepares for adding a to_depopulate list and sidelined list after
the free slot in the set of lists in pcpu_slot.

Signed-off-by: Dennis Zhou 
---
 mm/percpu.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/mm/percpu.c b/mm/percpu.c
index 5edc7bd88133..d46f4adc 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -135,6 +135,7 @@ static int pcpu_unit_size __ro_after_init;
 static int pcpu_nr_units __ro_after_init;
 static int pcpu_atom_size __ro_after_init;
 int pcpu_nr_slots __ro_after_init;
+int pcpu_free_slot __ro_after_init;
 static size_t pcpu_chunk_struct_size __ro_after_init;
 
 /* cpus with the lowest and highest unit addresses */
@@ -237,7 +238,7 @@ static int __pcpu_size_to_slot(int size)
 static int pcpu_size_to_slot(int size)
 {
if (size == pcpu_unit_size)
-   return pcpu_nr_slots - 1;
+   return pcpu_free_slot;
return __pcpu_size_to_slot(size);
 }
 
@@ -1806,7 +1807,7 @@ static void __percpu *pcpu_alloc(size_t size, size_t 
align, bool reserved,
goto fail;
}
 
-   if (list_empty(&pcpu_slot[pcpu_nr_slots - 1])) {
+   if (list_empty(&pcpu_slot[pcpu_free_slot])) {
chunk = pcpu_create_chunk(type, pcpu_gfp);
if (!chunk) {
err = "failed to allocate new chunk";
@@ -1958,7 +1959,7 @@ static void pcpu_balance_free(enum pcpu_chunk_type type)
 {
LIST_HEAD(to_free);
struct list_head *pcpu_slot = pcpu_chunk_list(type);
-   struct list_head *free_head = &pcpu_slot[pcpu_nr_slots - 1];
+   struct list_head *free_head = &pcpu_slot[pcpu_free_slot];
struct pcpu_chunk *chunk, *next;
 
/*
@@ -2033,7 +2034,7 @@ static void pcpu_balance_populated(enum pcpu_chunk_type 
type)
  0, PCPU_EMPTY_POP_PAGES_HIGH);
}
 
-   for (slot = pcpu_size_to_slot(PAGE_SIZE); slot < pcpu_nr_slots; slot++) 
{
+   for (slot = pcpu_size_to_slot(PAGE_SIZE); slot <= pcpu_free_slot; 
slot++) {
unsigned int nr_unpop = 0, rs, re;
 
if (!nr_to_pop)
@@ -2140,7 +2141,7 @@ void free_percpu(void __percpu *ptr)
if (chunk->free_bytes == pcpu_unit_size) {
struct pcpu_chunk *pos;
 
-   list_for_each_entry(pos, &pcpu_slot[pcpu_nr_slots - 1], list)
+   list_for_each_entry(pos, &pcpu_slot[pcpu_free_slot], list)
if (pos != chunk) {
need_balance = true;
break;
@@ -2562,7 +2563,8 @@ void __init pcpu_setup_first_chunk(const struct 
pcpu_alloc_info *ai,
 * Allocate chunk slots.  The additional last slot is for
 * empty chunks.
 */
-   pcpu_nr_slots = __pcpu_size_to_slot(pcpu_unit_size) + 2;
+   pcpu_free_slot = __pcpu_size_to_slot(pcpu_unit_size) + 1;
+   pcpu_nr_slots = pcpu_free_slot + 1;
pcpu_chunk_lists = memblock_alloc(pcpu_nr_slots *
  sizeof(pcpu_chunk_lists[0]) *
  PCPU_NR_CHUNK_TYPES,
-- 
2.31.1.368.gbe11c130af-goog



[PATCH 1/4] percpu: factor out pcpu_check_block_hint()

2021-04-19 Thread Dennis Zhou
From: Roman Gushchin 

Factor out the pcpu_check_block_hint() helper, which will be useful
in the future. The new function checks if the allocation can likely
fit within the contig hint.

Signed-off-by: Roman Gushchin 
Signed-off-by: Dennis Zhou 
---
 mm/percpu.c | 30 +++---
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/mm/percpu.c b/mm/percpu.c
index 61339b3d9337..5edc7bd88133 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -306,6 +306,25 @@ static unsigned long pcpu_block_off_to_off(int index, int 
off)
return index * PCPU_BITMAP_BLOCK_BITS + off;
 }
 
+/**
+ * pcpu_check_block_hint - check against the contig hint
+ * @block: block of interest
+ * @bits: size of allocation
+ * @align: alignment of area (max PAGE_SIZE)
+ *
+ * Check to see if the allocation can fit in the block's contig hint.
+ * Note, a chunk uses the same hints as a block so this can also check against
+ * the chunk's contig hint.
+ */
+static bool pcpu_check_block_hint(struct pcpu_block_md *block, int bits,
+ size_t align)
+{
+   int bit_off = ALIGN(block->contig_hint_start, align) -
+   block->contig_hint_start;
+
+   return bit_off + bits <= block->contig_hint;
+}
+
 /*
  * pcpu_next_hint - determine which hint to use
  * @block: block of interest
@@ -1066,14 +1085,11 @@ static int pcpu_find_block_fit(struct pcpu_chunk 
*chunk, int alloc_bits,
int bit_off, bits, next_off;
 
/*
-* Check to see if the allocation can fit in the chunk's contig hint.
-* This is an optimization to prevent scanning by assuming if it
-* cannot fit in the global hint, there is memory pressure and creating
-* a new chunk would happen soon.
+* This is an optimization to prevent scanning by assuming if the
+* allocation cannot fit in the global hint, there is memory pressure
+* and creating a new chunk would happen soon.
 */
-   bit_off = ALIGN(chunk_md->contig_hint_start, align) -
- chunk_md->contig_hint_start;
-   if (bit_off + alloc_bits > chunk_md->contig_hint)
+   if (!pcpu_check_block_hint(chunk_md, alloc_bits, align))
return -1;
 
bit_off = pcpu_next_hint(chunk_md, alloc_bits);
-- 
2.31.1.368.gbe11c130af-goog



[PATCH v4 0/4] percpu: partial chunk depopulation

2021-04-19 Thread Dennis Zhou
Hello,

This series is a continuation of Roman's series in [1]. It aims to solve
chunks holding onto free pages by adding a reclaim process to the percpu
balance work item.

The main difference is that the nr_empty_pop_pages is now managed at
time of isolation instead of intermixed. This helps with deciding which
chunks to free instead of having to interleave returning chunks to
active duty.

The allocation priority is as follows:
  1) appropriate chunk slot increasing until fit
  2) sidelined chunks
  3) full free chunks

The last slot for to_depopulate is never used for allocations.

A big thanks to Roman for initiating the work and being available for
iterating on these ideas.

This patchset contains the following 4 patches:
  0001-percpu-factor-out-pcpu_check_block_hint.patch
  0002-percpu-use-pcpu_free_slot-instead-of-pcpu_nr_slots-1.patch
  0003-percpu-implement-partial-chunk-depopulation.patch
  0004-percpu-use-reclaim-threshold-instead-of-running-for-.patch

0001 and 0002 are clean ups. 0003 implement partial chunk depopulation
initially from Roman. 0004 adds a reclaim threshold so we do not need to
schedule for every page freed.

This series is on top of percpu$for-5.14 67c2669d69fb.

diffstats below:

Dennis Zhou (2):
  percpu: use pcpu_free_slot instead of pcpu_nr_slots - 1
  percpu: use reclaim threshold instead of running for every page

Roman Gushchin (2):
  percpu: factor out pcpu_check_block_hint()
  percpu: implement partial chunk depopulation

 mm/percpu-internal.h |   5 +
 mm/percpu-km.c   |   5 +
 mm/percpu-stats.c|  20 ++--
 mm/percpu-vm.c   |  30 ++
 mm/percpu.c  | 252 ++-
 5 files changed, 278 insertions(+), 34 deletions(-)

Thanks,
Dennis


Re: [PATCH v3 0/6] percpu: partial chunk depopulation

2021-04-16 Thread Dennis Zhou
Hello,

On Sat, Apr 17, 2021 at 01:14:03AM +0530, Pratik Sampat wrote:
> 
> 
> On 17/04/21 12:39 am, Roman Gushchin wrote:
> > On Sat, Apr 17, 2021 at 12:11:37AM +0530, Pratik Sampat wrote:
> > > 
> > > On 17/04/21 12:04 am, Roman Gushchin wrote:
> > > > On Fri, Apr 16, 2021 at 11:57:03PM +0530, Pratik Sampat wrote:
> > > > > On 16/04/21 10:43 pm, Roman Gushchin wrote:
> > > > > > On Fri, Apr 16, 2021 at 08:58:33PM +0530, Pratik Sampat wrote:
> > > > > > > Hello Dennis,
> > > > > > > 
> > > > > > > I apologize for the clutter of logs before, I'm pasting the logs 
> > > > > > > of before and
> > > > > > > after the percpu test in the case of the patchset being applied 
> > > > > > > on 5.12-rc6 and
> > > > > > > the vanilla kernel 5.12-rc6.
> > > > > > > 
> > > > > > > On 16/04/21 7:48 pm, Dennis Zhou wrote:
> > > > > > > > Hello,
> > > > > > > > 
> > > > > > > > On Fri, Apr 16, 2021 at 06:26:15PM +0530, Pratik Sampat wrote:
> > > > > > > > > Hello Roman,
> > > > > > > > > 
> > > > > > > > > I've tried the v3 patch series on a POWER9 and an x86 KVM 
> > > > > > > > > setup.
> > > > > > > > > 
> > > > > > > > > My results of the percpu_test are as follows:
> > > > > > > > > Intel KVM 4CPU:4G
> > > > > > > > > Vanilla 5.12-rc6
> > > > > > > > > # ./percpu_test.sh
> > > > > > > > > Percpu: 1952 kB
> > > > > > > > > Percpu:   219648 kB
> > > > > > > > > Percpu:   219648 kB
> > > > > > > > > 
> > > > > > > > > 5.12-rc6 + with patchset applied
> > > > > > > > > # ./percpu_test.sh
> > > > > > > > > Percpu: 2080 kB
> > > > > > > > > Percpu:   219712 kB
> > > > > > > > > Percpu:    72672 kB
> > > > > > > > > 
> > > > > > > > > I'm able to see improvement comparable to that of what you're 
> > > > > > > > > see too.
> > > > > > > > > 
> > > > > > > > > However, on POWERPC I'm unable to reproduce these 
> > > > > > > > > improvements with the patchset in the same configuration
> > > > > > > > > 
> > > > > > > > > POWER9 KVM 4CPU:4G
> > > > > > > > > Vanilla 5.12-rc6
> > > > > > > > > # ./percpu_test.sh
> > > > > > > > > Percpu: 5888 kB
> > > > > > > > > Percpu:   118272 kB
> > > > > > > > > Percpu:   118272 kB
> > > > > > > > > 
> > > > > > > > > 5.12-rc6 + with patchset applied
> > > > > > > > > # ./percpu_test.sh
> > > > > > > > > Percpu: 6144 kB
> > > > > > > > > Percpu:   119040 kB
> > > > > > > > > Percpu:   119040 kB
> > > > > > > > > 
> > > > > > > > > I'm wondering if there's any architectural specific code that 
> > > > > > > > > needs plumbing
> > > > > > > > > here?
> > > > > > > > > 
> > > > > > > > There shouldn't be. Can you send me the percpu_stats debug 
> > > > > > > > output before
> > > > > > > > and after?
> > > > > > > I'll paste the whole debug stats before and after here.
> > > > > > > 5.12-rc6 + patchset
> > > > > > > -BEFORE-
> > > > > > > Percpu Memory Statistics
> > > > > > > Allocation Info:
> > > > > > Hm, this looks highly suspicious. Here is your stats in a more 
> > > > > > compact form:
> > > > > > 
> > > > > > Vanilla
> > > > > > 
> > > > > > nr_alloc: 903

Re: [PATCH v3 5/6] percpu: factor out pcpu_check_chunk_hint()

2021-04-16 Thread Dennis Zhou
Hello,

On Wed, Apr 07, 2021 at 08:57:35PM -0700, Roman Gushchin wrote:
> Factor out the pcpu_check_chunk_hint() helper, which will be useful
> in the future. The new function checks if the allocation can likely
> fit the given chunk.
> 
> Signed-off-by: Roman Gushchin 
> ---
>  mm/percpu.c | 30 +-
>  1 file changed, 21 insertions(+), 9 deletions(-)
> 
> diff --git a/mm/percpu.c b/mm/percpu.c
> index e20119668c42..357fd6994278 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -306,6 +306,26 @@ static unsigned long pcpu_block_off_to_off(int index, 
> int off)
>   return index * PCPU_BITMAP_BLOCK_BITS + off;
>  }
>  
> +/**
> + * pcpu_check_chunk_hint - check that allocation can fit a chunk
> + * @chunk_md: chunk's block

nit for consistency: @block: block of interest

> + * @bits: size of request in allocation units
> + * @align: alignment of area (max PAGE_SIZE)
> + *
> + * Check to see if the allocation can fit in the chunk's contig hint.
> + * This is an optimization to prevent scanning by assuming if it
> + * cannot fit in the global hint, there is memory pressure and creating
> + * a new chunk would happen soon.
> + */

It occurred to me, That I converged block_md and chunk_md to be the same
object as 1 is just a degenerative case of the other. Can we rename this
to be pcpu_check_block_hint() and have it take in pcpu_block_md?

> +static bool pcpu_check_chunk_hint(struct pcpu_block_md *chunk_md, int bits,
> +   size_t align)
> +{
> + int bit_off = ALIGN(chunk_md->contig_hint_start, align) -
> + chunk_md->contig_hint_start;
> +
> + return bit_off + bits <= chunk_md->contig_hint;
> +}
> +
>  /*
>   * pcpu_next_hint - determine which hint to use
>   * @block: block of interest
> @@ -1065,15 +1085,7 @@ static int pcpu_find_block_fit(struct pcpu_chunk 
> *chunk, int alloc_bits,
>   struct pcpu_block_md *chunk_md = &chunk->chunk_md;
>   int bit_off, bits, next_off;
>  
> - /*
> -  * Check to see if the allocation can fit in the chunk's contig hint.
> -  * This is an optimization to prevent scanning by assuming if it
> -  * cannot fit in the global hint, there is memory pressure and creating
> -  * a new chunk would happen soon.
> -  */
> - bit_off = ALIGN(chunk_md->contig_hint_start, align) -
> -   chunk_md->contig_hint_start;
> - if (bit_off + alloc_bits > chunk_md->contig_hint)
> + if (!pcpu_check_chunk_hint(chunk_md, alloc_bits, align))
>   return -1;
>  
>   bit_off = pcpu_next_hint(chunk_md, alloc_bits);
> -- 
> 2.30.2
> 

Thanks,
Dennis


Re: [PATCH v3 4/6] percpu: generalize pcpu_balance_populated()

2021-04-16 Thread Dennis Zhou
 */
> + if (pcpu_atomic_alloc_failed) {
> + nr_to_pop = PCPU_EMPTY_POP_PAGES_HIGH;
> + /* best effort anyway, don't worry about synchronization */
> + pcpu_atomic_alloc_failed = false;
> + pcpu_grow_populated(type, nr_to_pop);
> + } else if (pcpu_nr_empty_pop_pages[type] < PCPU_EMPTY_POP_PAGES_HIGH) {
> + nr_to_pop = PCPU_EMPTY_POP_PAGES_HIGH - 
> pcpu_nr_empty_pop_pages[type];
> + pcpu_grow_populated(type, nr_to_pop);
> + }
> +}
> +
>  /**
>   * pcpu_balance_workfn - manage the amount of free chunks and populated pages
>   * @work: unused
> -- 
> 2.30.2
> 

I've applied this for-5.14.

Thanks,
Dennis


Re: [PATCH v3 3/6] percpu: make pcpu_nr_empty_pop_pages per chunk type

2021-04-16 Thread Dennis Zhou
Hello,

On Wed, Apr 07, 2021 at 08:57:33PM -0700, Roman Gushchin wrote:
> nr_empty_pop_pages is used to guarantee that there are some free
> populated pages to satisfy atomic allocations. Accounted and
> non-accounted allocations are using separate sets of chunks,
> so both need to have a surplus of empty pages.
> 
> This commit makes pcpu_nr_empty_pop_pages and the corresponding logic
> per chunk type.
> 
> Signed-off-by: Roman Gushchin 
> ---
>  mm/percpu-internal.h |  2 +-
>  mm/percpu-stats.c|  9 +++--
>  mm/percpu.c  | 14 +++---
>  3 files changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/mm/percpu-internal.h b/mm/percpu-internal.h
> index 18b768ac7dca..095d7eaa0db4 100644
> --- a/mm/percpu-internal.h
> +++ b/mm/percpu-internal.h
> @@ -87,7 +87,7 @@ extern spinlock_t pcpu_lock;
>  
>  extern struct list_head *pcpu_chunk_lists;
>  extern int pcpu_nr_slots;
> -extern int pcpu_nr_empty_pop_pages;
> +extern int pcpu_nr_empty_pop_pages[];
>  
>  extern struct pcpu_chunk *pcpu_first_chunk;
>  extern struct pcpu_chunk *pcpu_reserved_chunk;
> diff --git a/mm/percpu-stats.c b/mm/percpu-stats.c
> index c8400a2adbc2..f6026dbcdf6b 100644
> --- a/mm/percpu-stats.c
> +++ b/mm/percpu-stats.c
> @@ -145,6 +145,7 @@ static int percpu_stats_show(struct seq_file *m, void *v)
>   int slot, max_nr_alloc;
>   int *buffer;
>   enum pcpu_chunk_type type;
> + int nr_empty_pop_pages;
>  
>  alloc_buffer:
>   spin_lock_irq(&pcpu_lock);
> @@ -165,7 +166,11 @@ static int percpu_stats_show(struct seq_file *m, void *v)
>   goto alloc_buffer;
>   }
>  
> -#define PL(X) \
> + nr_empty_pop_pages = 0;
> + for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++)
> + nr_empty_pop_pages += pcpu_nr_empty_pop_pages[type];
> +
> +#define PL(X)
> \
>   seq_printf(m, "  %-20s: %12lld\n", #X, (long long int)pcpu_stats_ai.X)
>  
>   seq_printf(m,
> @@ -196,7 +201,7 @@ static int percpu_stats_show(struct seq_file *m, void *v)
>   PU(nr_max_chunks);
>   PU(min_alloc_size);
>   PU(max_alloc_size);
> - P("empty_pop_pages", pcpu_nr_empty_pop_pages);
> + P("empty_pop_pages", nr_empty_pop_pages);
>   seq_putc(m, '\n');
>  
>  #undef PU
> diff --git a/mm/percpu.c b/mm/percpu.c
> index 7e31e1b8725f..61339b3d9337 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -176,10 +176,10 @@ struct list_head *pcpu_chunk_lists __ro_after_init; /* 
> chunk list slots */
>  static LIST_HEAD(pcpu_map_extend_chunks);
>  
>  /*
> - * The number of empty populated pages, protected by pcpu_lock.  The
> - * reserved chunk doesn't contribute to the count.
> + * The number of empty populated pages by chunk type, protected by pcpu_lock.
> + * The reserved chunk doesn't contribute to the count.
>   */
> -int pcpu_nr_empty_pop_pages;
> +int pcpu_nr_empty_pop_pages[PCPU_NR_CHUNK_TYPES];
>  
>  /*
>   * The number of populated pages in use by the allocator, protected by
> @@ -559,7 +559,7 @@ static inline void pcpu_update_empty_pages(struct 
> pcpu_chunk *chunk, int nr)
>  {
>   chunk->nr_empty_pop_pages += nr;
>   if (chunk != pcpu_reserved_chunk)
> - pcpu_nr_empty_pop_pages += nr;
> + pcpu_nr_empty_pop_pages[pcpu_chunk_type(chunk)] += nr;
>  }
>  
>  /*
> @@ -1835,7 +1835,7 @@ static void __percpu *pcpu_alloc(size_t size, size_t 
> align, bool reserved,
>   mutex_unlock(&pcpu_alloc_mutex);
>   }
>  
> - if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_LOW)
> + if (pcpu_nr_empty_pop_pages[type] < PCPU_EMPTY_POP_PAGES_LOW)
>   pcpu_schedule_balance_work();
>  
>   /* clear the areas and return address relative to base address */
> @@ -2013,7 +2013,7 @@ static void pcpu_balance_populated(enum pcpu_chunk_type 
> type)
>   pcpu_atomic_alloc_failed = false;
>   } else {
>   nr_to_pop = clamp(PCPU_EMPTY_POP_PAGES_HIGH -
> -   pcpu_nr_empty_pop_pages,
> +   pcpu_nr_empty_pop_pages[type],
> 0, PCPU_EMPTY_POP_PAGES_HIGH);
>   }
>  
> @@ -2595,7 +2595,7 @@ void __init pcpu_setup_first_chunk(const struct 
> pcpu_alloc_info *ai,
>  
>   /* link the first chunk in */
>   pcpu_first_chunk = chunk;
> - pcpu_nr_empty_pop_pages = pcpu_first_chunk->nr_empty_pop_pages;
> + pcpu_nr_empty_pop_pages[PCPU_CHUNK_ROOT] = 
> pcpu_first_chunk->nr_empty_pop_pages;
>   pcpu_chunk_relocate(pcpu_first_chunk, -1);
>  
>   /* include all regions of the first chunk */
> -- 
> 2.30.2
> 

This turns out to have been a more pressing issue. Thanks for fixing
this. I ran this to Linus for v5.12-rc7 [1].

https://lore.kernel.org/lkml/yhhs618esvkhy...@google.com/

Thanks,
Dennis


Re: [PATCH v3 2/6] percpu: split __pcpu_balance_workfn()

2021-04-16 Thread Dennis Zhou
Hello,

On Wed, Apr 07, 2021 at 08:57:32PM -0700, Roman Gushchin wrote:
> __pcpu_balance_workfn() became fairly big and hard to follow, but in
> fact it consists of two fully independent parts, responsible for
> the destruction of excessive free chunks and population of necessarily
> amount of free pages.
> 
> In order to simplify the code and prepare for adding of a new
> functionality, split it in two functions:
> 
>   1) pcpu_balance_free,
>   2) pcpu_balance_populated.
> 
> Move the taking/releasing of the pcpu_alloc_mutex to an upper level
> to keep the current synchronization in place.
> 
> Signed-off-by: Roman Gushchin 
> Reviewed-by: Dennis Zhou 
> ---
>  mm/percpu.c | 46 +-
>  1 file changed, 29 insertions(+), 17 deletions(-)
> 
> diff --git a/mm/percpu.c b/mm/percpu.c
> index 2f27123bb489..7e31e1b8725f 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -1933,31 +1933,22 @@ void __percpu *__alloc_reserved_percpu(size_t size, 
> size_t align)
>  }
>  
>  /**
> - * __pcpu_balance_workfn - manage the amount of free chunks and populated 
> pages
> + * pcpu_balance_free - manage the amount of free chunks
>   * @type: chunk type
>   *
> - * Reclaim all fully free chunks except for the first one.  This is also
> - * responsible for maintaining the pool of empty populated pages.  However,
> - * it is possible that this is called when physical memory is scarce causing
> - * OOM killer to be triggered.  We should avoid doing so until an actual
> - * allocation causes the failure as it is possible that requests can be
> - * serviced from already backed regions.
> + * Reclaim all fully free chunks except for the first one.
>   */
> -static void __pcpu_balance_workfn(enum pcpu_chunk_type type)
> +static void pcpu_balance_free(enum pcpu_chunk_type type)
>  {
> - /* gfp flags passed to underlying allocators */
> - const gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
>   LIST_HEAD(to_free);
>   struct list_head *pcpu_slot = pcpu_chunk_list(type);
>   struct list_head *free_head = &pcpu_slot[pcpu_nr_slots - 1];
>   struct pcpu_chunk *chunk, *next;
> - int slot, nr_to_pop, ret;
>  
>   /*
>* There's no reason to keep around multiple unused chunks and VM
>* areas can be scarce.  Destroy all free chunks except for one.
>*/
> - mutex_lock(&pcpu_alloc_mutex);
>   spin_lock_irq(&pcpu_lock);
>  
>   list_for_each_entry_safe(chunk, next, free_head, list) {
> @@ -1985,6 +1976,25 @@ static void __pcpu_balance_workfn(enum pcpu_chunk_type 
> type)
>   pcpu_destroy_chunk(chunk);
>   cond_resched();
>   }
> +}
> +
> +/**
> + * pcpu_balance_populated - manage the amount of populated pages
> + * @type: chunk type
> + *
> + * Maintain a certain amount of populated pages to satisfy atomic 
> allocations.
> + * It is possible that this is called when physical memory is scarce causing
> + * OOM killer to be triggered.  We should avoid doing so until an actual
> + * allocation causes the failure as it is possible that requests can be
> + * serviced from already backed regions.
> + */
> +static void pcpu_balance_populated(enum pcpu_chunk_type type)
> +{
> + /* gfp flags passed to underlying allocators */
> + const gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
> + struct list_head *pcpu_slot = pcpu_chunk_list(type);
> + struct pcpu_chunk *chunk;
> + int slot, nr_to_pop, ret;
>  
>   /*
>* Ensure there are certain number of free populated pages for
> @@ -2054,22 +2064,24 @@ static void __pcpu_balance_workfn(enum 
> pcpu_chunk_type type)
>   goto retry_pop;
>   }
>   }
> -
> - mutex_unlock(&pcpu_alloc_mutex);
>  }
>  
>  /**
>   * pcpu_balance_workfn - manage the amount of free chunks and populated pages
>   * @work: unused
>   *
> - * Call __pcpu_balance_workfn() for each chunk type.
> + * Call pcpu_balance_free() and pcpu_balance_populated() for each chunk type.
>   */
>  static void pcpu_balance_workfn(struct work_struct *work)
>  {
>   enum pcpu_chunk_type type;
>  
> - for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++)
> - __pcpu_balance_workfn(type);
> + for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++) {
> + mutex_lock(&pcpu_alloc_mutex);
> + pcpu_balance_free(type);
> + pcpu_balance_populated(type);
> + mutex_unlock(&pcpu_alloc_mutex);
> + }
>  }
>  
>  /**
> -- 
> 2.30.2
> 
> 

I've applied this to for-5.14.

Thanks,
Dennis


Re: [PATCH v3 1/6] percpu: fix a comment about the chunks ordering

2021-04-16 Thread Dennis Zhou
Hello,

On Wed, Apr 07, 2021 at 08:57:31PM -0700, Roman Gushchin wrote:
> Since the commit 3e54097beb22 ("percpu: manage chunks based on
> contig_bits instead of free_bytes") chunks are sorted based on the
> size of the biggest continuous free area instead of the total number
> of free bytes. Update the corresponding comment to reflect this.
> 
> Signed-off-by: Roman Gushchin 
> ---
>  mm/percpu.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/mm/percpu.c b/mm/percpu.c
> index 6596a0a4286e..2f27123bb489 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -99,7 +99,10 @@
>  
>  #include "percpu-internal.h"
>  
> -/* the slots are sorted by free bytes left, 1-31 bytes share the same slot */
> +/*
> + * The slots are sorted by the size of the biggest continuous free area.
> + * 1-31 bytes share the same slot.
> + */
>  #define PCPU_SLOT_BASE_SHIFT 5
>  /* chunks in slots below this are subject to being sidelined on failed alloc 
> */
>  #define PCPU_SLOT_FAIL_THRESHOLD 3
> -- 
> 2.30.2
> 

I've applied this to for-5.14.

Thanks,
Dennis


Re: [PATCH v3 0/6] percpu: partial chunk depopulation

2021-04-16 Thread Dennis Zhou
> > v1:
> >- depopulation heuristics changed and optimized
> >- chunks are put into a separate list, depopulation scan this list
> >- chunk->isolated is introduced, chunk->depopulate is dropped
> >- rearranged patches a bit
> >- fixed a panic discovered by krobot
> >- made pcpu_nr_empty_pop_pages per chunk type
> >- minor fixes
> > 
> > rfc:
> >https://lwn.net/Articles/850508/
> > 
> > 
> > Roman Gushchin (6):
> >percpu: fix a comment about the chunks ordering
> >percpu: split __pcpu_balance_workfn()
> >percpu: make pcpu_nr_empty_pop_pages per chunk type
> >percpu: generalize pcpu_balance_populated()
> >percpu: factor out pcpu_check_chunk_hint()
> >percpu: implement partial chunk depopulation
> > 
> >   mm/percpu-internal.h |   4 +-
> >   mm/percpu-stats.c|   9 +-
> >   mm/percpu.c  | 306 +++
> >   3 files changed, 261 insertions(+), 58 deletions(-)
> > 
> 

Roman, sorry for the delay. I'm looking to apply this today to for-5.14.

Thanks,
Dennis


Re: [PATCH 1/5] mm/swapfile: add percpu_ref support for swap

2021-04-15 Thread Dennis Zhou
On Thu, Apr 15, 2021 at 01:24:31PM +0800, Huang, Ying wrote:
> Dennis Zhou  writes:
> 
> > On Wed, Apr 14, 2021 at 01:44:58PM +0800, Huang, Ying wrote:
> >> Dennis Zhou  writes:
> >> 
> >> > On Wed, Apr 14, 2021 at 11:59:03AM +0800, Huang, Ying wrote:
> >> >> Dennis Zhou  writes:
> >> >> 
> >> >> > Hello,
> >> >> >
> >> >> > On Wed, Apr 14, 2021 at 10:06:48AM +0800, Huang, Ying wrote:
> >> >> >> Miaohe Lin  writes:
> >> >> >> 
> >> >> >> > On 2021/4/14 9:17, Huang, Ying wrote:
> >> >> >> >> Miaohe Lin  writes:
> >> >> >> >> 
> >> >> >> >>> On 2021/4/12 15:24, Huang, Ying wrote:
> >> >> >> >>>> "Huang, Ying"  writes:
> >> >> >> >>>>
> >> >> >> >>>>> Miaohe Lin  writes:
> >> >> >> >>>>>
> >> >> >> >>>>>> We will use percpu-refcount to serialize against concurrent 
> >> >> >> >>>>>> swapoff. This
> >> >> >> >>>>>> patch adds the percpu_ref support for later fixup.
> >> >> >> >>>>>>
> >> >> >> >>>>>> Signed-off-by: Miaohe Lin 
> >> >> >> >>>>>> ---
> >> >> >> >>>>>>  include/linux/swap.h |  2 ++
> >> >> >> >>>>>>  mm/swapfile.c| 25 ++---
> >> >> >> >>>>>>  2 files changed, 24 insertions(+), 3 deletions(-)
> >> >> >> >>>>>>
> >> >> >> >>>>>> diff --git a/include/linux/swap.h b/include/linux/swap.h
> >> >> >> >>>>>> index 144727041e78..849ba5265c11 100644
> >> >> >> >>>>>> --- a/include/linux/swap.h
> >> >> >> >>>>>> +++ b/include/linux/swap.h
> >> >> >> >>>>>> @@ -240,6 +240,7 @@ struct swap_cluster_list {
> >> >> >> >>>>>>   * The in-memory structure used to track swap areas.
> >> >> >> >>>>>>   */
> >> >> >> >>>>>>  struct swap_info_struct {
> >> >> >> >>>>>> + struct percpu_ref users;/* serialization 
> >> >> >> >>>>>> against concurrent swapoff */
> >> >> >> >>>>>>   unsigned long   flags;  /* SWP_USED etc: see 
> >> >> >> >>>>>> above */
> >> >> >> >>>>>>   signed shortprio;   /* swap priority of 
> >> >> >> >>>>>> this type */
> >> >> >> >>>>>>   struct plist_node list; /* entry in 
> >> >> >> >>>>>> swap_active_head */
> >> >> >> >>>>>> @@ -260,6 +261,7 @@ struct swap_info_struct {
> >> >> >> >>>>>>   struct block_device *bdev;  /* swap device or bdev 
> >> >> >> >>>>>> of swap file */
> >> >> >> >>>>>>   struct file *swap_file; /* seldom referenced */
> >> >> >> >>>>>>   unsigned int old_block_size;/* seldom referenced */
> >> >> >> >>>>>> + struct completion comp; /* seldom referenced */
> >> >> >> >>>>>>  #ifdef CONFIG_FRONTSWAP
> >> >> >> >>>>>>   unsigned long *frontswap_map;   /* frontswap in-use, 
> >> >> >> >>>>>> one bit per page */
> >> >> >> >>>>>>   atomic_t frontswap_pages;   /* frontswap pages 
> >> >> >> >>>>>> in-use counter */
> >> >> >> >>>>>> diff --git a/mm/swapfile.c b/mm/swapfile.c
> >> >> >> >>>>>> index 149e77454e3c..724173cd7d0c 100644
> >> >> >> >>>>>> --- a/mm/swapfile.c
> >> >> >> >>>>>> +++ b/mm/swapfile.c
> >> >> >> >>>>>>

Re: [PATCH 1/5] mm/swapfile: add percpu_ref support for swap

2021-04-14 Thread Dennis Zhou
On Thu, Apr 15, 2021 at 11:16:42AM +0800, Miaohe Lin wrote:
> On 2021/4/14 22:53, Dennis Zhou wrote:
> > On Wed, Apr 14, 2021 at 01:44:58PM +0800, Huang, Ying wrote:
> >> Dennis Zhou  writes:
> >>
> >>> On Wed, Apr 14, 2021 at 11:59:03AM +0800, Huang, Ying wrote:
> >>>> Dennis Zhou  writes:
> >>>>
> >>>>> Hello,
> >>>>>
> >>>>> On Wed, Apr 14, 2021 at 10:06:48AM +0800, Huang, Ying wrote:
> >>>>>> Miaohe Lin  writes:
> >>>>>>
> >>>>>>> On 2021/4/14 9:17, Huang, Ying wrote:
> >>>>>>>> Miaohe Lin  writes:
> >>>>>>>>
> >>>>>>>>> On 2021/4/12 15:24, Huang, Ying wrote:
> >>>>>>>>>> "Huang, Ying"  writes:
> >>>>>>>>>>
> >>>>>>>>>>> Miaohe Lin  writes:
> >>>>>>>>>>>
> >>>>>>>>>>>> We will use percpu-refcount to serialize against concurrent 
> >>>>>>>>>>>> swapoff. This
> >>>>>>>>>>>> patch adds the percpu_ref support for later fixup.
> >>>>>>>>>>>>
> >>>>>>>>>>>> Signed-off-by: Miaohe Lin 
> >>>>>>>>>>>> ---
> >>>>>>>>>>>>  include/linux/swap.h |  2 ++
> >>>>>>>>>>>>  mm/swapfile.c| 25 ++---
> >>>>>>>>>>>>  2 files changed, 24 insertions(+), 3 deletions(-)
> >>>>>>>>>>>>
> >>>>>>>>>>>> diff --git a/include/linux/swap.h b/include/linux/swap.h
> >>>>>>>>>>>> index 144727041e78..849ba5265c11 100644
> >>>>>>>>>>>> --- a/include/linux/swap.h
> >>>>>>>>>>>> +++ b/include/linux/swap.h
> >>>>>>>>>>>> @@ -240,6 +240,7 @@ struct swap_cluster_list {
> >>>>>>>>>>>>   * The in-memory structure used to track swap areas.
> >>>>>>>>>>>>   */
> >>>>>>>>>>>>  struct swap_info_struct {
> >>>>>>>>>>>> +struct percpu_ref users;/* serialization 
> >>>>>>>>>>>> against concurrent swapoff */
> >>>>>>>>>>>>  unsigned long   flags;  /* SWP_USED etc: see 
> >>>>>>>>>>>> above */
> >>>>>>>>>>>>  signed shortprio;   /* swap priority of 
> >>>>>>>>>>>> this type */
> >>>>>>>>>>>>  struct plist_node list; /* entry in 
> >>>>>>>>>>>> swap_active_head */
> >>>>>>>>>>>> @@ -260,6 +261,7 @@ struct swap_info_struct {
> >>>>>>>>>>>>  struct block_device *bdev;  /* swap device or bdev 
> >>>>>>>>>>>> of swap file */
> >>>>>>>>>>>>  struct file *swap_file; /* seldom referenced */
> >>>>>>>>>>>>  unsigned int old_block_size;/* seldom referenced */
> >>>>>>>>>>>> +struct completion comp; /* seldom referenced */
> >>>>>>>>>>>>  #ifdef CONFIG_FRONTSWAP
> >>>>>>>>>>>>  unsigned long *frontswap_map;   /* frontswap in-use, 
> >>>>>>>>>>>> one bit per page */
> >>>>>>>>>>>>  atomic_t frontswap_pages;   /* frontswap pages 
> >>>>>>>>>>>> in-use counter */
> >>>>>>>>>>>> diff --git a/mm/swapfile.c b/mm/swapfile.c
> >>>>>>>>>>>> index 149e77454e3c..724173cd7d0c 100644
> >>>>>>>>>>>> --- a/mm/swapfile.c
> >>>>>>>>>>>> +++ b/mm/swapfile.c
> >>>>>>>>>>>> @@ -39,6 +39,7 @@
> >>>>>>>>>>>>  #include 
> >>>>>>>>

Re: [PATCH 1/5] mm/swapfile: add percpu_ref support for swap

2021-04-14 Thread Dennis Zhou
On Wed, Apr 14, 2021 at 01:44:58PM +0800, Huang, Ying wrote:
> Dennis Zhou  writes:
> 
> > On Wed, Apr 14, 2021 at 11:59:03AM +0800, Huang, Ying wrote:
> >> Dennis Zhou  writes:
> >> 
> >> > Hello,
> >> >
> >> > On Wed, Apr 14, 2021 at 10:06:48AM +0800, Huang, Ying wrote:
> >> >> Miaohe Lin  writes:
> >> >> 
> >> >> > On 2021/4/14 9:17, Huang, Ying wrote:
> >> >> >> Miaohe Lin  writes:
> >> >> >> 
> >> >> >>> On 2021/4/12 15:24, Huang, Ying wrote:
> >> >> >>>> "Huang, Ying"  writes:
> >> >> >>>>
> >> >> >>>>> Miaohe Lin  writes:
> >> >> >>>>>
> >> >> >>>>>> We will use percpu-refcount to serialize against concurrent 
> >> >> >>>>>> swapoff. This
> >> >> >>>>>> patch adds the percpu_ref support for later fixup.
> >> >> >>>>>>
> >> >> >>>>>> Signed-off-by: Miaohe Lin 
> >> >> >>>>>> ---
> >> >> >>>>>>  include/linux/swap.h |  2 ++
> >> >> >>>>>>  mm/swapfile.c| 25 ++---
> >> >> >>>>>>  2 files changed, 24 insertions(+), 3 deletions(-)
> >> >> >>>>>>
> >> >> >>>>>> diff --git a/include/linux/swap.h b/include/linux/swap.h
> >> >> >>>>>> index 144727041e78..849ba5265c11 100644
> >> >> >>>>>> --- a/include/linux/swap.h
> >> >> >>>>>> +++ b/include/linux/swap.h
> >> >> >>>>>> @@ -240,6 +240,7 @@ struct swap_cluster_list {
> >> >> >>>>>>   * The in-memory structure used to track swap areas.
> >> >> >>>>>>   */
> >> >> >>>>>>  struct swap_info_struct {
> >> >> >>>>>> +struct percpu_ref users;/* serialization 
> >> >> >>>>>> against concurrent swapoff */
> >> >> >>>>>>  unsigned long   flags;  /* SWP_USED etc: see 
> >> >> >>>>>> above */
> >> >> >>>>>>  signed shortprio;   /* swap priority of 
> >> >> >>>>>> this type */
> >> >> >>>>>>  struct plist_node list; /* entry in 
> >> >> >>>>>> swap_active_head */
> >> >> >>>>>> @@ -260,6 +261,7 @@ struct swap_info_struct {
> >> >> >>>>>>  struct block_device *bdev;  /* swap device or bdev 
> >> >> >>>>>> of swap file */
> >> >> >>>>>>  struct file *swap_file; /* seldom referenced */
> >> >> >>>>>>  unsigned int old_block_size;/* seldom referenced */
> >> >> >>>>>> +struct completion comp; /* seldom referenced */
> >> >> >>>>>>  #ifdef CONFIG_FRONTSWAP
> >> >> >>>>>>  unsigned long *frontswap_map;   /* frontswap in-use, 
> >> >> >>>>>> one bit per page */
> >> >> >>>>>>  atomic_t frontswap_pages;   /* frontswap pages 
> >> >> >>>>>> in-use counter */
> >> >> >>>>>> diff --git a/mm/swapfile.c b/mm/swapfile.c
> >> >> >>>>>> index 149e77454e3c..724173cd7d0c 100644
> >> >> >>>>>> --- a/mm/swapfile.c
> >> >> >>>>>> +++ b/mm/swapfile.c
> >> >> >>>>>> @@ -39,6 +39,7 @@
> >> >> >>>>>>  #include 
> >> >> >>>>>>  #include 
> >> >> >>>>>>  #include 
> >> >> >>>>>> +#include 
> >> >> >>>>>>  
> >> >> >>>>>>  #include 
> >> >> >>>>>>  #include 
> >> >> >>>>>> @@ -511,6 +512,15 @@ static void swap_discard_work(struct 
> >> >> >>>>>> work_struct *work)

Re: [PATCH 1/5] mm/swapfile: add percpu_ref support for swap

2021-04-13 Thread Dennis Zhou
On Wed, Apr 14, 2021 at 11:59:03AM +0800, Huang, Ying wrote:
> Dennis Zhou  writes:
> 
> > Hello,
> >
> > On Wed, Apr 14, 2021 at 10:06:48AM +0800, Huang, Ying wrote:
> >> Miaohe Lin  writes:
> >> 
> >> > On 2021/4/14 9:17, Huang, Ying wrote:
> >> >> Miaohe Lin  writes:
> >> >> 
> >> >>> On 2021/4/12 15:24, Huang, Ying wrote:
> >> >>>> "Huang, Ying"  writes:
> >> >>>>
> >> >>>>> Miaohe Lin  writes:
> >> >>>>>
> >> >>>>>> We will use percpu-refcount to serialize against concurrent 
> >> >>>>>> swapoff. This
> >> >>>>>> patch adds the percpu_ref support for later fixup.
> >> >>>>>>
> >> >>>>>> Signed-off-by: Miaohe Lin 
> >> >>>>>> ---
> >> >>>>>>  include/linux/swap.h |  2 ++
> >> >>>>>>  mm/swapfile.c| 25 ++---
> >> >>>>>>  2 files changed, 24 insertions(+), 3 deletions(-)
> >> >>>>>>
> >> >>>>>> diff --git a/include/linux/swap.h b/include/linux/swap.h
> >> >>>>>> index 144727041e78..849ba5265c11 100644
> >> >>>>>> --- a/include/linux/swap.h
> >> >>>>>> +++ b/include/linux/swap.h
> >> >>>>>> @@ -240,6 +240,7 @@ struct swap_cluster_list {
> >> >>>>>>   * The in-memory structure used to track swap areas.
> >> >>>>>>   */
> >> >>>>>>  struct swap_info_struct {
> >> >>>>>> +   struct percpu_ref users;/* serialization against 
> >> >>>>>> concurrent swapoff */
> >> >>>>>> unsigned long   flags;  /* SWP_USED etc: see above */
> >> >>>>>> signed shortprio;   /* swap priority of this type */
> >> >>>>>> struct plist_node list; /* entry in swap_active_head */
> >> >>>>>> @@ -260,6 +261,7 @@ struct swap_info_struct {
> >> >>>>>> struct block_device *bdev;  /* swap device or bdev of swap 
> >> >>>>>> file */
> >> >>>>>> struct file *swap_file; /* seldom referenced */
> >> >>>>>> unsigned int old_block_size;/* seldom referenced */
> >> >>>>>> +   struct completion comp; /* seldom referenced */
> >> >>>>>>  #ifdef CONFIG_FRONTSWAP
> >> >>>>>> unsigned long *frontswap_map;   /* frontswap in-use, one bit 
> >> >>>>>> per page */
> >> >>>>>> atomic_t frontswap_pages;   /* frontswap pages in-use 
> >> >>>>>> counter */
> >> >>>>>> diff --git a/mm/swapfile.c b/mm/swapfile.c
> >> >>>>>> index 149e77454e3c..724173cd7d0c 100644
> >> >>>>>> --- a/mm/swapfile.c
> >> >>>>>> +++ b/mm/swapfile.c
> >> >>>>>> @@ -39,6 +39,7 @@
> >> >>>>>>  #include 
> >> >>>>>>  #include 
> >> >>>>>>  #include 
> >> >>>>>> +#include 
> >> >>>>>>  
> >> >>>>>>  #include 
> >> >>>>>>  #include 
> >> >>>>>> @@ -511,6 +512,15 @@ static void swap_discard_work(struct 
> >> >>>>>> work_struct *work)
> >> >>>>>> spin_unlock(&si->lock);
> >> >>>>>>  }
> >> >>>>>>  
> >> >>>>>> +static void swap_users_ref_free(struct percpu_ref *ref)
> >> >>>>>> +{
> >> >>>>>> +   struct swap_info_struct *si;
> >> >>>>>> +
> >> >>>>>> +   si = container_of(ref, struct swap_info_struct, users);
> >> >>>>>> +   complete(&si->comp);
> >> >>>>>> +   percpu_ref_exit(&si->users);
> >> >>>>>
> >> >>>>> Because percpu_ref_exit() is used, we cannot use percpu_ref_tryget() 
> >> >>>>> in
> >> >>>>> 

Re: [PATCH 1/5] mm/swapfile: add percpu_ref support for swap

2021-04-13 Thread Dennis Zhou
 I read 
> >>> the
> >>> implementation code of the percpu_ref and found percpu_ref_tryget_live() 
> >>> could
> >>> be called after exit now. But you're right we need to follow the API 
> >>> definition
> >>> to avoid potential issues in the long term.
> >>>
> >>>>
> >>>> And we need to call percpu_ref_init() before insert the swap_info_struct
> >>>> into the swap_info[].
> >>>
> >>> If we remove the call to percpu_ref_exit(), we should not use 
> >>> percpu_ref_init()
> >>> here because *percpu_ref->data is assumed to be NULL* in 
> >>> percpu_ref_init() while
> >>> this is not the case as we do not call percpu_ref_exit(). Maybe 
> >>> percpu_ref_reinit()
> >>> or percpu_ref_resurrect() will do the work.
> >>>
> >>> One more thing, how could I distinguish the killed percpu_ref from newly 
> >>> allocated one?
> >>> It seems percpu_ref_is_dying is only safe to call when @ref is between 
> >>> init and exit.
> >>> Maybe I could do this in alloc_swap_info()?
> >> 
> >> Yes.  In alloc_swap_info(), you can distinguish newly allocated and
> >> reused swap_info_struct.
> >> 
> >>>>
> >>>>>> +}
> >>>>>> +
> >>>>>>  static void alloc_cluster(struct swap_info_struct *si, unsigned long 
> >>>>>> idx)
> >>>>>>  {
> >>>>>>struct swap_cluster_info *ci = si->cluster_info;
> >>>>>> @@ -2500,7 +2510,7 @@ static void enable_swap_info(struct 
> >>>>>> swap_info_struct *p, int prio,
> >>>>>> * Guarantee swap_map, cluster_info, etc. fields are valid
> >>>>>> * between get/put_swap_device() if SWP_VALID bit is set
> >>>>>> */
> >>>>>> -  synchronize_rcu();
> >>>>>> +  percpu_ref_reinit(&p->users);
> >>>>>
> >>>>> Although the effect is same, I think it's better to use
> >>>>> percpu_ref_resurrect() here to improve code readability.
> >>>>
> >>>> Check the original commit description for commit eb085574a752 "mm, swap:
> >>>> fix race between swapoff and some swap operations" and discussion email
> >>>> thread as follows again,
> >>>>
> >>>> https://lore.kernel.org/linux-mm/20171219053650.gb7...@linux.vnet.ibm.com/
> >>>>
> >>>> I found that the synchronize_rcu() here is to avoid to call smp_rmb() or
> >>>> smp_load_acquire() in get_swap_device().  Now we will use
> >>>> percpu_ref_tryget_live() in get_swap_device(), so we will need to add
> >>>> the necessary memory barrier, or make sure percpu_ref_tryget_live() has
> >>>> ACQUIRE semantics.  Per my understanding, we need to change
> >>>> percpu_ref_tryget_live() for that.
> >>>>
> >>>
> >>> Do you mean the below scene is possible?
> >>>
> >>> cpu1
> >>> swapon()
> >>>   ...
> >>>   percpu_ref_init
> >>>   ...
> >>>   setup_swap_info
> >>>   /* smp_store_release() is inside percpu_ref_reinit */
> >>>   percpu_ref_reinit
> >> 
> >> spin_unlock() has RELEASE semantics already.
> >> 
> >>>   ...
> >>>
> >>> cpu2
> >>> get_swap_device()
> >>>   /* ignored  smp_rmb() */
> >>>   percpu_ref_tryget_live
> >> 
> >> Some kind of ACQUIRE is required here to guarantee the refcount is
> >> checked before fetching the other fields of swap_info_struct.  I have
> >> sent out a RFC patch to mailing list to discuss this.

I'm just catching up and following along a little bit. I apologize I
haven't read the swap code, but my understanding is you are trying to
narrow a race condition with swapoff. That makes sense to me. I'm not
sure I follow the need to race with reinitializing the ref though? Is it
not possible to wait out the dying swap info and then create a new one
rather than push acquire semantics?

> >
> > Many thanks.
> > But We may still need to add a smp_rmb() in get_swap_device() in case
> > we can't add ACQUIRE for refcount.
> 
> Yes.
> 
> Best Regards,
> Huang, Ying
> 

Thanks,
Dennis


[GIT PULL] percpu changes for v5.12-rc7

2021-04-10 Thread Dennis Zhou
Hi Linus,

This pull request contains a fix for sporadically failing atomic percpu
allocations. I only caught it recently while I was reviewing a new
series [1] and simultaneously saw reports by btrfs in xfstests [2] and
[3].

In v5.9, memcg accounting was extended to percpu done by adding a second
type of chunk. I missed an interaction with the free page float count
used to ensure we can support atomic allocations. If 1 type of chunk has
no free pages, but the other has enough to satisfy the free page float
requirement, we will not repopulate the free pages for the former type
of chunk. This led to sporadically failing atomic allocations.

[1] https://lore.kernel.org/linux-mm/20210324190626.564297-1-g...@fb.com/
[2] https://lore.kernel.org/linux-mm/20210401185158.3275.40950...@e16-tech.com/
[3] 
https://lore.kernel.org/linux-mm/cal3q7h5rnbjci708gh7jnczaoe0blnact9c+obga-dx9jhb...@mail.gmail.com/

Thanks,
Dennis

The following changes since commit e49d033bddf5b565044e2abe4241353959bc9120:

  Linux 5.12-rc6 (2021-04-04 14:15:36 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git for-5.12-fixes

for you to fetch changes up to 0760fa3d8f7fceeea508b98899f1c826e10ffe78:

  percpu: make pcpu_nr_empty_pop_pages per chunk type (2021-04-09 13:58:38 
+)


Roman Gushchin (1):
  percpu: make pcpu_nr_empty_pop_pages per chunk type

 mm/percpu-internal.h |  2 +-
 mm/percpu-stats.c|  9 +++--
 mm/percpu.c  | 14 +++---
 3 files changed, 15 insertions(+), 10 deletions(-)


Re: linux-next: Signed-off-by missing for commit in the rdma tree

2021-04-09 Thread Dennis Dalessandro

On 4/8/2021 6:00 PM, Stephen Rothwell wrote:

Hi all,

Commit

   042a00f93aad ("IB/{ipoib,hfi1}: Add a timeout handler for rdma_netdev")

is missing a Signed-off-by from its author.


Doh! That's my fault. I must have fat fingered the delete button instead 
of editing the line when I was converting our email addresses to the new 
name.


Jason do you want a v2 of the patch?

-Denny



Re: [PATCH v2 5/5] percpu: implement partial chunk depopulation

2021-04-07 Thread Dennis Zhou
Hello,

On Wed, Apr 07, 2021 at 11:26:18AM -0700, Roman Gushchin wrote:
> This patch implements partial depopulation of percpu chunks.
> 
> As now, a chunk can be depopulated only as a part of the final
> destruction, if there are no more outstanding allocations. However
> to minimize a memory waste it might be useful to depopulate a
> partially filed chunk, if a small number of outstanding allocations
> prevents the chunk from being fully reclaimed.
> 
> This patch implements the following depopulation process: it scans
> over the chunk pages, looks for a range of empty and populated pages
> and performs the depopulation. To avoid races with new allocations,
> the chunk is previously isolated. After the depopulation the chunk is
> sidelined to a special list or freed. New allocations can't be served
> using a sidelined chunk. The chunk can be moved back to a corresponding
> slot if there are not enough chunks with empty populated pages.
> 
> The depopulation is scheduled on the free path. Is the chunk:
>   1) has more than 1/4 of total pages free and populated
>   2) the system has enough free percpu pages aside of this chunk
>   3) isn't the reserved chunk
>   4) isn't the first chunk
>   5) isn't entirely free
> it's a good target for depopulation. If it's already depopulated
> but got free populated pages, it's a good target too.
> The chunk is moved to a special pcpu_depopulate_list, chunk->isolate
> flag is set and the async balancing is scheduled.
> 
> The async balancing moves pcpu_depopulate_list to a local list
> (because pcpu_depopulate_list can be changed when pcpu_lock is
> releases), and then tries to depopulate each chunk.  The depopulation
> is performed in the reverse direction to keep populated pages close to
> the beginning, if the global number of empty pages is reached.
> Depopulated chunks are sidelined to prevent further allocations.
> Skipped and fully empty chunks are returned to the corresponding slot.
> 
> On the allocation path, if there are no suitable chunks found,
> the list of sidelined chunks in scanned prior to creating a new chunk.
> If there is a good sidelined chunk, it's placed back to the slot
> and the scanning is restarted.
> 
> Many thanks to Dennis Zhou for his great ideas and a very constructive
> discussion which led to many improvements in this patchset!
> 
> Signed-off-by: Roman Gushchin 
> ---
>  mm/percpu-internal.h |   2 +
>  mm/percpu.c  | 164 ++-
>  2 files changed, 164 insertions(+), 2 deletions(-)
> 
> diff --git a/mm/percpu-internal.h b/mm/percpu-internal.h
> index 095d7eaa0db4..8e432663c41e 100644
> --- a/mm/percpu-internal.h
> +++ b/mm/percpu-internal.h
> @@ -67,6 +67,8 @@ struct pcpu_chunk {
>  
>   void*data;  /* chunk data */
>   boolimmutable;  /* no [de]population allowed */
> + boolisolated;   /* isolated from chunk slot 
> lists */
> + booldepopulated;/* sidelined after depopulation 
> */
>   int start_offset;   /* the overlap with the previous
>  region to have a page aligned
>  base_addr */
> diff --git a/mm/percpu.c b/mm/percpu.c
> index e20119668c42..0a5a5e84e0a4 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -181,6 +181,19 @@ static LIST_HEAD(pcpu_map_extend_chunks);
>   */
>  int pcpu_nr_empty_pop_pages[PCPU_NR_CHUNK_TYPES];
>  
> +/*
> + * List of chunks with a lot of free pages.  Used to depopulate them
> + * asynchronously.
> + */
> +static struct list_head pcpu_depopulate_list[PCPU_NR_CHUNK_TYPES];
> +
> +/*
> + * List of previously depopulated chunks.  They are not usually used for new
> + * allocations, but can be returned back to service if a need arises.
> + */
> +static struct list_head pcpu_sideline_list[PCPU_NR_CHUNK_TYPES];
> +
> +
>  /*
>   * The number of populated pages in use by the allocator, protected by
>   * pcpu_lock.  This number is kept per a unit per chunk (i.e. when a page 
> gets
> @@ -542,6 +555,12 @@ static void pcpu_chunk_relocate(struct pcpu_chunk 
> *chunk, int oslot)
>  {
>   int nslot = pcpu_chunk_slot(chunk);
>  
> + /*
> +  * Keep isolated and depopulated chunks on a sideline.
> +  */
> + if (chunk->isolated || chunk->depopulated)
> + return;
> +
>   if (oslot != nslot)
>   __pcpu_chunk_move(chunk, nslot, oslot < nslot);
>  }
> @@ -1778,6 +1797,25 @@ static void __percpu *pcpu_alloc(size_t size, size_t 
> align

Re: [PATCH v1 5/5] percpu: implement partial chunk depopulation

2021-04-05 Thread Dennis Zhou
On Thu, Apr 01, 2021 at 02:43:01PM -0700, Roman Gushchin wrote:
> This patch implements partial depopulation of percpu chunks.
> 
> As now, a chunk can be depopulated only as a part of the final
> destruction, if there are no more outstanding allocations. However
> to minimize a memory waste it might be useful to depopulate a
> partially filed chunk, if a small number of outstanding allocations
> prevents the chunk from being fully reclaimed.
> 
> This patch implements the following depopulation process: it scans
> over the chunk pages, looks for a range of empty and populated pages
> and performs the depopulation. To avoid races with new allocations,
> the chunk is previously isolated. After the depopulation the chunk is
> returned to the original slot (but is appended to the tail of the list
> to minimize the chances of population).
> 
> Because the pcpu_lock is dropped while calling pcpu_depopulate_chunk(),
> the chunk can be concurrently moved to a different slot. To prevent
> this, bool chunk->isolated flag is introduced. If set, the chunk can't
> be moved to a different slot.
> 
> The depopulation is scheduled on the free path. Is the chunk:
>   1) has more than 1/8 of total pages free and populated
>   2) the system has enough free percpu pages aside of this chunk
>   3) isn't the reserved chunk
>   4) isn't the first chunk
>   5) isn't entirely free
> it's a good target for depopulation.
> 
> If so, the chunk is moved to a special pcpu_depopulate_list,
> chunk->isolate flag is set and the async balancing is scheduled.
> 
> The async balancing moves pcpu_depopulate_list to a local list
> (because pcpu_depopulate_list can be changed when pcpu_lock is
> releases), and then tries to depopulate each chunk. Successfully
> or not, at the end all chunks are returned to appropriate slots
> and their isolated flags are cleared.
> 
> Many thanks to Dennis Zhou for his great ideas and a very constructive
> discussion which led to many improvements in this patchset!
> 
> Signed-off-by: Roman Gushchin 
> ---
>  mm/percpu-internal.h |   1 +
>  mm/percpu.c  | 101 ++-
>  2 files changed, 100 insertions(+), 2 deletions(-)
> 
> diff --git a/mm/percpu-internal.h b/mm/percpu-internal.h
> index 095d7eaa0db4..ff318752915d 100644
> --- a/mm/percpu-internal.h
> +++ b/mm/percpu-internal.h
> @@ -67,6 +67,7 @@ struct pcpu_chunk {
>  
>   void*data;  /* chunk data */
>   boolimmutable;  /* no [de]population allowed */
> + boolisolated;   /* isolated from chunk slot 
> lists */
>   int start_offset;   /* the overlap with the previous
>  region to have a page aligned
>  base_addr */
> diff --git a/mm/percpu.c b/mm/percpu.c
> index e20119668c42..dae0b870e10a 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -181,6 +181,12 @@ static LIST_HEAD(pcpu_map_extend_chunks);
>   */
>  int pcpu_nr_empty_pop_pages[PCPU_NR_CHUNK_TYPES];
>  
> +/*
> + * List of chunks with a lot of free pages. Used to depopulate them
> + * asynchronously.
> + */
> +static LIST_HEAD(pcpu_depopulate_list);
> +

Now that pcpu_nr_empty_pop_pages is per chunk_type I think the
depopulate_list should be per chunk_type.

>  /*
>   * The number of populated pages in use by the allocator, protected by
>   * pcpu_lock.  This number is kept per a unit per chunk (i.e. when a page 
> gets
> @@ -542,7 +548,7 @@ static void pcpu_chunk_relocate(struct pcpu_chunk *chunk, 
> int oslot)
>  {
>   int nslot = pcpu_chunk_slot(chunk);
>  
> - if (oslot != nslot)
> + if (!chunk->isolated && oslot != nslot)
>   __pcpu_chunk_move(chunk, nslot, oslot < nslot);
>  }
>  
> @@ -2048,6 +2054,82 @@ static void pcpu_grow_populated(enum pcpu_chunk_type 
> type, int nr_to_pop)
>   }
>  }
>  
> +/**
> + * pcpu_shrink_populated - scan chunks and release unused pages to the system
> + * @type: chunk type
> + *
> + * Scan over all chunks, find those marked with the depopulate flag and
> + * try to release unused pages to the system. On every attempt clear the
> + * chunk's depopulate flag to avoid wasting CPU by scanning the same
> + * chunk again and again.
> + */

There no longer is a depopulate flag.

> +static void pcpu_shrink_populated(enum pcpu_chunk_type type)
> +{
> + struct pcpu_block_md *block;
> + struct pcpu_chunk *chunk, *tmp;
> + LIST_HEAD(to_depopulate);
> + int i, start;
> +
> + spin_lock_irq(&pcpu_lock

Re: [PATCH rfc 3/4] percpu: on demand chunk depopulation

2021-03-29 Thread Dennis Zhou
On Mon, Mar 29, 2021 at 01:10:10PM -0700, Roman Gushchin wrote:
> On Mon, Mar 29, 2021 at 07:21:24PM +0000, Dennis Zhou wrote:
> > On Wed, Mar 24, 2021 at 12:06:25PM -0700, Roman Gushchin wrote:
> > > To return unused memory to the system schedule an async
> > > depopulation of percpu chunks.
> > > 
> > > To balance between scanning too much and creating an overhead because
> > > of the pcpu_lock contention and scanning not enough, let's track an
> > > amount of chunks to scan and mark chunks which are potentially a good
> > > target for the depopulation with a new boolean flag.  The async
> > > depopulation work will clear the flag after trying to depopulate a
> > > chunk (successfully or not).
> > > 
> > > This commit suggest the following logic: if a chunk
> > >   1) has more than 1/4 of total pages free and populated
> > >   2) isn't a reserved chunk
> > >   3) isn't entirely free
> > >   4) isn't alone in the corresponding slot
> > 
> > I'm not sure I like the check for alone that much. The reason being what
> > about some odd case where each slot has a single chunk, but every slot
> > is populated. It doesn't really make sense to keep them all around.
> 
> Yeah, I agree, I'm not sure either. Maybe we can just look at the total
> number of populated empty pages and make sure it's not too low and not
> too high. Btw, we should probably double PCPU_EMPTY_POP_PAGES_LOW/HIGH
> if memcg accounting is on.
> 

Hmmm. pcpu_nr_populated and pcpu_nr_empty_pop_pages should probably be
per chunk type now that you mention it.

> > 
> > I think there is some decision making we can do here to handle packing
> > post depopulation allocations into a handful of chunks. Depopulated
> > chunks could be sidelined with say a flag ->depopulated to prevent the
> > first attempt of allocations from using them. And then we could bring
> > back a chunk 1 by 1 somehow to attempt to suffice the allocation.
> > I'm not too sure if this is a good idea, just a thought.
> 
> I thought about it in this way: depopulated chunks are not different to
> new chunks, which are not yet fully populated. And they are naturally
> de-prioritized by being located in higher slots (and at the tail of the list).
> So I'm not sure we should handle them any special.
> 

I'm thinking of the following. Imagine 3 chunks, A and B in slot X, and
C in slot X+1. If B gets depopulated followed by A getting exhausted,
which chunk B or C should be used? If C is fully populated, we might
want to use that one.

I see that the priority is chunks at the very end, but I don't want to
take something that doesn't reasonable generalize to any slot PAGE_SIZE
and up. Or it should explicitly try to tackle only say the last N slots
(but preferably the former).

> > 
> > > it's a good target for depopulation.
> > > 
> > > If there are 2 or more of such chunks, an async depopulation
> > > is scheduled.
> > > 
> > > Because chunk population and depopulation are opposite processes
> > > which make a little sense together, split out the shrinking part of
> > > pcpu_balance_populated() into pcpu_grow_populated() and make
> > > pcpu_balance_populated() calling into pcpu_grow_populated() or
> > > pcpu_shrink_populated() conditionally.
> > > 
> > > Signed-off-by: Roman Gushchin 
> > > ---
> > >  mm/percpu-internal.h |   1 +
> > >  mm/percpu.c  | 111 ---
> > >  2 files changed, 85 insertions(+), 27 deletions(-)
> > > 
> > > diff --git a/mm/percpu-internal.h b/mm/percpu-internal.h
> > > index 18b768ac7dca..1c5b92af02eb 100644
> > > --- a/mm/percpu-internal.h
> > > +++ b/mm/percpu-internal.h
> > > @@ -67,6 +67,7 @@ struct pcpu_chunk {
> > >  
> > >   void*data;  /* chunk data */
> > >   boolimmutable;  /* no [de]population allowed */
> > > + booldepopulate; /* depopulation hint */
> > >   int start_offset;   /* the overlap with the previous
> > >  region to have a page aligned
> > >  base_addr */
> > > diff --git a/mm/percpu.c b/mm/percpu.c
> > > index 015d076893f5..148137f0fc0b 100644
> > > --- a/mm/percpu.c
> > > +++ b/mm/percpu.c
> > > @@ -178,6 +178,12 @@ static LIST_HEAD(pcpu_map_extend_chunks);
> > >   */

Re: [PATCH rfc 1/4] percpu: implement partial chunk depopulation

2021-03-29 Thread Dennis Zhou
On Mon, Mar 29, 2021 at 11:29:22AM -0700, Roman Gushchin wrote:
> On Mon, Mar 29, 2021 at 05:20:55PM +0000, Dennis Zhou wrote:
> > On Wed, Mar 24, 2021 at 12:06:23PM -0700, Roman Gushchin wrote:
> > > This patch implements partial depopulation of percpu chunks.
> > > 
> > > As now, a chunk can be depopulated only as a part of the final
> > > destruction, when there are no more outstanding allocations. However
> > > to minimize a memory waste, it might be useful to depopulate a
> > > partially filed chunk, if a small number of outstanding allocations
> > > prevents the chunk from being reclaimed.
> > > 
> > > This patch implements the following depopulation process: it scans
> > > over the chunk pages, looks for a range of empty and populated pages
> > > and performs the depopulation. To avoid races with new allocations,
> > > the chunk is previously isolated. After the depopulation the chunk is
> > > returned to the original slot (but is appended to the tail of the list
> > > to minimize the chances of population).
> > > 
> > > Because the pcpu_lock is dropped while calling pcpu_depopulate_chunk(),
> > > the chunk can be concurrently moved to a different slot. So we need
> > > to isolate it again on each step. pcpu_alloc_mutex is held, so the
> > > chunk can't be populated/depopulated asynchronously.
> > > 
> > > Signed-off-by: Roman Gushchin 
> > > ---
> > >  mm/percpu.c | 90 +
> > >  1 file changed, 90 insertions(+)
> > > 
> > > diff --git a/mm/percpu.c b/mm/percpu.c
> > > index 6596a0a4286e..78c55c73fa28 100644
> > > --- a/mm/percpu.c
> > > +++ b/mm/percpu.c
> > > @@ -2055,6 +2055,96 @@ static void __pcpu_balance_workfn(enum 
> > > pcpu_chunk_type type)
> > >   mutex_unlock(&pcpu_alloc_mutex);
> > >  }
> > >  
> > > +/**
> > > + * pcpu_shrink_populated - scan chunks and release unused pages to the 
> > > system
> > > + * @type: chunk type
> > > + *
> > > + * Scan over all chunks, find those marked with the depopulate flag and
> > > + * try to release unused pages to the system. On every attempt clear the
> > > + * chunk's depopulate flag to avoid wasting CPU by scanning the same
> > > + * chunk again and again.
> > > + */
> > > +static void pcpu_shrink_populated(enum pcpu_chunk_type type)
> > > +{
> > > + struct list_head *pcpu_slot = pcpu_chunk_list(type);
> > > + struct pcpu_chunk *chunk;
> > > + int slot, i, off, start;
> > > +
> > > + spin_lock_irq(&pcpu_lock);
> > > + for (slot = pcpu_nr_slots - 1; slot >= 0; slot--) {
> > > +restart:
> > > + list_for_each_entry(chunk, &pcpu_slot[slot], list) {
> > > + bool isolated = false;
> > > +
> > > + if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_HIGH)
> > > + break;
> > > +
> > 
> > Deallocation makes me a little worried for the atomic case as now we
> > could in theory pathologically scan deallocated chunks before finding a
> > populated one.
> > 
> > I wonder if we should do something like once a chunk gets depopulated,
> > it gets deprioritized and then only once we exhaust looking through
> > allocated chunks we then find a depopulated chunk and add it back into
> > the rotation. Possibly just add another set of slots? I guess it adds a
> > few dimensions to pcpu_slots after the memcg change.
> 
> Please, take a look at patch 3 in the series ("percpu: on demand chunk 
> depopulation").
> Chunks considered to be a good target for the depopulation are in advance
> marked with a special flag, so we'll actually try to depopulate only
> few chunks at once. While the total number of chunks is fairly low,
> I think it should work.
> 
> Another option is to link all such chunks into a list and scan over it,
> instead of iterating over all slots.
> 
> Adding new dimensions to pcpu_slots is an option too, but I hope we can avoid
> this, as it would complicate the code.
> 

Yeah, depopulation has been on the todo list for a while. It adds the
dimension/opportunity of bin packing by sidelining chunks and I'm
wondering if that is the right thing to do.

Do you have a rough idea of the distribution of # of chunks you're
seeing?

> > 
> > > + for (i = 0, start = -1; i < chunk->nr_pages; i++) {
> > > +

Re: [PATCH rfc 3/4] percpu: on demand chunk depopulation

2021-03-29 Thread Dennis Zhou
t pcpu_chunk *pos;
> -
> + /*
> +  * If there are more than one fully free chunks,
> +  * wake up grim reaper.
> +  */
>   list_for_each_entry(pos, &pcpu_slot[pcpu_nr_slots - 1], list)
>   if (pos != chunk) {
>   need_balance = true;
>   break;
>   }
> +
> + } else if (chunk->nr_empty_pop_pages > chunk->nr_pages / 4) {

We should have this ignore the first and reserved chunks. While it
shouldn't be possible in theory, it would be nice to just make it
explicit here.

> + /*
> +  * If there is more than one chunk in the slot and
> +  * at least 1/4 of its pages are empty, mark the chunk
> +  * as a target for the depopulation. If there is more
> +  * than one chunk like this, schedule an async balancing.
> +  */
> + int nslot = pcpu_chunk_slot(chunk);
> +
> + list_for_each_entry(pos, &pcpu_slot[nslot], list)
> + if (pos != chunk && !chunk->depopulate &&
> +     !chunk->immutable) {
> + chunk->depopulate = true;
> + pcpu_nr_chunks_to_depopulate++;
> + break;
> + }
> +
> + if (pcpu_nr_chunks_to_depopulate > 1)
> + need_balance = true;
>   }
>  
>   trace_percpu_free_percpu(chunk->base_addr, off, ptr);
> -- 
> 2.30.2
> 

Some questions I have:
1. How do we prevent unnecessary scanning for atomic allocations?
2. Even in the normal case, should we try to pack future allocations
into a smaller # of chunks in after depopulation?
3. What is the right frequency to do depopulation scanning? I think of
the pcpu work item as a way to defer the 2 the freeing of chunks and in
a way more immediately replenish free pages. Depopulation isn't
necessarily as high a priority.

Thanks,
Dennis


Re: [PATCH rfc 2/4] percpu: split __pcpu_balance_workfn()

2021-03-29 Thread Dennis Zhou
On Wed, Mar 24, 2021 at 12:06:24PM -0700, Roman Gushchin wrote:
> __pcpu_balance_workfn() became fairly big and hard to follow, but in
> fact it consists of two fully independent parts, responsible for
> the destruction of excessive free chunks and population of necessarily
> amount of free pages.
> 
> In order to simplify the code and prepare for adding of a new
> functionality, split it in two functions:
> 
>   1) pcpu_balance_free,
>   2) pcpu_balance_populated.
> 
> Move the taking/releasing of the pcpu_alloc_mutex to an upper level
> to keep the current synchronization in place.
> 
> Signed-off-by: Roman Gushchin 
> ---
>  mm/percpu.c | 46 +-
>  1 file changed, 29 insertions(+), 17 deletions(-)
> 
> diff --git a/mm/percpu.c b/mm/percpu.c
> index 78c55c73fa28..015d076893f5 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -1930,31 +1930,22 @@ void __percpu *__alloc_reserved_percpu(size_t size, 
> size_t align)
>  }
>  
>  /**
> - * __pcpu_balance_workfn - manage the amount of free chunks and populated 
> pages
> + * pcpu_balance_free - manage the amount of free chunks
>   * @type: chunk type
>   *
> - * Reclaim all fully free chunks except for the first one.  This is also
> - * responsible for maintaining the pool of empty populated pages.  However,
> - * it is possible that this is called when physical memory is scarce causing
> - * OOM killer to be triggered.  We should avoid doing so until an actual
> - * allocation causes the failure as it is possible that requests can be
> - * serviced from already backed regions.
> + * Reclaim all fully free chunks except for the first one.
>   */
> -static void __pcpu_balance_workfn(enum pcpu_chunk_type type)
> +static void pcpu_balance_free(enum pcpu_chunk_type type)
>  {
> - /* gfp flags passed to underlying allocators */
> - const gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
>   LIST_HEAD(to_free);
>   struct list_head *pcpu_slot = pcpu_chunk_list(type);
>   struct list_head *free_head = &pcpu_slot[pcpu_nr_slots - 1];
>   struct pcpu_chunk *chunk, *next;
> - int slot, nr_to_pop, ret;
>  
>   /*
>* There's no reason to keep around multiple unused chunks and VM
>* areas can be scarce.  Destroy all free chunks except for one.
>*/
> - mutex_lock(&pcpu_alloc_mutex);
>   spin_lock_irq(&pcpu_lock);
>  
>   list_for_each_entry_safe(chunk, next, free_head, list) {
> @@ -1982,6 +1973,25 @@ static void __pcpu_balance_workfn(enum pcpu_chunk_type 
> type)
>   pcpu_destroy_chunk(chunk);
>   cond_resched();
>   }
> +}
> +
> +/**
> + * pcpu_balance_populated - manage the amount of populated pages
> + * @type: chunk type
> + *
> + * Maintain a certain amount of populated pages to satisfy atomic 
> allocations.
> + * It is possible that this is called when physical memory is scarce causing
> + * OOM killer to be triggered.  We should avoid doing so until an actual
> + * allocation causes the failure as it is possible that requests can be
> + * serviced from already backed regions.
> + */
> +static void pcpu_balance_populated(enum pcpu_chunk_type type)
> +{
> + /* gfp flags passed to underlying allocators */
> + const gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
> + struct list_head *pcpu_slot = pcpu_chunk_list(type);
> + struct pcpu_chunk *chunk;
> + int slot, nr_to_pop, ret;
>  
>   /*
>* Ensure there are certain number of free populated pages for
> @@ -2051,8 +2061,6 @@ static void __pcpu_balance_workfn(enum pcpu_chunk_type 
> type)
>   goto retry_pop;
>   }
>   }
> -
> - mutex_unlock(&pcpu_alloc_mutex);
>  }
>  
>  /**
> @@ -2149,14 +2157,18 @@ static void pcpu_shrink_populated(enum 
> pcpu_chunk_type type)
>   * pcpu_balance_workfn - manage the amount of free chunks and populated pages
>   * @work: unused
>   *
> - * Call __pcpu_balance_workfn() for each chunk type.
> + * Call pcpu_balance_free() and pcpu_balance_populated() for each chunk type.
>   */
>  static void pcpu_balance_workfn(struct work_struct *work)
>  {
>   enum pcpu_chunk_type type;
>  
> - for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++)
> - __pcpu_balance_workfn(type);
> + for (type = 0; type < PCPU_NR_CHUNK_TYPES; type++) {
> + mutex_lock(&pcpu_alloc_mutex);
> +     pcpu_balance_free(type);
> + pcpu_balance_populated(type);
> + mutex_unlock(&pcpu_alloc_mutex);
> + }
>  }
>  
>  /**
> -- 
> 2.30.2
> 

Reviewed-by: Dennis Zhou 

This makes sense. If you want me to pick this and the last patch up
first I can. Otherwise, do you mind moving this to the front of the
stack because it is a clean up?

Thanks,
Dennis


Re: [PATCH rfc 1/4] percpu: implement partial chunk depopulation

2021-03-29 Thread Dennis Zhou
On Wed, Mar 24, 2021 at 12:06:23PM -0700, Roman Gushchin wrote:
> This patch implements partial depopulation of percpu chunks.
> 
> As now, a chunk can be depopulated only as a part of the final
> destruction, when there are no more outstanding allocations. However
> to minimize a memory waste, it might be useful to depopulate a
> partially filed chunk, if a small number of outstanding allocations
> prevents the chunk from being reclaimed.
> 
> This patch implements the following depopulation process: it scans
> over the chunk pages, looks for a range of empty and populated pages
> and performs the depopulation. To avoid races with new allocations,
> the chunk is previously isolated. After the depopulation the chunk is
> returned to the original slot (but is appended to the tail of the list
> to minimize the chances of population).
> 
> Because the pcpu_lock is dropped while calling pcpu_depopulate_chunk(),
> the chunk can be concurrently moved to a different slot. So we need
> to isolate it again on each step. pcpu_alloc_mutex is held, so the
> chunk can't be populated/depopulated asynchronously.
> 
> Signed-off-by: Roman Gushchin 
> ---
>  mm/percpu.c | 90 +
>  1 file changed, 90 insertions(+)
> 
> diff --git a/mm/percpu.c b/mm/percpu.c
> index 6596a0a4286e..78c55c73fa28 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -2055,6 +2055,96 @@ static void __pcpu_balance_workfn(enum pcpu_chunk_type 
> type)
>   mutex_unlock(&pcpu_alloc_mutex);
>  }
>  
> +/**
> + * pcpu_shrink_populated - scan chunks and release unused pages to the system
> + * @type: chunk type
> + *
> + * Scan over all chunks, find those marked with the depopulate flag and
> + * try to release unused pages to the system. On every attempt clear the
> + * chunk's depopulate flag to avoid wasting CPU by scanning the same
> + * chunk again and again.
> + */
> +static void pcpu_shrink_populated(enum pcpu_chunk_type type)
> +{
> + struct list_head *pcpu_slot = pcpu_chunk_list(type);
> + struct pcpu_chunk *chunk;
> + int slot, i, off, start;
> +
> + spin_lock_irq(&pcpu_lock);
> + for (slot = pcpu_nr_slots - 1; slot >= 0; slot--) {
> +restart:
> + list_for_each_entry(chunk, &pcpu_slot[slot], list) {
> + bool isolated = false;
> +
> + if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_HIGH)
> + break;
> +

Deallocation makes me a little worried for the atomic case as now we
could in theory pathologically scan deallocated chunks before finding a
populated one.

I wonder if we should do something like once a chunk gets depopulated,
it gets deprioritized and then only once we exhaust looking through
allocated chunks we then find a depopulated chunk and add it back into
the rotation. Possibly just add another set of slots? I guess it adds a
few dimensions to pcpu_slots after the memcg change.

> + for (i = 0, start = -1; i < chunk->nr_pages; i++) {
> + if (!chunk->nr_empty_pop_pages)
> + break;
> +
> + /*
> +  * If the page is empty and populated, start or
> +  * extend the [start, i) range.
> +  */
> + if (test_bit(i, chunk->populated)) {
> + off = find_first_bit(
> + pcpu_index_alloc_map(chunk, i),
> + PCPU_BITMAP_BLOCK_BITS);
> + if (off >= PCPU_BITMAP_BLOCK_BITS) {
> + if (start == -1)
> + start = i;
> + continue;
> + }

Here instead of looking at the alloc_map, you can look at the
pcpu_block_md and look for a fully free contig_hint.

> + }
> +
> + /*
> +  * Otherwise check if there is an active range,
> +  * and if yes, depopulate it.
> +  */
> + if (start == -1)
> + continue;
> +
> + /*
> +  * Isolate the chunk, so new allocations
> +  * wouldn't be served using this chunk.
> +  * Async releases can still happen.
> +  */
> + if (!list_empty(&chunk->list)) {
> + list_del_init(&chunk->list);
> + isolated = true;

Maybe when freeing a chunk, we should consider just isolating it period
and preventing pcpu_free_a

[GIT PULL] percpu changes for v5.12-rc1

2021-02-22 Thread Dennis Zhou
Hi Linus,

Percpu had a cleanup come in that makes use of the cpu bitmask helpers
instead of the current iterative approach. This clean up has an adverse
interaction when clang's inlining sensitivity is changed such that
not all sites are inlined resulting in modpost being upset with section
mismatch due to percpu setup being marked __init. It is fixed by
introducing __flatten to compiler_attributes.h. This has been supported
since clang 3.5 and gcc 4.4 [1].

[1] 
https://lore.kernel.org/lkml/CAKwvOdnxnooqtyeSem63V_P5980jc0Z2PDG=0im8ixeytsa...@mail.gmail.com/

Thanks,
Dennis

The following changes since commit 92bf22614b21a2706f4993b278017e437f7785b3:

  Linux 5.11-rc7 (2021-02-07 13:57:38 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git for-5.12

for you to fetch changes up to 258e0815e2b1706e87c0d874211097aa8a7aa52f:

  percpu: fix clang modpost section mismatch (2021-02-14 18:15:15 +)


Dennis Zhou (1):
  percpu: fix clang modpost section mismatch

Wonhyuk Yang (1):
  percpu: reduce the number of cpu distance comparisons

 include/linux/compiler_attributes.h |  6 ++
 mm/percpu.c | 36 +---
 2 files changed, 27 insertions(+), 15 deletions(-)


[PATCH] percpu: fix clang modpost section mismatch

2021-02-14 Thread Dennis Zhou
pcpu_build_alloc_info() is an __init function that makes a call to
cpumask_clear_cpu(). With CONFIG_GCOV_PROFILE_ALL enabled, the inline
heuristics are modified and such cpumask_clear_cpu() which is marked
inline doesn't get inlined. Because it works on mask in __initdata,
modpost throws a section mismatch error.

Arnd sent a patch with the flatten attribute as an alternative [2]. I've
added it to compiler_attributes.h.

modpost complaint:
  WARNING: modpost: vmlinux.o(.text+0x735425): Section mismatch in reference 
from the function cpumask_clear_cpu() to the variable 
.init.data:pcpu_build_alloc_info.mask
  The function cpumask_clear_cpu() references
  the variable __initdata pcpu_build_alloc_info.mask.
  This is often because cpumask_clear_cpu lacks a __initdata
  annotation or the annotation of pcpu_build_alloc_info.mask is wrong.

clang output:
  mm/percpu.c:2724:5: remark: cpumask_clear_cpu not inlined into 
pcpu_build_alloc_info because too costly to inline (cost=725, threshold=325) 
[-Rpass-missed=inline]

[1] https://lore.kernel.org/linux-mm/202012220454.9f6bkz9q-...@intel.com/
[2] 
https://lore.kernel.org/lkml/cak8p3a2zwfnexksm8k_suhhwkor17jfo3xaplxjzfpqx0eu...@mail.gmail.com/

Reported-by: kernel test robot 
Cc: Arnd Bergmann 
Cc: Nick Desaulniers 
Signed-off-by: Dennis Zhou 
---
 include/linux/compiler_attributes.h | 6 ++
 mm/percpu.c | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/compiler_attributes.h 
b/include/linux/compiler_attributes.h
index ea5e04e75845..c043b8d2b17b 100644
--- a/include/linux/compiler_attributes.h
+++ b/include/linux/compiler_attributes.h
@@ -210,6 +210,12 @@
 # define fallthroughdo {} while (0)  /* fallthrough */
 #endif
 
+/*
+ * gcc: 
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#flatten
+ */
+# define __flatten __attribute__((flatten))
+
 /*
  * Note the missing underscores.
  *
diff --git a/mm/percpu.c b/mm/percpu.c
index 80f8f885a990..6596a0a4286e 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -2663,7 +2663,7 @@ early_param("percpu_alloc", percpu_alloc_setup);
  * On success, pointer to the new allocation_info is returned.  On
  * failure, ERR_PTR value is returned.
  */
-static struct pcpu_alloc_info * __init pcpu_build_alloc_info(
+static struct pcpu_alloc_info * __init __flatten pcpu_build_alloc_info(
size_t reserved_size, size_t dyn_size,
size_t atom_size,
pcpu_fc_cpu_distance_fn_t cpu_distance_fn)
-- 
2.30.0.478.g8a0d178c01-goog



Re: [PATCH] percpu: fix clang modpost warning in pcpu_build_alloc_info()

2021-01-26 Thread Dennis Zhou
Hi Nick,

On Mon, Jan 25, 2021 at 10:27:11AM -0800, Nick Desaulniers wrote:
> On Mon, Jan 25, 2021 at 3:07 AM Arnd Bergmann  wrote:
> >
> > On Tue, Jan 5, 2021 at 1:55 AM Dennis Zhou  wrote:
> > >
> > > On Mon, Jan 04, 2021 at 04:46:51PM -0700, Nathan Chancellor wrote:
> > > > On Thu, Dec 31, 2020 at 09:28:52PM +, Dennis Zhou wrote:
> > > > >
> > >
> > > Hi Nathan,
> > >
> > > >
> > > > Hi Dennis,
> > > >
> > > > I did a bisect of the problematic config against defconfig and it points
> > > > out that CONFIG_GCOV_PROFILE_ALL is in the bad config but not the good
> > > > config, which makes some sense as that will mess with clang's inlining
> > > > heuristics. It does not appear to be the single config that makes a
> > > > difference but it gives some clarity.
> > > >
> > >
> > > Ah, thanks. To me it's kind of a corner case that I don't have a lot of
> > > insight into. __init code is pretty limited and this warning is really
> > > at the compilers whim. However, in this case only clang throws this
> > > warning.
> > >
> > > > I do not personally have any strong opinions around the patch but is it
> > > > really that much wasted memory to just annotate mask with __refdata?
> > >
> > > It's really not much memory, 1 bit per max # of cpus. The reported
> > > config is on the extreme side compiling with 8k NR_CPUS, so 1kb. I'm
> > > just not in love with the idea of adding a patch to improve readability
> > > and it cost idle memory to resolve a compile time warning.
> > >
> > > If no one else chimes in in the next few days, I'll probably just apply
> > > it and go from there. If another issue comes up I'll drop this and tag
> > > it as __refdata.
> >
> > I've come across this one again in linux-next today, and found that
> > I had an old patch for it already, that I had never submitted:
> >
> > From 7d6f40414490092b86f1a64d8c42426ee350da1a Mon Sep 17 00:00:00 2001
> > From: Arnd Bergmann 
> > Date: Mon, 7 Dec 2020 23:24:20 +0100
> > Subject: [PATCH] mm: percpu: fix section mismatch warning
> >
> > Building with arm64 clang sometimes (fairly rarely) shows a
> > warning about the pcpu_build_alloc_info() function:
> >
> > WARNING: modpost: vmlinux.o(.text+0x21697c): Section mismatch in
> > reference from the function cpumask_clear_cpu() to the variable
> > .init.data:pcpu_build_alloc_info.mask
> > The function cpumask_clear_cpu() references
> > the variable __initdata pcpu_build_alloc_info.mask.
> > This is often because cpumask_clear_cpu lacks a __initdata
> > annotation or the annotation of pcpu_build_alloc_info.mask is wrong.
> >
> > What appears to be going on here is that the compiler decides to not
> > inline the cpumask_clear_cpu() function that is marked 'inline' but not
> > 'always_inline', and it then produces a specialized version of it that
> > references the static mask unconditionally as an optimization.
> >
> > Marking cpumask_clear_cpu() as __always_inline would fix it, as would
> > removing the __initdata annotation on the variable.  I went for marking
> > the function as __attribute__((flatten)) instead because all functions
> 
> I had to look this one up; it's new to me!
> https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
> https://awesomekling.github.io/Smarter-C++-inlining-with-attribute-flatten/
> 
> Seems pretty cool/flexible to control inlining on the caller side!
> 
> At the least though, we should avoid open coding the function attributes.  See
> include/linux/compiler_attributes.h
> 

Arnd do you mind spinning a new version to add __flatten to
compiler_attributes.h?

> Testing quickly in godbolt, __flatten__ has been supported since at
> least clang 3.5 and gcc 4.4, FWIW (so it doesn't need a
> __has_attribute guard).
> 

Thanks for testing this!

Thanks,
Dennis


Re: [PATCH] percpu: fix clang modpost warning in pcpu_build_alloc_info()

2021-01-26 Thread Dennis Zhou
On Mon, Jan 25, 2021 at 12:07:24PM +0100, Arnd Bergmann wrote:
> On Tue, Jan 5, 2021 at 1:55 AM Dennis Zhou  wrote:
> >
> > On Mon, Jan 04, 2021 at 04:46:51PM -0700, Nathan Chancellor wrote:
> > > On Thu, Dec 31, 2020 at 09:28:52PM +, Dennis Zhou wrote:
> > > >
> >
> > Hi Nathan,
> >
> > >
> > > Hi Dennis,
> > >
> > > I did a bisect of the problematic config against defconfig and it points
> > > out that CONFIG_GCOV_PROFILE_ALL is in the bad config but not the good
> > > config, which makes some sense as that will mess with clang's inlining
> > > heuristics. It does not appear to be the single config that makes a
> > > difference but it gives some clarity.
> > >
> >
> > Ah, thanks. To me it's kind of a corner case that I don't have a lot of
> > insight into. __init code is pretty limited and this warning is really
> > at the compilers whim. However, in this case only clang throws this
> > warning.
> >
> > > I do not personally have any strong opinions around the patch but is it
> > > really that much wasted memory to just annotate mask with __refdata?
> >
> > It's really not much memory, 1 bit per max # of cpus. The reported
> > config is on the extreme side compiling with 8k NR_CPUS, so 1kb. I'm
> > just not in love with the idea of adding a patch to improve readability
> > and it cost idle memory to resolve a compile time warning.
> >
> > If no one else chimes in in the next few days, I'll probably just apply
> > it and go from there. If another issue comes up I'll drop this and tag
> > it as __refdata.
> 
> I've come across this one again in linux-next today, and found that
> I had an old patch for it already, that I had never submitted:
> 
> From 7d6f40414490092b86f1a64d8c42426ee350da1a Mon Sep 17 00:00:00 2001
> From: Arnd Bergmann 
> Date: Mon, 7 Dec 2020 23:24:20 +0100
> Subject: [PATCH] mm: percpu: fix section mismatch warning
> 
> Building with arm64 clang sometimes (fairly rarely) shows a
> warning about the pcpu_build_alloc_info() function:
> 
> WARNING: modpost: vmlinux.o(.text+0x21697c): Section mismatch in
> reference from the function cpumask_clear_cpu() to the variable
> .init.data:pcpu_build_alloc_info.mask
> The function cpumask_clear_cpu() references
> the variable __initdata pcpu_build_alloc_info.mask.
> This is often because cpumask_clear_cpu lacks a __initdata
> annotation or the annotation of pcpu_build_alloc_info.mask is wrong.
> 
> What appears to be going on here is that the compiler decides to not
> inline the cpumask_clear_cpu() function that is marked 'inline' but not
> 'always_inline', and it then produces a specialized version of it that
> references the static mask unconditionally as an optimization.
> 
> Marking cpumask_clear_cpu() as __always_inline would fix it, as would
> removing the __initdata annotation on the variable.  I went for marking
> the function as __attribute__((flatten)) instead because all functions
> called from it are really meant to be inlined here, and it prevents
> the same problem happening here again. This is unlikely to be a problem
> elsewhere because there are very few function-local static __initdata
> variables in the kernel.
> 
> Fixes: 6c207504ae79 ("percpu: reduce the number of cpu distance comparisons")
> Signed-off-by: Arnd Bergmann 
> 
> diff --git a/mm/percpu.c b/mm/percpu.c
> index 5ede8dd407d5..527181c46b08 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -2662,10 +2662,9 @@ early_param("percpu_alloc", percpu_alloc_setup);
>   * On success, pointer to the new allocation_info is returned.  On
>   * failure, ERR_PTR value is returned.
>   */
> -static struct pcpu_alloc_info * __init pcpu_build_alloc_info(
> -   size_t reserved_size, size_t dyn_size,
> -   size_t atom_size,
> -   pcpu_fc_cpu_distance_fn_t cpu_distance_fn)
> +static struct pcpu_alloc_info * __init __attribute__((flatten))
> +pcpu_build_alloc_info(size_t reserved_size, size_t dyn_size, size_t 
> atom_size,
> + pcpu_fc_cpu_distance_fn_t cpu_distance_fn)
>  {
> static int group_map[NR_CPUS] __initdata;
> static int group_cnt[NR_CPUS] __initdata;
> 
> 
> Not sure if this would be any better than your patch.
> 
>Arnd

Hi Arnd,

I like this solution a lot more than my previous solution because this
is a lot less fragile.

Thanks,
Dennis


Re: [PATCH] percpu: fix clang modpost warning in pcpu_build_alloc_info()

2021-01-04 Thread Dennis Zhou
On Mon, Jan 04, 2021 at 04:46:51PM -0700, Nathan Chancellor wrote:
> On Thu, Dec 31, 2020 at 09:28:52PM +0000, Dennis Zhou wrote:
> > This is an unusual situation so I thought it best to explain it in a
> > separate patch.
> > 
> > "percpu: reduce the number of cpu distance comparisons" introduces a
> > dependency on cpumask helper functions in __init code. This code
> > references a struct cpumask annotated __initdata. When the function is
> > inlined (gcc), everything is fine, but clang decides not to inline these
> > function calls. This causes modpost to warn about an __initdata access
> > by a function not annotated with __init [1].
> > 
> > Ways I thought about fixing it:
> > 1. figure out why clang thinks this inlining is too costly.
> > 2. create a wrapper function annotated __init (this).
> > 3. annotate cpumask with __refdata.
> > 
> > Ultimately it comes down to if it's worth saving the cpumask memory and
> > allowing it to be freed. IIUC, __refdata won't be freed, so option 3 is
> > just a little wasteful. 1 is out of my depth, leaving 2. I don't feel
> > great about this behavior being dependent on inlining semantics, but
> > cpumask helpers are small and probably should be inlined.
> > 
> > modpost complaint:
> >   WARNING: modpost: vmlinux.o(.text+0x735425): Section mismatch in 
> > reference from the function cpumask_clear_cpu() to the variable 
> > .init.data:pcpu_build_alloc_info.mask
> >   The function cpumask_clear_cpu() references
> >   the variable __initdata pcpu_build_alloc_info.mask.
> >   This is often because cpumask_clear_cpu lacks a __initdata
> >   annotation or the annotation of pcpu_build_alloc_info.mask is wrong.
> > 
> > clang output:
> >   mm/percpu.c:2724:5: remark: cpumask_clear_cpu not inlined into 
> > pcpu_build_alloc_info because too costly to inline (cost=725, 
> > threshold=325) [-Rpass-missed=inline]
> > 
> > [1] https://lore.kernel.org/linux-mm/202012220454.9f6bkz9q-...@intel.com/
> > 
> > Reported-by: kernel test robot 
> > Signed-off-by: Dennis Zhou 
> > ---
> > This is on top of percpu#for-5.12.
> > 
> >  mm/percpu.c | 16 ++--
> >  1 file changed, 14 insertions(+), 2 deletions(-)
> > 
> > diff --git a/mm/percpu.c b/mm/percpu.c
> > index 80f8f885a990..357977c4cb00 100644
> > --- a/mm/percpu.c
> > +++ b/mm/percpu.c
> > @@ -2642,6 +2642,18 @@ early_param("percpu_alloc", percpu_alloc_setup);
> >  
> >  /* pcpu_build_alloc_info() is used by both embed and page first chunk */
> >  #if defined(BUILD_EMBED_FIRST_CHUNK) || defined(BUILD_PAGE_FIRST_CHUNK)
> > +
> > +/*
> > + * This wrapper is to avoid a warning where cpumask_clear_cpu() is not 
> > inlined
> > + * when compiling with clang causing modpost to warn about accessing 
> > __initdata
> > + * from a non __init function.  By doing this, we allow the struct cpumask 
> > to be
> > + * freed instead of it taking space by annotating with __refdata.
> > + */
> > +static void __init pcpu_cpumask_clear_cpu(int cpu, struct cpumask *mask)
> > +{
> > +   cpumask_clear_cpu(cpu, mask);
> > +}
> > +
> >  /**
> >   * pcpu_build_alloc_info - build alloc_info considering distances between 
> > CPUs
> >   * @reserved_size: the size of reserved percpu area in bytes
> > @@ -2713,7 +2725,7 @@ static struct pcpu_alloc_info * __init 
> > pcpu_build_alloc_info(
> > cpu = cpumask_first(&mask);
> > group_map[cpu] = group;
> > group_cnt[group]++;
> > -   cpumask_clear_cpu(cpu, &mask);
> > +   pcpu_cpumask_clear_cpu(cpu, &mask);
> >  
> > for_each_cpu(tcpu, &mask) {
> > if (!cpu_distance_fn ||
> > @@ -2721,7 +2733,7 @@ static struct pcpu_alloc_info * __init 
> > pcpu_build_alloc_info(
> >  cpu_distance_fn(tcpu, cpu) == LOCAL_DISTANCE)) {
> > group_map[tcpu] = group;
> > group_cnt[group]++;
> > -   cpumask_clear_cpu(tcpu, &mask);
> > +   pcpu_cpumask_clear_cpu(tcpu, &mask);
> > }
> > }
> > }
> > -- 
> > 2.29.2.729.g45daf8777d-goog
> > 

Hi Nathan,

> 
> Hi Dennis,
> 
> I did a bisect of the problematic config against defconfig and it points
> out that CONFIG_GCOV_PROFILE_ALL is in the bad config but not the good
> config, which makes some sen

[PATCH] percpu: fix clang modpost warning in pcpu_build_alloc_info()

2020-12-31 Thread Dennis Zhou
This is an unusual situation so I thought it best to explain it in a
separate patch.

"percpu: reduce the number of cpu distance comparisons" introduces a
dependency on cpumask helper functions in __init code. This code
references a struct cpumask annotated __initdata. When the function is
inlined (gcc), everything is fine, but clang decides not to inline these
function calls. This causes modpost to warn about an __initdata access
by a function not annotated with __init [1].

Ways I thought about fixing it:
1. figure out why clang thinks this inlining is too costly.
2. create a wrapper function annotated __init (this).
3. annotate cpumask with __refdata.

Ultimately it comes down to if it's worth saving the cpumask memory and
allowing it to be freed. IIUC, __refdata won't be freed, so option 3 is
just a little wasteful. 1 is out of my depth, leaving 2. I don't feel
great about this behavior being dependent on inlining semantics, but
cpumask helpers are small and probably should be inlined.

modpost complaint:
  WARNING: modpost: vmlinux.o(.text+0x735425): Section mismatch in reference 
from the function cpumask_clear_cpu() to the variable 
.init.data:pcpu_build_alloc_info.mask
  The function cpumask_clear_cpu() references
  the variable __initdata pcpu_build_alloc_info.mask.
  This is often because cpumask_clear_cpu lacks a __initdata
  annotation or the annotation of pcpu_build_alloc_info.mask is wrong.

clang output:
  mm/percpu.c:2724:5: remark: cpumask_clear_cpu not inlined into 
pcpu_build_alloc_info because too costly to inline (cost=725, threshold=325) 
[-Rpass-missed=inline]

[1] https://lore.kernel.org/linux-mm/202012220454.9f6bkz9q-...@intel.com/

Reported-by: kernel test robot 
Signed-off-by: Dennis Zhou 
---
This is on top of percpu#for-5.12.

 mm/percpu.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/mm/percpu.c b/mm/percpu.c
index 80f8f885a990..357977c4cb00 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -2642,6 +2642,18 @@ early_param("percpu_alloc", percpu_alloc_setup);
 
 /* pcpu_build_alloc_info() is used by both embed and page first chunk */
 #if defined(BUILD_EMBED_FIRST_CHUNK) || defined(BUILD_PAGE_FIRST_CHUNK)
+
+/*
+ * This wrapper is to avoid a warning where cpumask_clear_cpu() is not inlined
+ * when compiling with clang causing modpost to warn about accessing __initdata
+ * from a non __init function.  By doing this, we allow the struct cpumask to 
be
+ * freed instead of it taking space by annotating with __refdata.
+ */
+static void __init pcpu_cpumask_clear_cpu(int cpu, struct cpumask *mask)
+{
+   cpumask_clear_cpu(cpu, mask);
+}
+
 /**
  * pcpu_build_alloc_info - build alloc_info considering distances between CPUs
  * @reserved_size: the size of reserved percpu area in bytes
@@ -2713,7 +2725,7 @@ static struct pcpu_alloc_info * __init 
pcpu_build_alloc_info(
cpu = cpumask_first(&mask);
group_map[cpu] = group;
group_cnt[group]++;
-   cpumask_clear_cpu(cpu, &mask);
+   pcpu_cpumask_clear_cpu(cpu, &mask);
 
for_each_cpu(tcpu, &mask) {
if (!cpu_distance_fn ||
@@ -2721,7 +2733,7 @@ static struct pcpu_alloc_info * __init 
pcpu_build_alloc_info(
 cpu_distance_fn(tcpu, cpu) == LOCAL_DISTANCE)) {
group_map[tcpu] = group;
group_cnt[group]++;
-   cpumask_clear_cpu(tcpu, &mask);
+   pcpu_cpumask_clear_cpu(tcpu, &mask);
}
}
}
-- 
2.29.2.729.g45daf8777d-goog



[PATCH] staging/vc04_services/bcm2835-audio: Parenthesize alsa2chip macro

2020-12-02 Thread Dennis Skovborg Jørgensen
Add parenthesis around the alsa2chip macro to remove a checkpatch error.

Signed-off-by: Dennis Skovborg Jørgensen 
---
 drivers/staging/vc04_services/bcm2835-audio/bcm2835.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h 
b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h
index 1b36475872d6..51066ac8eea5 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h
@@ -22,7 +22,7 @@ enum {
 /* macros for alsa2chip and chip2alsa, instead of functions */
 
 // convert alsa to chip volume (defined as macro rather than function call)
-#define alsa2chip(vol) (uint)(-(((vol) << 8) / 100))
+#define alsa2chip(vol) ((uint)(-(((vol) << 8) / 100)))
 
 // convert chip to alsa volume
 #define chip2alsa(vol) -(((vol) * 100) >> 8)
-- 
2.29.2



[GIT PULL] percpu fix for v5.10-rc4

2020-11-14 Thread Dennis Zhou
Hi Linus,

A fix for a Wshadow warning in asm-generic percpu macros came in and
then I tacked on the removal of flexible array initializers in the
percpu allocator which was discussed in the 5.9 pull request.

Thanks,
Dennis

The following changes since commit 3650b228f83adda7e5ee532e2b90429c03f7b9ec:

  Linux 5.10-rc1 (2020-10-25 15:14:11 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git for-5.10-fixes

for you to fetch changes up to 61cf93d3e14a29288e4d5522aecb6e58268eec62:

  percpu: convert flexible array initializers to use struct_size() (2020-10-30 
23:02:28 +)


Arnd Bergmann (1):
  asm-generic: percpu: avoid Wshadow warning

Dennis Zhou (1):
  percpu: convert flexible array initializers to use struct_size()

 include/asm-generic/percpu.h | 18 +-
 mm/percpu.c  |  8 
 2 files changed, 13 insertions(+), 13 deletions(-)


[PATCH] percpu: convert flexible array initializers to use struct_size()

2020-10-30 Thread Dennis Zhou
Use the safer macro as sparked by the long discussion in [1].

[1] https://lore.kernel.org/lkml/20200917204514.ga2880...@google.com/

Signed-off-by: Dennis Zhou 
---
I'll apply it to for-5.10-fixes.

 mm/percpu.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mm/percpu.c b/mm/percpu.c
index 66a93f096394..ad7a37ee74ef 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1315,8 +1315,8 @@ static struct pcpu_chunk * __init 
pcpu_alloc_first_chunk(unsigned long tmp_addr,
region_size = ALIGN(start_offset + map_size, lcm_align);
 
/* allocate chunk */
-   alloc_size = sizeof(struct pcpu_chunk) +
-   BITS_TO_LONGS(region_size >> PAGE_SHIFT) * sizeof(unsigned 
long);
+   alloc_size = struct_size(chunk, populated,
+BITS_TO_LONGS(region_size >> PAGE_SHIFT));
chunk = memblock_alloc(alloc_size, SMP_CACHE_BYTES);
if (!chunk)
panic("%s: Failed to allocate %zu bytes\n", __func__,
@@ -2521,8 +2521,8 @@ void __init pcpu_setup_first_chunk(const struct 
pcpu_alloc_info *ai,
pcpu_unit_pages = ai->unit_size >> PAGE_SHIFT;
pcpu_unit_size = pcpu_unit_pages << PAGE_SHIFT;
pcpu_atom_size = ai->atom_size;
-   pcpu_chunk_struct_size = sizeof(struct pcpu_chunk) +
-   BITS_TO_LONGS(pcpu_unit_pages) * sizeof(unsigned long);
+   pcpu_chunk_struct_size = struct_size(chunk, populated,
+BITS_TO_LONGS(pcpu_unit_pages));
 
pcpu_stats_save_ai(ai);
 
-- 
2.29.1.341.ge80a0c044ae-goog



Re: [PATCH] asm-generic: percpu: avoid Wshadow warning

2020-10-26 Thread Dennis Zhou
Hello,

On Mon, Oct 26, 2020 at 04:53:48PM +0100, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> Nesting macros that use the same local variable names causes
> warnings when building with "make W=2":
> 
> include/asm-generic/percpu.h:117:14: warning: declaration of '__ret' shadows 
> a previous local [-Wshadow]
> include/asm-generic/percpu.h:126:14: warning: declaration of '__ret' shadows 
> a previous local [-Wshadow]
> 
> These are fairly harmless, but since the warning comes from
> a global header, the warning happens every time the headers
> are included, which is fairly annoying.
> 
> Rename the variables to avoid shadowing and shut up the warning.
> 
> Signed-off-by: Arnd Bergmann 
> ---
>  include/asm-generic/percpu.h | 18 +-
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
> index 35e4a53b83e6..6432a7fade91 100644
> --- a/include/asm-generic/percpu.h
> +++ b/include/asm-generic/percpu.h
> @@ -114,21 +114,21 @@ do {
> \
>  
>  #define __this_cpu_generic_read_nopreempt(pcp)   
> \
>  ({   \
> - typeof(pcp) __ret;  \
> + typeof(pcp) ___ret; \
>   preempt_disable_notrace();  \
> - __ret = READ_ONCE(*raw_cpu_ptr(&(pcp)));\
> + ___ret = READ_ONCE(*raw_cpu_ptr(&(pcp)));   \
>   preempt_enable_notrace();   \
> - __ret;  \
> + ___ret; \
>  })
>  
>  #define __this_cpu_generic_read_noirq(pcp)   \
>  ({   \
> - typeof(pcp) __ret;  \
> - unsigned long __flags;  \
> - raw_local_irq_save(__flags);\
> - __ret = raw_cpu_generic_read(pcp);  \
> - raw_local_irq_restore(__flags); \
> - __ret;  \
> + typeof(pcp) ___ret; \
> + unsigned long ___flags; \
> + raw_local_irq_save(___flags);   \
> + ___ret = raw_cpu_generic_read(pcp); \
> + raw_local_irq_restore(___flags);\
> + ___ret;     \
>  })
>  
>  #define this_cpu_generic_read(pcp)   \
> -- 
> 2.27.0
> 

I've applied this to percpu#for-5.10-fixes.

Thanks,
Dennis


Greetings

2020-10-22 Thread Dennis Mattu
I am Mr.Dennis, i work as an accountant in a bank, i am contacting you
in regards to a business transfer of a huge sum of money from a
deceased account. I need your urgent assistance in transferring the
sum of $11.6million dollars to your private bank  account,the fund
belongs to one of our foreign customer who died along with his entire
family since July 22, 2003.The money has been here in our Bank lying
dormant for years now without anybody coming for the claim of it.

I now seek your permission to have you stand in as the deceased
relative to enable the funds be released in your favor as the
beneficiary and the next of kin to our deceased customer,the Banking
laws here does not allow such money to stay more than 19years,because
the money will be recalled to the Bank treasury account as unclaimed
fund.I am ready to share with you 40% for you and 60% will be kept for
me, by indicating your interest i will send you the full details on
how the business will be executed.


Re: [PATCH] IB/hfi1: Avoid allocing memory on memoryless numa node

2020-10-16 Thread Dennis Dalessandro

On 10/16/2020 10:11 AM, Jason Gunthorpe wrote:

On Mon, Oct 12, 2020 at 08:36:57AM -0400, Dennis Dalessandro wrote:

On 10/10/2020 4:57 AM, Xianting Tian wrote:

In architecture like powerpc, we can have cpus without any local memory
attached to it. In such cases the node does not have real memory.

Use local_memory_node(), which is guaranteed to have memory.
local_memory_node is a noop in other architectures that does not support
memoryless nodes.

Signed-off-by: Xianting Tian 
   drivers/infiniband/hw/hfi1/file_ops.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/hfi1/file_ops.c 
b/drivers/infiniband/hw/hfi1/file_ops.c
index 8ca51e43c..79fa22cc7 100644
+++ b/drivers/infiniband/hw/hfi1/file_ops.c
@@ -965,7 +965,7 @@ static int allocate_ctxt(struct hfi1_filedata *fd, struct 
hfi1_devdata *dd,
 */
fd->rec_cpu_num = hfi1_get_proc_affinity(dd->node);
if (fd->rec_cpu_num != -1)
-   numa = cpu_to_node(fd->rec_cpu_num);
+   numa = local_memory_node(cpu_to_node(fd->rec_cpu_num));
else
numa = numa_node_id();
ret = hfi1_create_ctxtdata(dd->pport, numa, &uctxt);



The hfi1 driver depends on X86_64. I'm not sure what this patch buys, can
you expand a bit?


Yikes, that is strongly discouraged.


Hmm. This was never raised as an issue before. Regardless I can't recall 
why we did this in the first place. I'll do some digging, try to jog my 
memory.


-Denny


Re: [PATCH] IB/hfi1: Avoid allocing memory on memoryless numa node

2020-10-12 Thread Dennis Dalessandro

On 10/10/2020 4:57 AM, Xianting Tian wrote:

In architecture like powerpc, we can have cpus without any local memory
attached to it. In such cases the node does not have real memory.

Use local_memory_node(), which is guaranteed to have memory.
local_memory_node is a noop in other architectures that does not support
memoryless nodes.

Signed-off-by: Xianting Tian 
---
  drivers/infiniband/hw/hfi1/file_ops.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/hfi1/file_ops.c 
b/drivers/infiniband/hw/hfi1/file_ops.c
index 8ca51e43c..79fa22cc7 100644
--- a/drivers/infiniband/hw/hfi1/file_ops.c
+++ b/drivers/infiniband/hw/hfi1/file_ops.c
@@ -965,7 +965,7 @@ static int allocate_ctxt(struct hfi1_filedata *fd, struct 
hfi1_devdata *dd,
 */
fd->rec_cpu_num = hfi1_get_proc_affinity(dd->node);
if (fd->rec_cpu_num != -1)
-   numa = cpu_to_node(fd->rec_cpu_num);
+   numa = local_memory_node(cpu_to_node(fd->rec_cpu_num));
else
numa = numa_node_id();
ret = hfi1_create_ctxtdata(dd->pport, numa, &uctxt);



The hfi1 driver depends on X86_64. I'm not sure what this patch buys, 
can you expand a bit?


-Denny


Re: [PATCH] IB/rdmavt: Fix sizeof mismatch

2020-10-08 Thread dennis . dalessandro

On 2020-10-08 05:52, Colin King wrote:


From: Colin Ian King 

An incorrect sizeof is being used, struct rvt_ibport ** is not correct,
it should be struct rvt_ibport *. Note that since ** is the same size 
as

* this is not causing any issues.  Improve this fix by using
sizeof(*rdi->ports) as this allows us to not even reference the type
of the pointer.  Also remove line breaks as the entire statement can
fit on one line.

Addresses-Coverity: ("Sizeof not portable (SIZEOF_MISMATCH)")
Fixes: ff6acd69518e ("IB/rdmavt: Add device structure allocation")
Signed-off-by: Colin Ian King 
---
drivers/infiniband/sw/rdmavt/vt.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/infiniband/sw/rdmavt/vt.c 
b/drivers/infiniband/sw/rdmavt/vt.c

index f904bb34477a..2d534c450f3c 100644
--- a/drivers/infiniband/sw/rdmavt/vt.c
+++ b/drivers/infiniband/sw/rdmavt/vt.c
@@ -95,9 +95,7 @@ struct rvt_dev_info *rvt_alloc_device(size_t size, 
int nports)

if (!rdi)
return rdi;

-rdi->ports = kcalloc(nports,
- sizeof(struct rvt_ibport **),
- GFP_KERNEL);
+rdi->ports = kcalloc(nports, sizeof(*rdi->ports), GFP_KERNEL);
if (!rdi->ports)
ib_dealloc_device(&rdi->ibdev);


Acked-by: Dennis Dalessandro 


Re: [PATCH v3 8/9] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-09-21 Thread Dennis-YC Hsieh
Hi Matthias,


On Mon, 2020-09-21 at 18:19 +0200, Matthias Brugger wrote:
> 
> On 07/07/2020 17:45, Dennis YC Hsieh wrote:
> > Add clear parameter to let client decide if
> > event should be clear to 0 after GCE receive it.
> > 
> > Change since v2:
> > - Keep behavior in drm crtc driver and
> >separate bug fix code into another patch.
> 
> This, should go...
> 
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > ---
> 
> ...here :)
> 
> I fixed to commit message and pushed the patch to v5.9-next/soc

got it, thanks a lot


Regards,
Dennis

> 
> Thanks!
> 
> >   drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
> >   drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
> >   include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
> >   include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
> >   4 files changed, 8 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index ec6c9ffbf35e..c84e7a14d4a8 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
> > *mtk_crtc)
> > mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
> > cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
> > cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> > -   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
> > +   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, true);
> > mtk_crtc_ddp_config(crtc, cmdq_handle);
> > cmdq_pkt_finalize(cmdq_handle);
> > cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index d55dc3296105..505651b0d715 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -316,15 +316,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >   }
> >   EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
> >   
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
> >   {
> > struct cmdq_instruction inst = { {0} };
> > +   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
> >   
> > if (event >= CMDQ_MAX_EVENT)
> > return -EINVAL;
> >   
> > inst.op = CMDQ_CODE_WFE;
> > -   inst.value = CMDQ_WFE_OPTION;
> > +   inst.value = CMDQ_WFE_OPTION | clear_option;
> > inst.event = event;
> >   
> > return cmdq_pkt_append_command(pkt, inst);
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index efbd8a9eb2d1..d5a983d65f05 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -28,8 +28,7 @@
> >* bit 16-27: update value
> >* bit 31: 1 - update, 0 - no update
> >*/
> > -#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
> > CMDQ_WFE_WAIT | \
> > -   CMDQ_WFE_WAIT_VALUE)
> > +#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
> > CMDQ_WFE_WAIT_VALUE)
> >   
> >   /** cmdq event maximum */
> >   #define CMDQ_MAX_EVENT0x3ff
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 34354e952f60..960704d75994 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >   /**
> >* cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >* @pkt:  the CMDQ packet
> > - * @event: the desired event type to "wait and CLEAR"
> > + * @event: the desired event type to wait
> > + * @clear: clear event or not after event arrive
> >*
> >* Return: 0 for success; else the error code is returned
> >*/
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
> >   
> >   /**
> >* cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
> > 



[GIT PULL] percpu fix for v5.9-rc6

2020-09-17 Thread Dennis Zhou
Hi Linus,

This is a fix for the first chunk size calculation where the variable
length array incorrectly used # of longs instead of bytes of longs. This
came in as a code fix and not a bug report, so I don't think it was
widely problematic. I believe it worked out due to it being memblock
memory and alignment requirements working in our favor.

Thanks,
Dennis

The following changes since commit f75aef392f869018f78cfedf3c320a6b3fcfda6b:

  Linux 5.9-rc3 (2020-08-30 16:01:54 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git for-5.9-fixes

for you to fetch changes up to b3b33d3c43bbe0177d70653f4e889c78cc37f097:

  percpu: fix first chunk size calculation for populated bitmap (2020-09-17 
17:34:39 +)


Sunghyun Jin (1):
  percpu: fix first chunk size calculation for populated bitmap

 mm/percpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/percpu.c b/mm/percpu.c
index f4709629e6de..1ed1a349eab8 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1316,7 +1316,7 @@ static struct pcpu_chunk * __init 
pcpu_alloc_first_chunk(unsigned long tmp_addr,
 
/* allocate chunk */
alloc_size = sizeof(struct pcpu_chunk) +
-   BITS_TO_LONGS(region_size >> PAGE_SHIFT);
+   BITS_TO_LONGS(region_size >> PAGE_SHIFT) * sizeof(unsigned 
long);
chunk = memblock_alloc(alloc_size, SMP_CACHE_BYTES);
if (!chunk)
panic("%s: Failed to allocate %zu bytes\n", __func__,


RE: [PATCH] drm/amd/display: remove unintended executable mode

2020-08-20 Thread Li, Dennis
[AMD Official Use Only - Internal Distribution Only]

Hi, Lukas,
  Thanks for your fix. This issue was caused by that I modified these files 
in windows system with Samba. I will take care in the future. 

Best Regards
Dennis Li
-Original Message-
From: Lukas Bulwahn  
Sent: Wednesday, August 19, 2020 4:18 PM
To: Deucher, Alexander ; Koenig, Christian 
; Li, Dennis ; Zuo, Jerry 

Cc: amd-...@lists.freedesktop.org; dri-de...@lists.freedesktop.org; 
linux-kernel@vger.kernel.org; Chen, Guchun ; Wu, Hersen 
; Lukas Bulwahn 
Subject: [PATCH] drm/amd/display: remove unintended executable mode

Besides the intended change, commit 4cc1178e166a ("drm/amdgpu: replace DRM 
prefix with PCI device info for gfx/mmhub") also set the source files 
mmhub_v1_0.c and gfx_v9_4.c to be executable, i.e., changed fromold mode
644 to new mode 755.

Commit 241b2ec9317e ("drm/amd/display: Add dcn30 Headers (v2)") added the four 
header files {dpcs,dcn}_3_0_0_{offset,sh_mask}.h as executable, i.e., mode 755.

Set to the usual modes for source and headers files and clean up those 
mistakes. No functional change.

Signed-off-by: Lukas Bulwahn 
---
applies cleanly on current master and next-20200819

Alex, Christian, please pick this minor non-urgent cleanup patch.

Dennis, Jerry, please ack.

Dennis, Jerry, you might want to check your development environment introducing 
those executable modes on files.

 drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c | 0
 drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c   | 0
 drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_offset.h   | 0
 drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_sh_mask.h  | 0  
drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_offset.h  | 0  
drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_sh_mask.h | 0
 6 files changed, 0 insertions(+), 0 deletions(-)  mode change 100755 => 100644 
drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c
 mode change 100755 => 100644 drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
 mode change 100755 => 100644 
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_offset.h
 mode change 100755 => 100644 
drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_sh_mask.h
 mode change 100755 => 100644 
drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_offset.h
 mode change 100755 => 100644 
drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_sh_mask.h

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c
old mode 100755
new mode 100644
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c 
b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
old mode 100755
new mode 100644
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_offset.h 
b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_offset.h
old mode 100755
new mode 100644
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_sh_mask.h 
b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_0_0_sh_mask.h
old mode 100755
new mode 100644
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_offset.h 
b/drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_offset.h
old mode 100755
new mode 100644
diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_sh_mask.h 
b/drivers/gpu/drm/amd/include/asic_reg/dcn/dpcs_3_0_0_sh_mask.h
old mode 100755
new mode 100644
--
2.17.1


Good morning

2020-08-18 Thread Lisa Dennis
-- 
Hello. Greetings dd you received my previous email?


Re: [PATCH v3 00/11] i386 Clang support

2020-07-22 Thread Dennis Zhou
On Thu, Jul 23, 2020 at 01:08:42AM +0200, Thomas Gleixner wrote:
> Dennis Zhou  writes:
> > On Mon, Jul 20, 2020 at 01:49:14PM -0700, Nick Desaulniers wrote:
> >> Resend of Brian's v2 with Acks from Peter and Linus collected, as well
> >> as the final patch (mine) added. The commit of the final patch discusses
> >> some of the architectural differences between GCC and Clang, and the
> >> kernels tickling of this difference for i386, which necessitated these
> >> patches.
> >> 
> >> Brian Gerst (10):
> >>   x86/percpu: Introduce size abstraction macros
> >>   x86/percpu: Clean up percpu_to_op()
> >>   x86/percpu: Clean up percpu_from_op()
> >>   x86/percpu: Clean up percpu_add_op()
> >>   x86/percpu: Remove "e" constraint from XADD
> >>   x86/percpu: Clean up percpu_add_return_op()
> >>   x86/percpu: Clean up percpu_xchg_op()
> >>   x86/percpu: Clean up percpu_cmpxchg_op()
> >>   x86/percpu: Clean up percpu_stable_op()
> >>   x86/percpu: Remove unused PER_CPU() macro
> >> 
> >> Nick Desaulniers (1):
> >>   x86: support i386 with Clang
> >> 
> >>  arch/x86/include/asm/percpu.h  | 510 +++--
> >>  arch/x86/include/asm/uaccess.h |   4 +-
> >>  2 files changed, 175 insertions(+), 339 deletions(-)
> >> 
> >> -- 
> >> 2.28.0.rc0.105.gf9edc3c819-goog
> >> 
> >
> > This looks great to me! I applied it to for-5.9.
> 
> You applied it? I'm not aware that you're maintaining x86 nowadays.
> 
> Thanks,
> 
> tglx

I'm sorry I overstepped. I've dropped them. Please take them with my
ack.

Thanks,
Dennis


Re: [PATCH v3 00/11] i386 Clang support

2020-07-21 Thread Dennis Zhou
On Mon, Jul 20, 2020 at 01:49:14PM -0700, Nick Desaulniers wrote:
> Resend of Brian's v2 with Acks from Peter and Linus collected, as well
> as the final patch (mine) added. The commit of the final patch discusses
> some of the architectural differences between GCC and Clang, and the
> kernels tickling of this difference for i386, which necessitated these
> patches.
> 
> Brian Gerst (10):
>   x86/percpu: Introduce size abstraction macros
>   x86/percpu: Clean up percpu_to_op()
>   x86/percpu: Clean up percpu_from_op()
>   x86/percpu: Clean up percpu_add_op()
>   x86/percpu: Remove "e" constraint from XADD
>   x86/percpu: Clean up percpu_add_return_op()
>   x86/percpu: Clean up percpu_xchg_op()
>   x86/percpu: Clean up percpu_cmpxchg_op()
>   x86/percpu: Clean up percpu_stable_op()
>   x86/percpu: Remove unused PER_CPU() macro
> 
> Nick Desaulniers (1):
>   x86: support i386 with Clang
> 
>  arch/x86/include/asm/percpu.h  | 510 +++--
>  arch/x86/include/asm/uaccess.h |   4 +-
>  2 files changed, 175 insertions(+), 339 deletions(-)
> 
> -- 
> 2.28.0.rc0.105.gf9edc3c819-goog
> 

This looks great to me! I applied it to for-5.9.

Thanks,
Dennis


Greetings

2020-07-08 Thread Dennis Kosi
I am Mr.Dennis ,i work as an accountant in a bank.I am contacting you
independently of my investigation in my bank,i need your urgent
assistance in transferring the sum of $11.6million dollars to your
private bank account,the fund belongs to one of our foreign customer
who died a longtime with his supposed next of kin since July 22,
2003.The money has been here in our Bank lying dormant for years now
without anybody coming for the claim of it.

I want the bank to release the money to you as the relative and the
next of kin to our deceased customer,the Banking laws here does not
allow such money to stay more than 19years,because the money will be
recalled to the Bank treasury account as unclaimed fund.I am ready to
share with you 40% for you and 60% will be kept for me, by indicating
your interest i will send you the full details on how the business
will be executed.


[PATCH v3 7/9] soc: mediatek: cmdq: add jump function

2020-07-07 Thread Dennis YC Hsieh
Add jump function so that client can jump to any address which
contains instruction.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   13 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   11 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index b6e25f216605..d55dc3296105 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -13,6 +13,7 @@
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
 #define CMDQ_REG_TYPE  1
+#define CMDQ_JUMP_RELATIVE 1
 
 struct cmdq_instruction {
union {
@@ -407,6 +408,18 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_JUMP;
+   inst.offset = CMDQ_JUMP_RELATIVE;
+   inst.value = addr >>
+   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index d9390d76ee14..34354e952f60 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -253,6 +253,17 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
+ * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
+ *  to execute an instruction that change current thread PC to
+ *  a physical address which should contains more instruction.
+ * @pkt:the CMDQ packet
+ * @addr:   physical address of target instruction buffer
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+
+/**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:   the CMDQ packet
  *
-- 
1.7.9.5


[PATCH v3 5/9] soc: mediatek: cmdq: add write_s value function

2020-07-07 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes a constant value to address with large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   14 ++
 include/linux/soc/mediatek/mtk-cmdq.h  |   13 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index ed9f5e63c195..4e86b65815fc 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -280,6 +280,20 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
 
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index cd7ec714344e..ae73e10da274 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,19 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
  u16 addr_low, u16 src_reg_idx, u32 mask);
 
 /**
+ * cmdq_pkt_write_s_value() - append write_s command to the CMDQ packet which
+ *   write value to a physical address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v3 9/9] drm/mediatek: reduce clear event

2020-07-07 Thread Dennis YC Hsieh
No need to clear event again since event always clear before wait.
This fix depend on patch:
  "soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api"

Fixes: 2f965be7f9008 ("drm/mediatek: apply CMDQ control flow")
Signed-off-by: Dennis YC Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index c84e7a14d4a8..ba6cf956b239 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
-   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, true);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
-- 
1.7.9.5


[PATCH v3 2/9] soc: mediatek: cmdq: add write_s function

2020-07-07 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes value contains in internal register to address
with large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
 3 files changed, 39 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 9faf78fbed3a..880349b3f16c 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -18,6 +18,10 @@ struct cmdq_instruction {
union {
u32 value;
u32 mask;
+   struct {
+   u16 arg_c;
+   u16 src_reg;
+   };
};
union {
u16 offset;
@@ -223,6 +227,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 05eea1aef5aa..1f76cfedb16d 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 2249ecaf77e4..9b0c57a0063d 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -12,6 +12,8 @@
 #include 
 
 #define CMDQ_NO_TIMEOUT0xu
+#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
+#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
 
 struct cmdq_pkt;
 
@@ -103,6 +105,23 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
 /**
+ * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v3 1/9] soc: mediatek: cmdq: add address shift in jump

2020-07-07 Thread Dennis YC Hsieh
Add address shift when compose jump instruction
to compatible with 35bit format.

Change since v1:
- Rename cmdq_mbox_shift() to cmdq_get_shift_pa().

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index dc644cfb6419..9faf78fbed3a 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -329,7 +329,8 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
/* JUMP to end */
inst.op = CMDQ_CODE_JUMP;
-   inst.value = CMDQ_JUMP_PASS;
+   inst.value = CMDQ_JUMP_PASS >>
+   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
err = cmdq_pkt_append_command(pkt, inst);
 
return err;
-- 
1.7.9.5


[PATCH v3 4/9] soc: mediatek: cmdq: add read_s function

2020-07-07 Thread Dennis YC Hsieh
Add read_s function in cmdq helper functions which support read value from
register or dma physical address into gce internal register.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   12 
 3 files changed, 28 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 550e9e7e3ff2..ed9f5e63c195 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -227,6 +227,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_READ_S;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.reg_dst = reg_idx;
+   inst.src_reg = addr_low;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_read_s);
+
 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 90d1d8e64412..efbd8a9eb2d1 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_READ_S = 0x80,
CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 53230341bf94..cd7ec714344e 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -104,6 +104,18 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, 
int index,
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
+/*
+ * cmdq_pkt_read_s() - append read_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @reg_idx:   the CMDQ internal register ID to cache read data
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx);
+
 /**
  * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
1.7.9.5


[PATCH v3 3/9] soc: mediatek: cmdq: add write_s_mask function

2020-07-07 Thread Dennis YC Hsieh
add write_s_mask function in cmdq helper functions which
writes value contains in internal register to address
with mask and large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   23 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   18 ++
 3 files changed, 42 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 880349b3f16c..550e9e7e3ff2 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -242,6 +242,29 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s);
 
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.mask = 0;
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 1f76cfedb16d..90d1d8e64412 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -61,6 +61,7 @@ enum cmdq_code {
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
CMDQ_CODE_WRITE_S = 0x90,
+   CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 9b0c57a0063d..53230341bf94 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -122,6 +122,24 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx);
 
 /**
+ * cmdq_pkt_write_s_mask() - append write_s with mask command to the CMDQ 
packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ * @mask:  the specified target address mask, use U32_MAX if no need
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v3 0/9] support cmdq helper function on mt6779 platform

2020-07-07 Thread Dennis YC Hsieh
This patch support more gce helper function on mt6779 platform.

depends on patch: support gce on mt6779 platform

and depends on following applied patches
soc: mediatek: cmdq: add set event function
soc: mediatek: cmdq: export finalize function
soc: mediatek: cmdq: add assign function

Change since v2:
- Keep behavior in drm crtc driver and
  separate bug fix code into another patch.

Change since v1:
- Rename cmdq_mbox_shift() to cmdq_get_shift_pa().


Dennis YC Hsieh (9):
  soc: mediatek: cmdq: add address shift in jump
  soc: mediatek: cmdq: add write_s function
  soc: mediatek: cmdq: add write_s_mask function
  soc: mediatek: cmdq: add read_s function
  soc: mediatek: cmdq: add write_s value function
  soc: mediatek: cmdq: add write_s_mask value function
  soc: mediatek: cmdq: add jump function
  soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
  drm/mediatek: reduce clear event

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |   2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 113 ++-
 include/linux/mailbox/mtk-cmdq-mailbox.h |   6 +-
 include/linux/soc/mediatek/mtk-cmdq.h|  93 ++-
 4 files changed, 206 insertions(+), 8 deletions(-)

-- 
2.18.0

[PATCH v3 6/9] soc: mediatek: cmdq: add write_s_mask value function

2020-07-07 Thread Dennis YC Hsieh
add write_s_mask_value function in cmdq helper functions which
writes a constant value to address with mask and large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   21 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   15 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 4e86b65815fc..b6e25f216605 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -294,6 +294,27 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_value);
 
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index ae73e10da274..d9390d76ee14 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -165,6 +165,21 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
   u16 addr_low, u32 value);
 
 /**
+ * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ
+ *packet which write value to a physical
+ *address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ * @mask:  the specified target mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v3 8/9] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-07-07 Thread Dennis YC Hsieh
Add clear parameter to let client decide if
event should be clear to 0 after GCE receive it.

Change since v2:
- Keep behavior in drm crtc driver and
  separate bug fix code into another patch.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
 include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
 include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index ec6c9ffbf35e..c84e7a14d4a8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
-   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, true);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index d55dc3296105..505651b0d715 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -316,15 +316,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
 {
struct cmdq_instruction inst = { {0} };
+   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
 
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
 
inst.op = CMDQ_CODE_WFE;
-   inst.value = CMDQ_WFE_OPTION;
+   inst.value = CMDQ_WFE_OPTION | clear_option;
inst.event = event;
 
return cmdq_pkt_append_command(pkt, inst);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index efbd8a9eb2d1..d5a983d65f05 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -28,8 +28,7 @@
  * bit 16-27: update value
  * bit 31: 1 - update, 0 - no update
  */
-#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
CMDQ_WFE_WAIT | \
-   CMDQ_WFE_WAIT_VALUE)
+#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
CMDQ_WFE_WAIT_VALUE)
 
 /** cmdq event maximum */
 #define CMDQ_MAX_EVENT 0x3ff
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 34354e952f60..960704d75994 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
- * @event: the desired event type to "wait and CLEAR"
+ * @event: the desired event type to wait
+ * @clear: clear event or not after event arrive
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
 
 /**
  * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
-- 
1.7.9.5


Re: [mm] 4e2c82a409: ltp.overcommit_memory01.fail

2020-07-06 Thread Dennis Zhou
ndler(struct ctl_table *table, int write, void 
> *buffer,
>   size_t *lenp, loff_t *ppos)
>  {
>   int ret;
>  
>   ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
> - if (ret == 0 && write)
> + if (ret == 0 && write) {
> + if (sysctl_overcommit_memory == OVERCOMMIT_NEVER)
> + schedule_on_each_cpu(sync_overcommit_as);
> +
>   mm_compute_batch();
> + }
>  
>   return ret;
>  }
> -- 
> 2.7.4
>  
> 
> On Sun, Jul 05, 2020 at 10:36:14PM -0400, Qian Cai wrote:
> > > In my last email, I was not saying OVERCOMMIT_NEVER is not a normal case,
> > > but I don't think user will too frequently runtime change the overcommit
> > > policy. And the fix patch of syncing 'vm_committed_as' is only called when
> > > user calls 'sysctl -w vm.overcommit_memory=2'.
> > > 
> > > > The question is now if any of those regression fixes would now regress
> > > > performance of OVERCOMMIT_NEVER workloads or just in-par with the data
> > > > before the patchset?
> > > 
> > > For the original patchset, it keeps vm_committed_as unchanged for
> > > OVERCOMMIT_NEVER policy and enlarge it for the other 2 loose policies
> > > OVERCOMMIT_ALWAYS and OVERCOMMIT_GUESS, and I don't expect the 
> > > "OVERCOMMIT_NEVER
> > > workloads" performance  will be impacted. If you have suggetions for this
> > > kind of benchmarks, I can test them to better verify the patchset, thanks!
> > 
> > Then, please capture those information into a proper commit log when you
> > submit the regression fix on top of the patchset, and CC PER-CPU MEMORY
> > ALLOCATOR maintainers, so they might be able to review it properly.
> 
> 
> 

Thanks,
Dennis


Re: [PATCH v2 8/8] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-07-06 Thread Dennis-YC Hsieh
Hi CK,

Thanks for your comment.

On Tue, 2020-07-07 at 07:46 +0800, Chun-Kuang Hu wrote:
> Hi, Dennis:
> 
> Dennis YC Hsieh  於 2020年7月6日 週一 下午3:20寫道:
> >
> > Add clear parameter to let client decide if
> > event should be clear to 0 after GCE receive it.
> >
> > Fixes: 2f965be7f9008 ("drm/mediatek: apply CMDQ control flow")
> 
> I think this patch include two things, one is bug fix, another is
> changing interface.
> below is the bug fix part.
> 
> -#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE |
> CMDQ_WFE_WAIT | \
> -   CMDQ_WFE_WAIT_VALUE)
> +#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT |
> CMDQ_WFE_WAIT_VALUE)
> 
> the other is changing interface part. So this patch should be broken
> into two patches.

ok I'll break into two patches


Regards,
Dennis

> 
> Regards,
> Chun-Kuang.
> 
> > Signed-off-by: Dennis YC Hsieh 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
> >  include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
> >  4 files changed, 8 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index ec6c9ffbf35e..ba6cf956b239 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
> > *mtk_crtc)
> > mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
> > cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, 
> > PAGE_SIZE);
> > cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> > -   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
> > +   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
> > mtk_crtc_ddp_config(crtc, cmdq_handle);
> > cmdq_pkt_finalize(cmdq_handle);
> > cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index d55dc3296105..505651b0d715 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -316,15 +316,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
> >
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > +   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
> >
> > if (event >= CMDQ_MAX_EVENT)
> > return -EINVAL;
> >
> > inst.op = CMDQ_CODE_WFE;
> > -   inst.value = CMDQ_WFE_OPTION;
> > +   inst.value = CMDQ_WFE_OPTION | clear_option;
> > inst.event = event;
> >
> > return cmdq_pkt_append_command(pkt, inst);
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index efbd8a9eb2d1..d5a983d65f05 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -28,8 +28,7 @@
> >   * bit 16-27: update value
> >   * bit 31: 1 - update, 0 - no update
> >   */
> > -#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
> > CMDQ_WFE_WAIT | \
> > -   CMDQ_WFE_WAIT_VALUE)
> > +#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
> > CMDQ_WFE_WAIT_VALUE)
> >
> >  /** cmdq event maximum */
> >  #define CMDQ_MAX_EVENT 0x3ff
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 34354e952f60..960704d75994 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >  /**
> >   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >   * @pkt:   the CMDQ packet
> > - * @event: the desired event type to "wait and CLEAR"
> > + * @event: the desired event

Re: [PATCH v2 1/8] soc: mediatek: cmdq: add address shift in jump

2020-07-06 Thread Dennis-YC Hsieh
Hi Matthias,

thanks for your comment

On Mon, 2020-07-06 at 16:03 +0200, Matthias Brugger wrote:
> 
> On 05/07/2020 08:48, Dennis YC Hsieh wrote:
> > Add address shift when compose jump instruction
> > to compatible with 35bit format.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> 
> You are missing Bibby's Reviewed-by. Please honour the effort reviewers do by
> adding the appropriate tags.
> 
> Please double check the series and resend with all tags added.
> 
> Also, it would be good if you could provide a change log. That makes it easier
> for the maintainer to see which statements you addressed.

this patch changed since cmdq_mbox_shift() rename to cmdq_get_shift_pa()
by Bibby's comment [1], so I removed reviewed tags from this patch.

I'll provide change log to this patch and resend later, thanks.

[1]
http://lists.infradead.org/pipermail/linux-mediatek/2020-June/013387.html


Regards,
Dennis

> 
> Thanks,
> Matthias
> 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c |3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index dc644cfb6419..9faf78fbed3a 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -329,7 +329,8 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
> >  
> > /* JUMP to end */
> > inst.op = CMDQ_CODE_JUMP;
> > -   inst.value = CMDQ_JUMP_PASS;
> > +   inst.value = CMDQ_JUMP_PASS >>
> > +   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
> > err = cmdq_pkt_append_command(pkt, inst);
> >  
> > return err;
> > 



[PATCH v2 4/8] soc: mediatek: cmdq: add read_s function

2020-07-04 Thread Dennis YC Hsieh
Add read_s function in cmdq helper functions which support read value from
register or dma physical address into gce internal register.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   12 
 3 files changed, 28 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 550e9e7e3ff2..ed9f5e63c195 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -227,6 +227,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_READ_S;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.reg_dst = reg_idx;
+   inst.src_reg = addr_low;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_read_s);
+
 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 90d1d8e64412..efbd8a9eb2d1 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_READ_S = 0x80,
CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 53230341bf94..cd7ec714344e 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -104,6 +104,18 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, 
int index,
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
+/*
+ * cmdq_pkt_read_s() - append read_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @reg_idx:   the CMDQ internal register ID to cache read data
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx);
+
 /**
  * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
1.7.9.5


Subject: [PATCH v1 0/8] support cmdq helper function on mt6779 platform

2020-07-04 Thread Dennis YC Hsieh
This patch support more gce helper function on mt6779 platform.

depends on patch: support gce on mt6779 platform

and depends on following applied patches
soc: mediatek: cmdq: add set event function
soc: mediatek: cmdq: export finalize function
soc: mediatek: cmdq: add assign function

Change since v1:
- Rename cmdq_mbox_shift() to cmdq_get_shift_pa().


Dennis YC Hsieh (8):
  soc: mediatek: cmdq: add address shift in jump
  soc: mediatek: cmdq: add write_s function
  soc: mediatek: cmdq: add write_s_mask function
  soc: mediatek: cmdq: add read_s function
  soc: mediatek: cmdq: add write_s value function
  soc: mediatek: cmdq: add write_s_mask value function
  soc: mediatek: cmdq: add jump function
  soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |   2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 113 ++-
 include/linux/mailbox/mtk-cmdq-mailbox.h |   6 +-
 include/linux/soc/mediatek/mtk-cmdq.h|  93 ++-
 4 files changed, 206 insertions(+), 8 deletions(-)

-- 
2.18.0

[PATCH v2 3/8] soc: mediatek: cmdq: add write_s_mask function

2020-07-04 Thread Dennis YC Hsieh
add write_s_mask function in cmdq helper functions which
writes value contains in internal register to address
with mask and large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   23 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   18 ++
 3 files changed, 42 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 880349b3f16c..550e9e7e3ff2 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -242,6 +242,29 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s);
 
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.mask = 0;
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 1f76cfedb16d..90d1d8e64412 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -61,6 +61,7 @@ enum cmdq_code {
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
CMDQ_CODE_WRITE_S = 0x90,
+   CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 9b0c57a0063d..53230341bf94 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -122,6 +122,24 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx);
 
 /**
+ * cmdq_pkt_write_s_mask() - append write_s with mask command to the CMDQ 
packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ * @mask:  the specified target address mask, use U32_MAX if no need
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v2 5/8] soc: mediatek: cmdq: add write_s value function

2020-07-04 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes a constant value to address with large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   14 ++
 include/linux/soc/mediatek/mtk-cmdq.h  |   13 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index ed9f5e63c195..4e86b65815fc 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -280,6 +280,20 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
 
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index cd7ec714344e..ae73e10da274 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,19 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
  u16 addr_low, u16 src_reg_idx, u32 mask);
 
 /**
+ * cmdq_pkt_write_s_value() - append write_s command to the CMDQ packet which
+ *   write value to a physical address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v2 1/8] soc: mediatek: cmdq: add address shift in jump

2020-07-04 Thread Dennis YC Hsieh
Add address shift when compose jump instruction
to compatible with 35bit format.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index dc644cfb6419..9faf78fbed3a 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -329,7 +329,8 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
/* JUMP to end */
inst.op = CMDQ_CODE_JUMP;
-   inst.value = CMDQ_JUMP_PASS;
+   inst.value = CMDQ_JUMP_PASS >>
+   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
err = cmdq_pkt_append_command(pkt, inst);
 
return err;
-- 
1.7.9.5


[PATCH v2 7/8] soc: mediatek: cmdq: add jump function

2020-07-04 Thread Dennis YC Hsieh
Add jump function so that client can jump to any address which
contains instruction.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   13 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   11 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index b6e25f216605..d55dc3296105 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -13,6 +13,7 @@
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
 #define CMDQ_REG_TYPE  1
+#define CMDQ_JUMP_RELATIVE 1
 
 struct cmdq_instruction {
union {
@@ -407,6 +408,18 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_JUMP;
+   inst.offset = CMDQ_JUMP_RELATIVE;
+   inst.value = addr >>
+   cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index d9390d76ee14..34354e952f60 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -253,6 +253,17 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
+ * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
+ *  to execute an instruction that change current thread PC to
+ *  a physical address which should contains more instruction.
+ * @pkt:the CMDQ packet
+ * @addr:   physical address of target instruction buffer
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+
+/**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:   the CMDQ packet
  *
-- 
1.7.9.5


[PATCH v2 2/8] soc: mediatek: cmdq: add write_s function

2020-07-04 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes value contains in internal register to address
with large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
 3 files changed, 39 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 9faf78fbed3a..880349b3f16c 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -18,6 +18,10 @@ struct cmdq_instruction {
union {
u32 value;
u32 mask;
+   struct {
+   u16 arg_c;
+   u16 src_reg;
+   };
};
union {
u16 offset;
@@ -223,6 +227,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 05eea1aef5aa..1f76cfedb16d 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 2249ecaf77e4..9b0c57a0063d 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -12,6 +12,8 @@
 #include 
 
 #define CMDQ_NO_TIMEOUT0xu
+#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
+#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
 
 struct cmdq_pkt;
 
@@ -103,6 +105,23 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
 /**
+ * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v2 8/8] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-07-04 Thread Dennis YC Hsieh
Add clear parameter to let client decide if
event should be clear to 0 after GCE receive it.

Fixes: 2f965be7f9008 ("drm/mediatek: apply CMDQ control flow")
Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
 include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
 include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index ec6c9ffbf35e..ba6cf956b239 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -490,7 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
-   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index d55dc3296105..505651b0d715 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -316,15 +316,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
 {
struct cmdq_instruction inst = { {0} };
+   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
 
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
 
inst.op = CMDQ_CODE_WFE;
-   inst.value = CMDQ_WFE_OPTION;
+   inst.value = CMDQ_WFE_OPTION | clear_option;
inst.event = event;
 
return cmdq_pkt_append_command(pkt, inst);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index efbd8a9eb2d1..d5a983d65f05 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -28,8 +28,7 @@
  * bit 16-27: update value
  * bit 31: 1 - update, 0 - no update
  */
-#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
CMDQ_WFE_WAIT | \
-   CMDQ_WFE_WAIT_VALUE)
+#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
CMDQ_WFE_WAIT_VALUE)
 
 /** cmdq event maximum */
 #define CMDQ_MAX_EVENT 0x3ff
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 34354e952f60..960704d75994 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
- * @event: the desired event type to "wait and CLEAR"
+ * @event: the desired event type to wait
+ * @clear: clear event or not after event arrive
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
 
 /**
  * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
-- 
1.7.9.5


[PATCH v2 6/8] soc: mediatek: cmdq: add write_s_mask value function

2020-07-04 Thread Dennis YC Hsieh
add write_s_mask_value function in cmdq helper functions which
writes a constant value to address with mask and large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   21 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   15 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 4e86b65815fc..b6e25f216605 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -294,6 +294,27 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_value);
 
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index ae73e10da274..d9390d76ee14 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -165,6 +165,21 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
   u16 addr_low, u32 value);
 
 /**
+ * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ
+ *packet which write value to a physical
+ *address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ * @mask:  the specified target mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v8 2/4] mailbox: cmdq: variablize address shift in platform

2020-07-04 Thread Dennis YC Hsieh
Some gce hardware shift pc and end address in register to support
large dram addressing.
Implement gce address shift when write or read pc and end register.
And add shift bit in platform definition.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/mailbox/mtk-cmdq-mailbox.c   |   57 +++---
 include/linux/mailbox/mtk-cmdq-mailbox.h |2 ++
 2 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index b24822ad8409..49d9264145aa 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -75,8 +75,22 @@ struct cmdq {
struct cmdq_thread  *thread;
struct clk  *clock;
boolsuspended;
+   u8  shift_pa;
 };
 
+struct gce_plat {
+   u32 thread_nr;
+   u8 shift;
+};
+
+u8 cmdq_get_shift_pa(struct mbox_chan *chan)
+{
+   struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
+
+   return cmdq->shift_pa;
+}
+EXPORT_SYMBOL(cmdq_get_shift_pa);
+
 static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread *thread)
 {
u32 status;
@@ -183,13 +197,15 @@ static void cmdq_task_handle_error(struct cmdq_task *task)
 {
struct cmdq_thread *thread = task->thread;
struct cmdq_task *next_task;
+   struct cmdq *cmdq = task->cmdq;
 
-   dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
-   WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
+   dev_err(cmdq->mbox.dev, "task 0x%p error\n", task);
+   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
next_task = list_first_entry_or_null(&thread->task_busy_list,
struct cmdq_task, list_entry);
if (next_task)
-   writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
+   writel(next_task->pa_base >> cmdq->shift_pa,
+  thread->base + CMDQ_THR_CURR_ADDR);
cmdq_thread_resume(thread);
 }
 
@@ -219,7 +235,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
else
return;
 
-   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
+   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->shift_pa;
 
list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
 list_entry) {
@@ -335,27 +351,31 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, 
void *data)
WARN_ON(clk_enable(cmdq->clock) < 0);
WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
 
-   writel(task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
-   writel(task->pa_base + pkt->cmd_buf_size,
+   writel(task->pa_base >> cmdq->shift_pa,
+  thread->base + CMDQ_THR_CURR_ADDR);
+   writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
   thread->base + CMDQ_THR_END_ADDR);
+
writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABLE_TASK);
} else {
WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
-   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
-   end_pa = readl(thread->base + CMDQ_THR_END_ADDR);
+   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) <<
+   cmdq->shift_pa;
+   end_pa = readl(thread->base + CMDQ_THR_END_ADDR) <<
+   cmdq->shift_pa;
/* check boundary */
if (curr_pa == end_pa - CMDQ_INST_SIZE ||
curr_pa == end_pa) {
/* set to this task directly */
-   writel(task->pa_base,
+   writel(task->pa_base >> cmdq->shift_pa,
   thread->base + CMDQ_THR_CURR_ADDR);
} else {
cmdq_task_insert_into_thread(task);
smp_mb(); /* modify jump before enable thread */
}
-   writel(task->pa_base + pkt->cmd_buf_size,
+   writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
   thread->base + CMDQ_THR_END_ADDR);
cmdq_thread_resume(thread);
}
@@ -453,6 +473,7 @@ static int cmdq_probe(struct platform_device *pdev)
struct resource *res;
struct cmdq *cmdq;
int err, i;
+   struct gce_plat *plat_data;
 
cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL);
if (!cmdq)
@@ -471,7 +492,14 @@

[PATCH v8 0/4] support gce on mt6779 platform

2020-07-04 Thread Dennis YC Hsieh
This patch support gce on mt6779 platform.

Change since v7:
- Rename cmdq_mbox_shift() to cmdq_get_shift_pa().

Change since v6:
- Separate all helper function to another patchset.

Change since v5:
- spearate address shift code in client helper and mailbox controller
- separate write_s/write_s_mask and write_s_value/write_s_mask_value so that
  client can decide use mask or not
- fix typo in header

[... snip ...]


Dennis YC Hsieh (4):
  dt-binding: gce: add gce header file for mt6779
  mailbox: cmdq: variablize address shift in platform
  mailbox: cmdq: support mt6779 gce platform definition
  mailbox: mediatek: cmdq: clear task in channel before shutdown

 .../devicetree/bindings/mailbox/mtk-gce.txt   |   8 +-
 drivers/mailbox/mtk-cmdq-mailbox.c|  97 +++-
 include/dt-bindings/gce/mt6779-gce.h  | 222 ++
 include/linux/mailbox/mtk-cmdq-mailbox.h  |   2 +
 4 files changed, 313 insertions(+), 16 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt6779-gce.h

-- 
2.18.0

[PATCH v8 3/4] mailbox: cmdq: support mt6779 gce platform definition

2020-07-04 Thread Dennis YC Hsieh
Add gce v4 hardware support with different thread number and shift.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Reviewed-by: Matthias Brugger 
Reviewed-by: Bibby Hsieh 
---
 drivers/mailbox/mtk-cmdq-mailbox.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 49d9264145aa..08bd4f1eb469 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -564,10 +564,12 @@ static int cmdq_probe(struct platform_device *pdev)
 
 static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
 static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
+static const struct gce_plat gce_plat_v4 = {.thread_nr = 24, .shift = 3};
 
 static const struct of_device_id cmdq_of_ids[] = {
{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
+   {.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
{}
 };
 
-- 
1.7.9.5


[PATCH v8 1/4] dt-binding: gce: add gce header file for mt6779

2020-07-04 Thread Dennis YC Hsieh
Add documentation for the mt6779 gce.

Add gce header file defined the gce hardware event,
subsys number and constant for mt6779.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: Rob Herring 
Reviewed-by: CK Hu 
Reviewed-by: Bibby Hsieh 
---
 .../devicetree/bindings/mailbox/mtk-gce.txt|8 +-
 include/dt-bindings/gce/mt6779-gce.h   |  222 
 2 files changed, 227 insertions(+), 3 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt6779-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt 
b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 0b5b2a6bcc48..cf48cd806e00 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,7 +9,8 @@ CMDQ driver uses mailbox framework for communication. Please 
refer to
 mailbox.txt for generic information about mailbox device-tree bindings.
 
 Required properties:
-- compatible: can be "mediatek,mt8173-gce" or "mediatek,mt8183-gce"
+- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce" or
+  "mediatek,mt6779-gce".
 - reg: Address range of the GCE unit
 - interrupts: The interrupt signal from the GCE block
 - clock: Clocks according to the common clock binding
@@ -34,8 +35,9 @@ Optional properties for a client device:
   start_offset: the start offset of register address that GCE can access.
   size: the total size of register address that GCE can access.
 
-Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'
-or 'dt-binding/gce/mt8183-gce.h'. Such as sub-system ids, thread priority, 
event ids.
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h',
+'dt-binding/gce/mt8183-gce.h' or 'dt-bindings/gce/mt6779-gce.h'. Such as
+sub-system ids, thread priority, event ids.
 
 Example:
 
diff --git a/include/dt-bindings/gce/mt6779-gce.h 
b/include/dt-bindings/gce/mt6779-gce.h
new file mode 100644
index ..06101316ace4
--- /dev/null
+++ b/include/dt-bindings/gce/mt6779-gce.h
@@ -0,0 +1,222 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Dennis-YC Hsieh 
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT6779_H
+#define _DT_BINDINGS_GCE_MT6779_H
+
+#define CMDQ_NO_TIMEOUT0x
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST   0
+#define CMDQ_THR_PRIO_11
+#define CMDQ_THR_PRIO_22
+#define CMDQ_THR_PRIO_33
+#define CMDQ_THR_PRIO_44
+#define CMDQ_THR_PRIO_55
+#define CMDQ_THR_PRIO_66
+#define CMDQ_THR_PRIO_HIGHEST  7
+
+/* GCE subsys table */
+#define SUBSYS_13000
+#define SUBSYS_14001
+#define SUBSYS_14012
+#define SUBSYS_14023
+#define SUBSYS_15024
+#define SUBSYS_18805
+#define SUBSYS_18816
+#define SUBSYS_18827
+#define SUBSYS_18838
+#define SUBSYS_18849
+#define SUBSYS_100010
+#define SUBSYS_100111
+#define SUBSYS_100212
+#define SUBSYS_100313
+#define SUBSYS_100414
+#define SUBSYS_100515
+#define SUBSYS_102016
+#define SUBSYS_102817
+#define SUBSYS_170018
+#define SUBSYS_170119
+#define SUBSYS_170220
+#define SUBSYS_170321
+#define SUBSYS_180022
+#define SUBSYS_180123
+#define SUBSYS_180224
+#define SUBSYS_180425
+#define SUBSYS_180526
+#define SUBSYS_180827
+#define SUBSYS_180a28
+#define SUBSYS_180b29
+#define CMDQ_SUBSYS_OFF32
+
+/* GCE hardware events */
+#define CMDQ_EVENT_DISP_RDMA0_SOF  0
+#define CMDQ_EVENT_DISP_RDMA1_SOF  1
+#define CMDQ_EVENT_MDP_RDMA0_SOF   2
+#define CMDQ_EVENT_MDP_RDMA1_SOF   3
+#define CMDQ_EVENT_MDP_RSZ0_SOF4
+#define CMDQ_EVENT_MDP_RSZ1_SOF5
+#define CMDQ_EVENT_MDP_TDSHP_SOF   6
+#define CMDQ_EVENT_MDP_WROT0_SOF   7
+#define CMDQ_EVENT_MDP_WROT1_SOF   8
+#define CMDQ_EVENT_DISP_OVL0_SOF   9
+#define CMDQ_EVENT_DISP_2L_OVL0_SOF10
+#define CMDQ_EVENT_DISP_2L_OVL1_SOF11
+#define CMDQ_EVENT_DISP_WDMA0_SOF  12
+#define CMDQ_EVENT_DISP_COLOR0_SOF 13
+#define CMDQ_EVENT_DISP_CCORR0_SOF 14
+#define CMDQ_EVENT_DISP_AAL0_SOF   15
+#define CMDQ_EVENT_DISP_GAMMA0_SOF

[PATCH v8 4/4] mailbox: mediatek: cmdq: clear task in channel before shutdown

2020-07-04 Thread Dennis YC Hsieh
Do success callback in channel when shutdown. For those task not finish,
callback with error code thus client has chance to cleanup or reset.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Reviewed-by: Bibby Hsieh 
---
 drivers/mailbox/mtk-cmdq-mailbox.c |   38 
 1 file changed, 38 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 08bd4f1eb469..484d4438cd83 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -349,6 +349,12 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, 
void *data)
 
if (list_empty(&thread->task_busy_list)) {
WARN_ON(clk_enable(cmdq->clock) < 0);
+   /*
+* The thread reset will clear thread related register to 0,
+* including pc, end, priority, irq, suspend and enable. Thus
+* set CMDQ_THR_ENABLED to CMDQ_THR_ENABLE_TASK will enable
+* thread and make it running.
+*/
WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
 
writel(task->pa_base >> cmdq->shift_pa,
@@ -391,6 +397,38 @@ static int cmdq_mbox_startup(struct mbox_chan *chan)
 
 static void cmdq_mbox_shutdown(struct mbox_chan *chan)
 {
+   struct cmdq_thread *thread = (struct cmdq_thread *)chan->con_priv;
+   struct cmdq *cmdq = dev_get_drvdata(chan->mbox->dev);
+   struct cmdq_task *task, *tmp;
+   unsigned long flags;
+
+   spin_lock_irqsave(&thread->chan->lock, flags);
+   if (list_empty(&thread->task_busy_list))
+   goto done;
+
+   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
+
+   /* make sure executed tasks have success callback */
+   cmdq_thread_irq_handler(cmdq, thread);
+   if (list_empty(&thread->task_busy_list))
+   goto done;
+
+   list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
+list_entry) {
+   cmdq_task_exec_done(task, CMDQ_CB_ERROR);
+   kfree(task);
+   }
+
+   cmdq_thread_disable(cmdq, thread);
+   clk_disable(cmdq->clock);
+done:
+   /*
+* The thread->task_busy_list empty means thread already disable. The
+* cmdq_mbox_send_data() always reset thread which clear disable and
+* suspend statue when first pkt send to channel, so there is no need
+* to do any operation here, only unlock and leave.
+*/
+   spin_unlock_irqrestore(&thread->chan->lock, flags);
 }
 
 static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
-- 
1.7.9.5


Re: [PATCH v2 3/8] IB/hfi1: Convert PCIBIOS_* errors to generic -E* errors

2020-06-29 Thread Dennis Dalessandro

On 6/15/2020 3:32 AM, refactormys...@gmail.com wrote:

From: Bolarinwa Olayemi Saheed 

restore_pci_variables() and save_pci_variables() return PCIBIOS_ error
codes from PCIe capability accessors.

PCIBIOS_ error codes have positive values. Passing on these values is
inconsistent with functions which return only a negative value on failure.

Before passing on the return value of PCIe capability accessors, call
pcibios_err_to_errno() to convert any positive PCIBIOS_ error codes to
negative generic error values.

Fix redundant initialisation.

Suggested-by: Bjorn Helgaas 
Signed-off-by: Bolarinwa Olayemi Saheed 


Looks like we may have had a problem when calling 
pci_read_config_dword() from the init dd path and doing a check for < 0 
to bail. So this looks like goodness to me.


Reviewed-by: Dennis Dalessandro 


Re: [PATCH v2 2/8] IB/hfi1: Convert PCIBIOS_* errors to generic -E* errors

2020-06-29 Thread Dennis Dalessandro

On 6/15/2020 3:32 AM, refactormys...@gmail.com wrote:

From: Bolarinwa Olayemi Saheed 

pcie_speeds() returns PCIBIOS_ error codes from PCIe capability accessors.

PCIBIOS_ error codes have positive values. Passing on these values is
inconsistent with functions which return only a negative value on failure.

Before passing on the return value of PCIe capability accessors, call
pcibios_err_to_errno() to convert any positive PCIBIOS_ error codes to
negative generic error values.

Suggested-by: Bjorn Helgaas 
Signed-off-by: Bolarinwa Olayemi Saheed 
---
  drivers/infiniband/hw/hfi1/pcie.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/hfi1/pcie.c 
b/drivers/infiniband/hw/hfi1/pcie.c
index 1a6268d61977..eb53781d0c6a 100644
--- a/drivers/infiniband/hw/hfi1/pcie.c
+++ b/drivers/infiniband/hw/hfi1/pcie.c
@@ -306,7 +306,7 @@ int pcie_speeds(struct hfi1_devdata *dd)
ret = pcie_capability_read_dword(dd->pcidev, PCI_EXP_LNKCAP, &linkcap);
if (ret) {
dd_dev_err(dd, "Unable to read from PCI config\n");
-   return ret;
+   return pcibios_err_to_errno(ret);
}
  
  	if ((linkcap & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_8_0GB) {




Reviewed-by: Dennis Dalessandro 


Re: [PATCH] IB/hfi1: Add explicit cast OPA_MTU_8192 to 'enum ib_mtu'

2020-06-24 Thread Dennis Dalessandro

On 6/22/2020 8:52 PM, Nathan Chancellor wrote:

Clang warns:

drivers/infiniband/hw/hfi1/qp.c:198:9: warning: implicit conversion from
enumeration type 'enum opa_mtu' to different enumeration type 'enum
ib_mtu' [-Wenum-conversion]
 mtu = OPA_MTU_8192;
 ~ ^~~~
1 warning generated.

enum opa_mtu extends enum ib_mtu. There are typically two ways to deal
with this:

* Remove the expected types and just use 'int' for all parameters and
   types.

* Explicitly cast the enums between each other.

This driver chooses to do the later so do the same thing here.

Fixes: 6d72344cf6c4 ("IB/ipoib: Increase ipoib Datagram mode MTU's upper limit")
Link: https://github.com/ClangBuiltLinux/linux/issues/1062
Link: 
https://lore.kernel.org/linux-rdma/20200527040350.GA3118979@ubuntu-s3-xlarge-x86/
Signed-off-by: Nathan Chancellor 
---


Acked-by: Dennis Dalessandro 



Re: [PATCH v1 03/11] soc: mediatek: cmdq: add write_s function

2020-06-22 Thread Dennis-YC Hsieh
Hi Matthias,


On Mon, 2020-06-22 at 19:08 +0200, Matthias Brugger wrote:
> 
> On 22/06/2020 18:12, Dennis-YC Hsieh wrote:
> > Hi Matthias,
> > 
> > On Mon, 2020-06-22 at 17:54 +0200, Matthias Brugger wrote:
> >>
> >> On 22/06/2020 17:36, Dennis-YC Hsieh wrote:
> >>> Hi Matthias,
> >>>
> >>> thanks for your comment.
> >>>
> >>> On Mon, 2020-06-22 at 13:07 +0200, Matthias Brugger wrote:
> >>>>
> >>>> On 21/06/2020 16:18, Dennis YC Hsieh wrote:
> >>>>> add write_s function in cmdq helper functions which
> >>>>> writes value contains in internal register to address
> >>>>> with large dma access support.
> >>>>>
> >>>>> Signed-off-by: Dennis YC Hsieh 
> >>>>> ---
> >>>>>  drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
> >>>>>  include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
> >>>>>  include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
> >>>>>  3 files changed, 39 insertions(+)
> >>>>>
> >>>>> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> >>>>> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>>>> index bf32e3b2ca6c..817a5a97dbe5 100644
> >>>>> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>>>> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>>>> @@ -18,6 +18,10 @@ struct cmdq_instruction {
> >>>>> union {
> >>>>> u32 value;
> >>>>> u32 mask;
> >>>>> +   struct {
> >>>>> +   u16 arg_c;
> >>>>> +   u16 src_reg;
> >>>>> +   };
> >>>>> };
> >>>>> union {
> >>>>> u16 offset;
> >>>>> @@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> >>>>> subsys,
> >>>>>  }
> >>>>>  EXPORT_SYMBOL(cmdq_pkt_write_mask);
> >>>>>  
> >>>>> +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>>>> +u16 addr_low, u16 src_reg_idx)
> >>>>> +{
> >>>>
> >>>> Do I understand correctly that we use CMDQ_ADDR_HIGH(addr) and
> >>>> CMDQ_ADDR_LOW(addr) to calculate in the client high_addr_reg_idx and 
> >>>> addr_low
> >>>> respectively?
> >>>>
> >>>> In that case I think a better interface would be to pass the address and 
> >>>> do the
> >>>> high/low calculation in the cmdq_pkt_write_s
> >>>
> >>> Not exactly. The high_addr_reg_idx parameter is index of internal
> >>> register (which store address bit[47:16]), not result of
> >>> CMDQ_ADDR_HIGH(addr). 
> >>>
> >>> The CMDQ_ADDR_HIGH macro use in patch 02/11 cmdq_pkt_assign() api. This
> >>> api helps assign address bit[47:16] into one of internal register by
> >>> index. And same index could be use in cmdq_pkt_write_s(). The gce
> >>> combine bit[47:16] in internal register and bit[15:0] in addr_low
> >>> parameter to final address. So it is better to keep interface in this
> >>> way.
> >>>
> >>
> >> Got it, but then why don't we call cmdq_pkt_assign() in 
> >> cmdq_pkt_write_s()? This
> >> way we would get a clean API for what we want to do.
> >> Do we expect other users of cmdq_pkt_assign()? Otherwise we could keep it
> >> private the this file and don't export it.
> > 
> > Considering this case: write 2 register 0xaabb00c0 0xaabb00d0.
> > 
> > If we call assign inside write_s api it will be:
> > assign aabb to internal reg 0
> > write reg 0 + 0x00c0
> > assign aabb to internal reg 0
> > write reg 0 + 0x00d0
> > 
> > 
> > But if we let client decide timing to call assign, it will be like:
> > assign aabb to internal reg 0
> > write reg 0 + 0x00c0
> > write reg 0 + 0x00d0
> > 
> 
> Ok, thanks for clarification. Is this something you exepect to see in the gce
> consumer driver?
> 

yes it is, less command means better performance and save memory, so it
is a good practice for consumer.

> > 
> > The first way uses 4 command and second one uses only 3 comm

Re: [PATCH v1 03/11] soc: mediatek: cmdq: add write_s function

2020-06-22 Thread Dennis-YC Hsieh
Hi Matthias,

On Mon, 2020-06-22 at 17:54 +0200, Matthias Brugger wrote:
> 
> On 22/06/2020 17:36, Dennis-YC Hsieh wrote:
> > Hi Matthias,
> > 
> > thanks for your comment.
> > 
> > On Mon, 2020-06-22 at 13:07 +0200, Matthias Brugger wrote:
> >>
> >> On 21/06/2020 16:18, Dennis YC Hsieh wrote:
> >>> add write_s function in cmdq helper functions which
> >>> writes value contains in internal register to address
> >>> with large dma access support.
> >>>
> >>> Signed-off-by: Dennis YC Hsieh 
> >>> ---
> >>>  drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
> >>>  include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
> >>>  include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
> >>>  3 files changed, 39 insertions(+)
> >>>
> >>> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> >>> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> index bf32e3b2ca6c..817a5a97dbe5 100644
> >>> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> @@ -18,6 +18,10 @@ struct cmdq_instruction {
> >>>   union {
> >>>   u32 value;
> >>>   u32 mask;
> >>> + struct {
> >>> + u16 arg_c;
> >>> + u16 src_reg;
> >>> + };
> >>>   };
> >>>   union {
> >>>   u16 offset;
> >>> @@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> >>> subsys,
> >>>  }
> >>>  EXPORT_SYMBOL(cmdq_pkt_write_mask);
> >>>  
> >>> +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>> +  u16 addr_low, u16 src_reg_idx)
> >>> +{
> >>
> >> Do I understand correctly that we use CMDQ_ADDR_HIGH(addr) and
> >> CMDQ_ADDR_LOW(addr) to calculate in the client high_addr_reg_idx and 
> >> addr_low
> >> respectively?
> >>
> >> In that case I think a better interface would be to pass the address and 
> >> do the
> >> high/low calculation in the cmdq_pkt_write_s
> > 
> > Not exactly. The high_addr_reg_idx parameter is index of internal
> > register (which store address bit[47:16]), not result of
> > CMDQ_ADDR_HIGH(addr). 
> > 
> > The CMDQ_ADDR_HIGH macro use in patch 02/11 cmdq_pkt_assign() api. This
> > api helps assign address bit[47:16] into one of internal register by
> > index. And same index could be use in cmdq_pkt_write_s(). The gce
> > combine bit[47:16] in internal register and bit[15:0] in addr_low
> > parameter to final address. So it is better to keep interface in this
> > way.
> > 
> 
> Got it, but then why don't we call cmdq_pkt_assign() in cmdq_pkt_write_s()? 
> This
> way we would get a clean API for what we want to do.
> Do we expect other users of cmdq_pkt_assign()? Otherwise we could keep it
> private the this file and don't export it.

Considering this case: write 2 register 0xaabb00c0 0xaabb00d0.

If we call assign inside write_s api it will be:
assign aabb to internal reg 0
write reg 0 + 0x00c0
assign aabb to internal reg 0
write reg 0 + 0x00d0


But if we let client decide timing to call assign, it will be like:
assign aabb to internal reg 0
write reg 0 + 0x00c0
write reg 0 + 0x00d0


The first way uses 4 command and second one uses only 3 command.
Thus it is better to let client call assign explicitly.

> 
> By the way, why do you postfix the _s, I understand that it reflects the large
> DMA access but I wonder why you choose '_s'.
> 

The name of this command is "write_s" which is hardware spec.
I'm just following it since it is a common language between gce sw/hw
designers.


Regards,
Dennis

> Regards,
> Matthias
> 
> > 
> > Regards,
> > Dennis
> > 
> >>
> >> Regards,
> >> Matthias
> >>
> >>> + struct cmdq_instruction inst = {};
> >>> +
> >>> + inst.op = CMDQ_CODE_WRITE_S;
> >>> + inst.src_t = CMDQ_REG_TYPE;
> >>> + inst.sop = high_addr_reg_idx;
> >>> + inst.offset = addr_low;
> >>> + inst.src_reg = src_reg_idx;
> >>> +
> >>> + return cmdq_pkt_append_command(pkt, inst);
> >>> +}
> >>> +EXPORT_SYMBOL(cmdq_pkt_write_s);
> >>> +
> >>>  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >>>  {
> >>>   struct cmdq_instruction

Re: [PATCH v1 10/11] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-06-22 Thread Dennis-YC Hsieh
Hi Matthias,

thanks for your comment.

On Mon, 2020-06-22 at 13:19 +0200, Matthias Brugger wrote:
> 
> On 21/06/2020 16:18, Dennis YC Hsieh wrote:
> > Add clear parameter to let client decide if
> > event should be clear to 0 after GCE receive it.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > Reviewed-by: CK Hu 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
> >  include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
> >  4 files changed, 8 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > index 7daaabc26eb1..a065b3a412cf 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> > @@ -488,7 +488,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
> > *mtk_crtc)
> > if (mtk_crtc->cmdq_client) {
> > cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
> > cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
> > -   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
> > +   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
> 
> This does not set CMDQ_WFE_UPDATE while the old code did. Is this a bug fix 
> or a
> bug in the code?
> If it's a fix, please provide a fixes tag.

no need to to update again since event always clear before wait.
I'll provide a fix tag, thanks.


Regards,
Dennis

> 
> Thanks,
> Matthias
> 
> > mtk_crtc_ddp_config(crtc, cmdq_handle);
> > cmdq_pkt_finalize(cmdq_handle);
> > cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index 009f86ae72c6..13f78c9b5901 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -315,15 +315,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
> >  
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > +   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
> >  
> > if (event >= CMDQ_MAX_EVENT)
> > return -EINVAL;
> >  
> > inst.op = CMDQ_CODE_WFE;
> > -   inst.value = CMDQ_WFE_OPTION;
> > +   inst.value = CMDQ_WFE_OPTION | clear_option;
> > inst.event = event;
> >  
> > return cmdq_pkt_append_command(pkt, inst);
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index 3f6bc0dfd5da..42d2a30e6a70 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -27,8 +27,7 @@
> >   * bit 16-27: update value
> >   * bit 31: 1 - update, 0 - no update
> >   */
> > -#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
> > CMDQ_WFE_WAIT | \
> > -   CMDQ_WFE_WAIT_VALUE)
> > +#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
> > CMDQ_WFE_WAIT_VALUE)
> >  
> >  /** cmdq event maximum */
> >  #define CMDQ_MAX_EVENT 0x3ff
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 18364d81e8f7..4b5f5d154bad 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, 
> > u8 high_addr_reg_idx,
> >  /**
> >   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >   * @pkt:   the CMDQ packet
> > - * @event: the desired event type to "wait and CLEAR"
> > + * @event: the desired event type to wait
> > + * @clear: clear event or not after event arrive
> >   *
> >   * Return: 0 for success; else the error code is returned
> >   */
> > -int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
> > +int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
> >  
> >  /**
> >   * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
> > 



Re: [PATCH v1 03/11] soc: mediatek: cmdq: add write_s function

2020-06-22 Thread Dennis-YC Hsieh
Hi Matthias,

thanks for your comment.

On Mon, 2020-06-22 at 13:07 +0200, Matthias Brugger wrote:
> 
> On 21/06/2020 16:18, Dennis YC Hsieh wrote:
> > add write_s function in cmdq helper functions which
> > writes value contains in internal register to address
> > with large dma access support.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > ---
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
> >  include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
> >  3 files changed, 39 insertions(+)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> > b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > index bf32e3b2ca6c..817a5a97dbe5 100644
> > --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> > +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> > @@ -18,6 +18,10 @@ struct cmdq_instruction {
> > union {
> > u32 value;
> > u32 mask;
> > +   struct {
> > +   u16 arg_c;
> > +   u16 src_reg;
> > +   };
> > };
> > union {
> > u16 offset;
> > @@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> > subsys,
> >  }
> >  EXPORT_SYMBOL(cmdq_pkt_write_mask);
> >  
> > +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> > +u16 addr_low, u16 src_reg_idx)
> > +{
> 
> Do I understand correctly that we use CMDQ_ADDR_HIGH(addr) and
> CMDQ_ADDR_LOW(addr) to calculate in the client high_addr_reg_idx and addr_low
> respectively?
> 
> In that case I think a better interface would be to pass the address and do 
> the
> high/low calculation in the cmdq_pkt_write_s

Not exactly. The high_addr_reg_idx parameter is index of internal
register (which store address bit[47:16]), not result of
CMDQ_ADDR_HIGH(addr). 

The CMDQ_ADDR_HIGH macro use in patch 02/11 cmdq_pkt_assign() api. This
api helps assign address bit[47:16] into one of internal register by
index. And same index could be use in cmdq_pkt_write_s(). The gce
combine bit[47:16] in internal register and bit[15:0] in addr_low
parameter to final address. So it is better to keep interface in this
way.


Regards,
Dennis

> 
> Regards,
> Matthias
> 
> > +   struct cmdq_instruction inst = {};
> > +
> > +   inst.op = CMDQ_CODE_WRITE_S;
> > +   inst.src_t = CMDQ_REG_TYPE;
> > +   inst.sop = high_addr_reg_idx;
> > +   inst.offset = addr_low;
> > +   inst.src_reg = src_reg_idx;
> > +
> > +   return cmdq_pkt_append_command(pkt, inst);
> > +}
> > +EXPORT_SYMBOL(cmdq_pkt_write_s);
> > +
> >  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >  {
> > struct cmdq_instruction inst = { {0} };
> > diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
> > b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > index 121c3bb6d3de..ee67dd3b86f5 100644
> > --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> > +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> > @@ -59,6 +59,7 @@ enum cmdq_code {
> > CMDQ_CODE_JUMP = 0x10,
> > CMDQ_CODE_WFE = 0x20,
> > CMDQ_CODE_EOC = 0x40,
> > +   CMDQ_CODE_WRITE_S = 0x90,
> > CMDQ_CODE_LOGIC = 0xa0,
> >  };
> >  
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 83340211e1d3..e1c5a7549b4f 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -12,6 +12,8 @@
> >  #include 
> >  
> >  #define CMDQ_NO_TIMEOUT0xu
> > +#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
> > +#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
> >  
> >  struct cmdq_pkt;
> >  
> > @@ -103,6 +105,23 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 
> > subsys,
> > u16 offset, u32 value, u32 mask);
> >  
> >  /**
> > + * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
> > + * @pkt:   the CMDQ packet
> > + * @high_addr_reg_idx: internal register ID which contains high 
> > address of pa
> > + * @addr_low:  low address of pa
> > + * @src_reg_idx:   the CMDQ internal register ID which cache source value
> > + *
> > + * Return: 0 for success; else the error code is returned
> > + *
> > + * Support write value to physical address without subsys. Use 
> > CMDQ_ADDR_HIGH()
> > + * to get high address and call cmdq_pkt_assign() to assign value into 
> > internal
> > + * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter 
> > when
> > + * call to this function.
> > + */
> > +int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> > +u16 addr_low, u16 src_reg_idx);
> > +
> > +/**
> >   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >   * @pkt:   the CMDQ packet
> >   * @event: the desired event type to "wait and CLEAR"
> > 



Re: [PATCH v1 0/11] support cmdq helper function on mt6779 platform

2020-06-22 Thread Dennis-YC Hsieh
Hi Bibby,


On Mon, 2020-06-22 at 10:40 +0800, Bibby Hsieh wrote:
> Hi, Dennis,
> 
> Please add "depends on patch: support gce on mt6779 platform" in cover
> letter. Thanks

ok will do, thanks


Regards,
Dennis


> 
> Bibby
> 
> On Sun, 2020-06-21 at 22:18 +0800, Dennis YC Hsieh wrote:
> > This patch support cmdq helper function on mt6779 platform,
> > based on "support gce on mt6779 platform" patchset.
> > 
> > 
> > Dennis YC Hsieh (11):
> >   soc: mediatek: cmdq: add address shift in jump
> >   soc: mediatek: cmdq: add assign function
> >   soc: mediatek: cmdq: add write_s function
> >   soc: mediatek: cmdq: add write_s_mask function
> >   soc: mediatek: cmdq: add read_s function
> >   soc: mediatek: cmdq: add write_s value function
> >   soc: mediatek: cmdq: add write_s_mask value function
> >   soc: mediatek: cmdq: export finalize function
> >   soc: mediatek: cmdq: add jump function
> >   soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
> >   soc: mediatek: cmdq: add set event function
> > 
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |   3 +-
> >  drivers/soc/mediatek/mtk-cmdq-helper.c   | 159 +--
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |   8 +-
> >  include/linux/soc/mediatek/mtk-cmdq.h| 124 +-
> >  4 files changed, 280 insertions(+), 14 deletions(-)
> > 
> 
> 



Re: [PATCH v7 2/4] mailbox: cmdq: variablize address shift in platform

2020-06-22 Thread Dennis-YC Hsieh
Hi Bibby,

Thanks for your comment.

On Mon, 2020-06-22 at 10:33 +0800, Bibby Hsieh wrote:
> On Sun, 2020-06-21 at 21:22 +0800, Dennis YC Hsieh wrote:
> > Some gce hardware shift pc and end address in register to support
> > large dram addressing.
> > Implement gce address shift when write or read pc and end register.
> > And add shift bit in platform definition.
> > 
> > Signed-off-by: Dennis YC Hsieh 
> > ---
> >  drivers/mailbox/mtk-cmdq-mailbox.c   |   61 
> > ++
> >  include/linux/mailbox/mtk-cmdq-mailbox.h |2 +
> >  2 files changed, 48 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
> > b/drivers/mailbox/mtk-cmdq-mailbox.c
> > index 9a6ce9f5a7db..4dbee9258127 100644
> > --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> > +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> > @@ -76,8 +76,22 @@ struct cmdq {
> > struct cmdq_thread  *thread;
> > struct clk  *clock;
> > boolsuspended;
> > +   u8  shift_pa;
> >  };
> >  
> > +struct gce_plat {
> > +   u32 thread_nr;
> > +   u8 shift;
> > +};
> > +
> > +u8 cmdq_mbox_shift(struct mbox_chan *chan)
> 
> How about rename this function as cmdq_get_shift_pa()?

ok, I'll rename it, thanks


Regards,
Dennis


> 
> 
> Bibby
> 
> > +{
> > +   struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
> > +
> > +   return cmdq->shift_pa;
> > +}
> > +EXPORT_SYMBOL(cmdq_mbox_shift);
> > +
> >  static int cmdq_thread_suspend(struct cmdq *cmdq, struct cmdq_thread 
> > *thread)
> >  {
> > u32 status;
> > @@ -183,7 +197,7 @@ static void cmdq_task_remove_wfe(struct cmdq_task *task)
> > for (i = 0; i < CMDQ_NUM_CMD(task->pkt); i++)
> > if (cmdq_command_is_wfe(base[i]))
> > base[i] = (u64)CMDQ_JUMP_BY_OFFSET << 32 |
> > - CMDQ_JUMP_PASS;
> > + CMDQ_JUMP_PASS >> task->cmdq->shift_pa;
> > dma_sync_single_for_device(dev, task->pa_base, task->pkt->cmd_buf_size,
> >DMA_TO_DEVICE);
> >  }
> > @@ -221,13 +235,15 @@ static void cmdq_task_handle_error(struct cmdq_task 
> > *task)
> >  {
> > struct cmdq_thread *thread = task->thread;
> > struct cmdq_task *next_task;
> > +   struct cmdq *cmdq = task->cmdq;
> >  
> > -   dev_err(task->cmdq->mbox.dev, "task 0x%p error\n", task);
> > -   WARN_ON(cmdq_thread_suspend(task->cmdq, thread) < 0);
> > +   dev_err(cmdq->mbox.dev, "task 0x%p error\n", task);
> > +   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
> > next_task = list_first_entry_or_null(&thread->task_busy_list,
> > struct cmdq_task, list_entry);
> > if (next_task)
> > -   writel(next_task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
> > +   writel(next_task->pa_base >> cmdq->shift_pa,
> > +  thread->base + CMDQ_THR_CURR_ADDR);
> > cmdq_thread_resume(thread);
> >  }
> >  
> > @@ -257,7 +273,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
> > else
> > return;
> >  
> > -   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR);
> > +   curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->shift_pa;
> >  
> > list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
> >  list_entry) {
> > @@ -373,16 +389,20 @@ static int cmdq_mbox_send_data(struct mbox_chan 
> > *chan, void *data)
> > WARN_ON(clk_enable(cmdq->clock) < 0);
> > WARN_ON(cmdq_thread_reset(cmdq, thread) < 0);
> >  
> > -   writel(task->pa_base, thread->base + CMDQ_THR_CURR_ADDR);
> > -   writel(task->pa_base + pkt->cmd_buf_size,
> > +   writel(task->pa_base >> cmdq->shift_pa,
> > +  thread->base + CMDQ_THR_CURR_ADDR);
> > +   writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->shift_pa,
> >thread->base + CMDQ_THR_END_ADDR);
> > +
> > writel(thread->priority, thread->base + CMDQ_THR_PRIORITY);
> > writel(CMDQ_THR_IRQ_EN, thread->base + CMDQ_THR_IRQ_ENABLE);
> > writel(CMDQ_THR_ENABLED, thread->base + CMDQ_THR_ENABL

[PATCH v1 02/11] soc: mediatek: cmdq: add assign function

2020-06-21 Thread Dennis YC Hsieh
Add assign function in cmdq helper which assign constant value into
internal register by index.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   24 +++-
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   14 ++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 98f23ba3ba47..bf32e3b2ca6c 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -12,6 +12,7 @@
 #define CMDQ_WRITE_ENABLE_MASK BIT(0)
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
+#define CMDQ_REG_TYPE  1
 
 struct cmdq_instruction {
union {
@@ -21,8 +22,17 @@ struct cmdq_instruction {
union {
u16 offset;
u16 event;
+   u16 reg_dst;
+   };
+   union {
+   u8 subsys;
+   struct {
+   u8 sop:5;
+   u8 arg_c_t:1;
+   u8 src_t:1;
+   u8 dst_t:1;
+   };
};
-   u8 subsys;
u8 op;
 };
 
@@ -277,6 +287,18 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_poll_mask);
 
+int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_LOGIC;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.reg_dst = reg_idx;
+   inst.value = value;
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_assign);
+
 static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index dfe5b2eb85cc..121c3bb6d3de 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -59,6 +59,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_LOGIC = 0xa0,
 };
 
 enum cmdq_cb_status {
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index a74c1d5acdf3..83340211e1d3 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,20 @@ int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
  */
 int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
   u16 offset, u32 value, u32 mask);
+
+/**
+ * cmdq_pkt_assign() - Append logic assign command to the CMDQ packet, ask GCE
+ *to execute an instruction that set a constant value into
+ *internal register and use as value, mask or address in
+ *read/write instruction.
+ * @pkt:   the CMDQ packet
+ * @reg_idx:   the CMDQ internal register ID
+ * @value: the specified value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
+
 /**
  * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
  *  packet and call back at the end of done packet
-- 
1.7.9.5


[PATCH v1 04/11] soc: mediatek: cmdq: add write_s_mask function

2020-06-21 Thread Dennis YC Hsieh
add write_s_mask function in cmdq helper functions which
writes value contains in internal register to address
with mask and large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   23 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   18 ++
 3 files changed, 42 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 817a5a97dbe5..13b888779093 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -241,6 +241,29 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s);
 
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.mask = 0;
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index ee67dd3b86f5..8ef87e1bd03b 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -60,6 +60,7 @@ enum cmdq_code {
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
CMDQ_CODE_WRITE_S = 0x90,
+   CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index e1c5a7549b4f..ca9c75fd8125 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -122,6 +122,24 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx);
 
 /**
+ * cmdq_pkt_write_s_mask() - append write_s with mask command to the CMDQ 
packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ * @mask:  the specified target address mask, use U32_MAX if no need
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+ u16 addr_low, u16 src_reg_idx, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v1 03/11] soc: mediatek: cmdq: add write_s function

2020-06-21 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes value contains in internal register to address
with large dma access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   19 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   19 +++
 3 files changed, 39 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index bf32e3b2ca6c..817a5a97dbe5 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -18,6 +18,10 @@ struct cmdq_instruction {
union {
u32 value;
u32 mask;
+   struct {
+   u16 arg_c;
+   u16 src_reg;
+   };
};
union {
u16 offset;
@@ -222,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.src_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.src_reg = src_reg_idx;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 121c3bb6d3de..ee67dd3b86f5 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -59,6 +59,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_LOGIC = 0xa0,
 };
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 83340211e1d3..e1c5a7549b4f 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -12,6 +12,8 @@
 #include 
 
 #define CMDQ_NO_TIMEOUT0xu
+#define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
+#define CMDQ_ADDR_LOW(addr)((u16)(addr) | BIT(1))
 
 struct cmdq_pkt;
 
@@ -103,6 +105,23 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
 /**
+ * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @src_reg_idx:   the CMDQ internal register ID which cache source value
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Support write value to physical address without subsys. Use CMDQ_ADDR_HIGH()
+ * to get high address and call cmdq_pkt_assign() to assign value into internal
+ * reg. Also use CMDQ_ADDR_LOW() to get low address for addr_low parameter when
+ * call to this function.
+ */
+int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
+u16 addr_low, u16 src_reg_idx);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v1 01/11] soc: mediatek: cmdq: add address shift in jump

2020-06-21 Thread Dennis YC Hsieh
Add address shift when compose jump instruction
to compatible with 35bit format.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index c67081759728..98f23ba3ba47 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -291,7 +291,8 @@ static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
/* JUMP to end */
inst.op = CMDQ_CODE_JUMP;
-   inst.value = CMDQ_JUMP_PASS;
+   inst.value = CMDQ_JUMP_PASS >>
+   cmdq_mbox_shift(((struct cmdq_client *)pkt->cl)->chan);
err = cmdq_pkt_append_command(pkt, inst);
 
return err;
-- 
1.7.9.5


[PATCH v1 11/11] soc: mediatek: cmdq: add set event function

2020-06-21 Thread Dennis YC Hsieh
Add set event function in cmdq helper functions to set specific event.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|9 +
 3 files changed, 25 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 13f78c9b5901..e6133a42d229 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -346,6 +346,21 @@ int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
 }
 EXPORT_SYMBOL(cmdq_pkt_clear_event);
 
+int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event)
+{
+   struct cmdq_instruction inst = {};
+
+   if (event >= CMDQ_MAX_EVENT)
+   return -EINVAL;
+
+   inst.op = CMDQ_CODE_WFE;
+   inst.value = CMDQ_WFE_UPDATE | CMDQ_WFE_UPDATE_VALUE;
+   inst.event = event;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_set_event);
+
 int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
  u16 offset, u32 value)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 42d2a30e6a70..ba2d811183a9 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -17,6 +17,7 @@
 #define CMDQ_JUMP_PASS CMDQ_INST_SIZE
 
 #define CMDQ_WFE_UPDATEBIT(31)
+#define CMDQ_WFE_UPDATE_VALUE  BIT(16)
 #define CMDQ_WFE_WAIT  BIT(15)
 #define CMDQ_WFE_WAIT_VALUE0x1
 
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 4b5f5d154bad..960704d75994 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -199,6 +199,15 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
 
 /**
+ * cmdq_pkt_set_event() - append set event command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @event: the desired event to be set
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event);
+
+/**
  * cmdq_pkt_poll() - Append polling command to the CMDQ packet, ask GCE to
  *  execute an instruction that wait for a specified
  *  hardware register to check for the value w/o mask.
-- 
1.7.9.5


[PATCH v1 10/11] soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api

2020-06-21 Thread Dennis YC Hsieh
Add clear parameter to let client decide if
event should be clear to 0 after GCE receive it.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |2 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   |5 +++--
 include/linux/mailbox/mtk-cmdq-mailbox.h |3 +--
 include/linux/soc/mediatek/mtk-cmdq.h|5 +++--
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 7daaabc26eb1..a065b3a412cf 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -488,7 +488,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
if (mtk_crtc->cmdq_client) {
cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
-   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
+   cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 009f86ae72c6..13f78c9b5901 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -315,15 +315,16 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
 {
struct cmdq_instruction inst = { {0} };
+   u32 clear_option = clear ? CMDQ_WFE_UPDATE : 0;
 
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
 
inst.op = CMDQ_CODE_WFE;
-   inst.value = CMDQ_WFE_OPTION;
+   inst.value = CMDQ_WFE_OPTION | clear_option;
inst.event = event;
 
return cmdq_pkt_append_command(pkt, inst);
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 3f6bc0dfd5da..42d2a30e6a70 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -27,8 +27,7 @@
  * bit 16-27: update value
  * bit 31: 1 - update, 0 - no update
  */
-#define CMDQ_WFE_OPTION(CMDQ_WFE_UPDATE | 
CMDQ_WFE_WAIT | \
-   CMDQ_WFE_WAIT_VALUE)
+#define CMDQ_WFE_OPTION(CMDQ_WFE_WAIT | 
CMDQ_WFE_WAIT_VALUE)
 
 /** cmdq event maximum */
 #define CMDQ_MAX_EVENT 0x3ff
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 18364d81e8f7..4b5f5d154bad 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -182,11 +182,12 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
- * @event: the desired event type to "wait and CLEAR"
+ * @event: the desired event type to wait
+ * @clear: clear event or not after event arrive
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
 
 /**
  * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
-- 
1.7.9.5


[PATCH v1 05/11] soc: mediatek: cmdq: add read_s function

2020-06-21 Thread Dennis YC Hsieh
Add read_s function in cmdq helper functions which support read value from
register or dma physical address into gce internal register.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   |   15 +++
 include/linux/mailbox/mtk-cmdq-mailbox.h |1 +
 include/linux/soc/mediatek/mtk-cmdq.h|   12 
 3 files changed, 28 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 13b888779093..58075589509b 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -226,6 +226,21 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_READ_S;
+   inst.dst_t = CMDQ_REG_TYPE;
+   inst.sop = high_addr_reg_idx;
+   inst.reg_dst = reg_idx;
+   inst.src_reg = addr_low;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_read_s);
+
 int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
 u16 addr_low, u16 src_reg_idx)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h 
b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 8ef87e1bd03b..3f6bc0dfd5da 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -59,6 +59,7 @@ enum cmdq_code {
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
+   CMDQ_CODE_READ_S = 0x80,
CMDQ_CODE_WRITE_S = 0x90,
CMDQ_CODE_WRITE_S_MASK = 0x91,
CMDQ_CODE_LOGIC = 0xa0,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index ca9c75fd8125..40fe1eb52190 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -104,6 +104,18 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, 
int index,
 int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask);
 
+/*
+ * cmdq_pkt_read_s() - append read_s command to the CMDQ packet
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @reg_idx:   the CMDQ internal register ID to cache read data
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx, u16 addr_low,
+   u16 reg_idx);
+
 /**
  * cmdq_pkt_write_s() - append write_s command to the CMDQ packet
  * @pkt:   the CMDQ packet
-- 
1.7.9.5


[PATCH v1 07/11] soc: mediatek: cmdq: add write_s_mask value function

2020-06-21 Thread Dennis YC Hsieh
add write_s_mask_value function in cmdq helper functions which
writes a constant value to address with mask and large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   21 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   15 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 2ad78df46636..e372ae065240 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -293,6 +293,27 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_value);
 
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask)
+{
+   struct cmdq_instruction inst = {};
+   int err;
+
+   inst.op = CMDQ_CODE_MASK;
+   inst.mask = ~mask;
+   err = cmdq_pkt_append_command(pkt, inst);
+   if (err < 0)
+   return err;
+
+   inst.op = CMDQ_CODE_WRITE_S_MASK;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 7f1c115a66b8..6e8caacedc80 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -165,6 +165,21 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 
high_addr_reg_idx,
   u16 addr_low, u32 value);
 
 /**
+ * cmdq_pkt_write_s_mask_value() - append write_s command with mask to the CMDQ
+ *packet which write value to a physical
+ *address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ * @mask:  the specified target mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+   u16 addr_low, u32 value, u32 mask);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v1 09/11] soc: mediatek: cmdq: add jump function

2020-06-21 Thread Dennis YC Hsieh
Add jump function so that client can jump to any address which
contains instruction.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   13 +
 include/linux/soc/mediatek/mtk-cmdq.h  |   11 +++
 2 files changed, 24 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 248945108a36..009f86ae72c6 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -13,6 +13,7 @@
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_ENBIT(0)
 #define CMDQ_REG_TYPE  1
+#define CMDQ_JUMP_RELATIVE 1
 
 struct cmdq_instruction {
union {
@@ -391,6 +392,18 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_JUMP;
+   inst.offset = CMDQ_JUMP_RELATIVE;
+   inst.value = addr >>
+   cmdq_mbox_shift(((struct cmdq_client *)pkt->cl)->chan);
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump);
+
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index eac1405e4872..18364d81e8f7 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -244,6 +244,17 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
+ * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
+ *  to execute an instruction that change current thread PC to
+ *  a physical address which should contains more instruction.
+ * @pkt:the CMDQ packet
+ * @addr:   physical address of target instruction buffer
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+
+/**
  * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:   the CMDQ packet
  *
-- 
1.7.9.5


[PATCH v1 06/11] soc: mediatek: cmdq: add write_s value function

2020-06-21 Thread Dennis YC Hsieh
add write_s function in cmdq helper functions which
writes a constant value to address with large dma
access support.

Signed-off-by: Dennis YC Hsieh 
---
 drivers/soc/mediatek/mtk-cmdq-helper.c |   14 ++
 include/linux/soc/mediatek/mtk-cmdq.h  |   13 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 58075589509b..2ad78df46636 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -279,6 +279,20 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask);
 
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value)
+{
+   struct cmdq_instruction inst = {};
+
+   inst.op = CMDQ_CODE_WRITE_S;
+   inst.sop = high_addr_reg_idx;
+   inst.offset = addr_low;
+   inst.value = value;
+
+   return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_write_s_value);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
struct cmdq_instruction inst = { {0} };
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 40fe1eb52190..7f1c115a66b8 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -152,6 +152,19 @@ int cmdq_pkt_write_s_mask(struct cmdq_pkt *pkt, u16 
high_addr_reg_idx,
  u16 addr_low, u16 src_reg_idx, u32 mask);
 
 /**
+ * cmdq_pkt_write_s_value() - append write_s command to the CMDQ packet which
+ *   write value to a physical address
+ * @pkt:   the CMDQ packet
+ * @high_addr_reg_idx: internal register ID which contains high address of pa
+ * @addr_low:  low address of pa
+ * @value: the specified target value
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
+  u16 addr_low, u32 value);
+
+/**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:   the CMDQ packet
  * @event: the desired event type to "wait and CLEAR"
-- 
1.7.9.5


[PATCH v1 08/11] soc: mediatek: cmdq: export finalize function

2020-06-21 Thread Dennis YC Hsieh
Export finalize function to client which helps append eoc and jump
command to pkt. Let client decide call finalize or not.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Acked-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |1 +
 drivers/soc/mediatek/mtk-cmdq-helper.c  |7 ++-
 include/linux/soc/mediatek/mtk-cmdq.h   |8 
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 0dfcd1787e65..7daaabc26eb1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -490,6 +490,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc 
*mtk_crtc)
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event);
mtk_crtc_ddp_config(crtc, cmdq_handle);
+   cmdq_pkt_finalize(cmdq_handle);
cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
}
 #endif
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
b/drivers/soc/mediatek/mtk-cmdq-helper.c
index e372ae065240..248945108a36 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -391,7 +391,7 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 
value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
-static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
+int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
struct cmdq_instruction inst = { {0} };
int err;
@@ -411,6 +411,7 @@ static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 
return err;
 }
+EXPORT_SYMBOL(cmdq_pkt_finalize);
 
 static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
 {
@@ -445,10 +446,6 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, 
cmdq_async_flush_cb cb,
unsigned long flags = 0;
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
 
-   err = cmdq_pkt_finalize(pkt);
-   if (err < 0)
-   return err;
-
pkt->cb.cb = cb;
pkt->cb.data = data;
pkt->async_cb.cb = cmdq_pkt_flush_async_cb;
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
b/include/linux/soc/mediatek/mtk-cmdq.h
index 6e8caacedc80..eac1405e4872 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -244,6 +244,14 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
+ * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
+ * @pkt:   the CMDQ packet
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
+
+/**
  * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
  *  packet and call back at the end of done packet
  * @pkt:   the CMDQ packet
-- 
1.7.9.5


[PATCH v1 0/11] support cmdq helper function on mt6779 platform

2020-06-21 Thread Dennis YC Hsieh
This patch support cmdq helper function on mt6779 platform,
based on "support gce on mt6779 platform" patchset.


Dennis YC Hsieh (11):
  soc: mediatek: cmdq: add address shift in jump
  soc: mediatek: cmdq: add assign function
  soc: mediatek: cmdq: add write_s function
  soc: mediatek: cmdq: add write_s_mask function
  soc: mediatek: cmdq: add read_s function
  soc: mediatek: cmdq: add write_s value function
  soc: mediatek: cmdq: add write_s_mask value function
  soc: mediatek: cmdq: export finalize function
  soc: mediatek: cmdq: add jump function
  soc: mediatek: cmdq: add clear option in cmdq_pkt_wfe api
  soc: mediatek: cmdq: add set event function

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  |   3 +-
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 159 +--
 include/linux/mailbox/mtk-cmdq-mailbox.h |   8 +-
 include/linux/soc/mediatek/mtk-cmdq.h| 124 +-
 4 files changed, 280 insertions(+), 14 deletions(-)

-- 
2.18.0

[PATCH v7 3/4] mailbox: cmdq: support mt6779 gce platform definition

2020-06-21 Thread Dennis YC Hsieh
Add gce v4 hardware support with different thread number and shift.

Signed-off-by: Dennis YC Hsieh 
Reviewed-by: CK Hu 
Reviewed-by: Matthias Brugger 
---
 drivers/mailbox/mtk-cmdq-mailbox.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c 
b/drivers/mailbox/mtk-cmdq-mailbox.c
index 4dbee9258127..9994ac9426d6 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -572,10 +572,12 @@ static int cmdq_probe(struct platform_device *pdev)
 
 static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
 static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
+static const struct gce_plat gce_plat_v4 = {.thread_nr = 24, .shift = 3};
 
 static const struct of_device_id cmdq_of_ids[] = {
{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
+   {.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
{}
 };
 
-- 
1.7.9.5


  1   2   3   4   5   6   7   >