Re: [PATCH -next v6 0/2] Make memory reclamation measurable

2024-01-14 Thread Bixuan Cui

ping~

在 2024/1/5 9:36, Bixuan Cui 写道:

When the system memory is low, kswapd reclaims the memory. The key steps
of memory reclamation include
1.shrink_lruvec
   * shrink_active_list, moves folios from the active LRU to the inactive LRU
   * shrink_inactive_list, shrink lru from inactive LRU list
2.shrink_slab
   * shrinker->count_objects(), calculates the freeable memory
   * shrinker->scan_objects(), reclaims the slab memory

The existing tracers in the vmscan are as follows:

--do_try_to_free_pages
--shrink_zones
--trace_mm_vmscan_node_reclaim_begin (tracer)
--shrink_node
--shrink_node_memcgs
   --trace_mm_vmscan_memcg_shrink_begin (tracer)
   --shrink_lruvec
 --shrink_list
   --shrink_active_list
  --trace_mm_vmscan_lru_shrink_active (tracer)
   --shrink_inactive_list
  --trace_mm_vmscan_lru_shrink_inactive (tracer)
 --shrink_active_list
   --shrink_slab
 --do_shrink_slab
 --shrinker->count_objects()
 --trace_mm_shrink_slab_start (tracer)
 --shrinker->scan_objects()
 --trace_mm_shrink_slab_end (tracer)
   --trace_mm_vmscan_memcg_shrink_end (tracer)
--trace_mm_vmscan_node_reclaim_end (tracer)

If we get the duration and quantity of shrink lru and slab,
then we can measure the memory recycling, as follows

Measuring memory reclamation with bpf:
   LRU FILE:
CPU COMMShrinkActive(us) ShrinkInactive(us)  Reclaim(page)
7   kswapd0 26  51  32
7   kswapd0 52  47  13
   SLAB:
CPU COMMOBJ_NAMECount_Dur(us) 
Freeable(page) Scan_Dur(us) Reclaim(page)
 1  kswapd0 super_cache_scan.cfi_jt 2   341 
   3225 128
 7  kswapd0 super_cache_scan.cfi_jt 0   
2247   8524 1024
 7  kswapd0 super_cache_scan.cfi_jt 23670   
   00

For this, add the new tracer to shrink_active_list/shrink_inactive_list
and shrinker->count_objects().

Changes:
v6: * Add Reviewed-by from Steven Rostedt.
v5: * Use 'DECLARE_EVENT_CLASS(mm_vmscan_lru_shrink_start_template' to
replace 'RACE_EVENT(mm_vmscan_lru_shrink_inactive/active_start'
 * Add the explanation for adding new shrink lru events into 'mm: vmscan: 
add new event to trace shrink lru'
v4: Add Reviewed-by and Changlog to every patch.
v3: Swap the positions of 'nid' and 'freeable' to prevent the hole in the trace 
event.
v2: Modify trace_mm_vmscan_lru_shrink_inactive() in evict_folios() at the same 
time to fix build error.

cuibixuan (2):
   mm: shrinker: add new event to trace shrink count
   mm: vmscan: add new event to trace shrink lru

  include/trace/events/vmscan.h | 80 ++-
  mm/shrinker.c |  4 ++
  mm/vmscan.c   | 11 +++--
  3 files changed, 90 insertions(+), 5 deletions(-)





[RFC PATCH 4/4] mm/damon: introduce DAMOS_PROMOTE action for promotion

2024-01-14 Thread Honggyu Kim
From: Hyeongtak Ji 

This patch introduces DAMOS_PROMOTE action for paddr mode.

It includes renaming alloc_demote_folio to alloc_migrate_folio to use it
for promotion as well.

The execution sequence of DAMOS_DEMOTE and DAMOS_PROMOTE look as
follows for comparison.

  DAMOS_DEMOTE action
damo_pa_apply_scheme
-> damon_pa_reclaim
-> demote_pages
-> do_demote_folio_list
-> __demote_folio_list
-> demote_folio_list

  DAMOS_PROMOTE action
damo_pa_apply_scheme
-> damon_pa_promote
-> promote_pages
-> do_promote_folio_list
-> __promote_folio_list
-> promote_folio_list

Signed-off-by: Hyeongtak Ji 
Signed-off-by: Honggyu Kim 
---
 include/linux/damon.h  |   2 +
 include/linux/migrate_mode.h   |   1 +
 include/linux/vm_event_item.h  |   1 +
 include/trace/events/migrate.h |   3 +-
 mm/damon/paddr.c   |  29 
 mm/damon/sysfs-schemes.c   |   1 +
 mm/internal.h  |   1 +
 mm/vmscan.c| 129 -
 mm/vmstat.c|   1 +
 9 files changed, 165 insertions(+), 3 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index 4c0a0fef09c5..477060bb6718 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -107,6 +107,7 @@ struct damon_target {
  * @DAMOS_LRU_DEPRIO:  Deprioritize the region on its LRU lists.
  * @DAMOS_STAT:Do nothing but count the stat.
  * @DAMOS_DEMOTE:  Do demotion for the current region.
+ * @DAMOS_PROMOTE: Do promotion if possible, otherwise do nothing.
  * @NR_DAMOS_ACTIONS:  Total number of DAMOS actions
  *
  * The support of each action is up to running  damon_operations.
@@ -125,6 +126,7 @@ enum damos_action {
DAMOS_LRU_DEPRIO,
DAMOS_STAT, /* Do nothing but only record the stat */
DAMOS_DEMOTE,
+   DAMOS_PROMOTE,
NR_DAMOS_ACTIONS,
 };
 
diff --git a/include/linux/migrate_mode.h b/include/linux/migrate_mode.h
index f37cc03f9369..63f75eb9abf3 100644
--- a/include/linux/migrate_mode.h
+++ b/include/linux/migrate_mode.h
@@ -29,6 +29,7 @@ enum migrate_reason {
MR_CONTIG_RANGE,
MR_LONGTERM_PIN,
MR_DEMOTION,
+   MR_PROMOTION,
MR_TYPES
 };
 
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index 8abfa1240040..63cf920afeaa 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -44,6 +44,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
PGDEMOTE_KSWAPD,
PGDEMOTE_DIRECT,
PGDEMOTE_KHUGEPAGED,
+   PGPROMOTE,
PGSCAN_KSWAPD,
PGSCAN_DIRECT,
PGSCAN_KHUGEPAGED,
diff --git a/include/trace/events/migrate.h b/include/trace/events/migrate.h
index 0190ef725b43..f0dd569c1e62 100644
--- a/include/trace/events/migrate.h
+++ b/include/trace/events/migrate.h
@@ -22,7 +22,8 @@
EM( MR_NUMA_MISPLACED,  "numa_misplaced")   \
EM( MR_CONTIG_RANGE,"contig_range") \
EM( MR_LONGTERM_PIN,"longterm_pin") \
-   EMe(MR_DEMOTION,"demotion")
+   EM( MR_DEMOTION,"demotion") \
+   EMe(MR_PROMOTION,   "promotion")
 
 /*
  * First define the enums in the above macros to be exported to userspace
diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
index d3e3f077cd00..360ce69d5898 100644
--- a/mm/damon/paddr.c
+++ b/mm/damon/paddr.c
@@ -257,6 +257,32 @@ static unsigned long damon_pa_reclaim(struct damon_region 
*r, struct damos *s, b
return applied * PAGE_SIZE;
 }
 
+static unsigned long damon_pa_promote(struct damon_region *r, struct damos *s)
+{
+   unsigned long addr, applied;
+   LIST_HEAD(folio_list);
+
+   for (addr = r->ar.start; addr < r->ar.end; addr += PAGE_SIZE) {
+   struct folio *folio = damon_get_folio(PHYS_PFN(addr));
+
+   if (!folio)
+   continue;
+
+   if (damos_pa_filter_out(s, folio))
+   goto put_folio;
+
+   if (!folio_isolate_lru(folio))
+   goto put_folio;
+
+   list_add(>lru, _list);
+put_folio:
+   folio_put(folio);
+   }
+   applied = promote_pages(_list);
+   cond_resched();
+   return applied * PAGE_SIZE;
+}
+
 static inline unsigned long damon_pa_mark_accessed_or_deactivate(
struct damon_region *r, struct damos *s, bool mark_accessed)
 {
@@ -309,6 +335,8 @@ static unsigned long damon_pa_apply_scheme(struct damon_ctx 
*ctx,
break;
case DAMOS_DEMOTE:
return damon_pa_reclaim(r, scheme, true);
+   case DAMOS_PROMOTE:
+   return damon_pa_promote(r, scheme);
default:
/* DAMOS actions that not yet supported by 'paddr'. */
break;
@@ -326,6 +354,7 @@ static int 

[RFC PATCH 2/4] mm/damon: introduce DAMOS_DEMOTE action for demotion

2024-01-14 Thread Honggyu Kim
This patch introduces DAMOS_DEMOTE action, which is similar to
DAMOS_PAGEOUT, but demote folios instead of swapping them out.

Since there are some common routines with pageout, many functions have
similar logics between pageout and demote.

The execution sequence of DAMOS_PAGEOUT and DAMOS_DEMOTE look as follows.

  DAMOS_PAGEOUT action
damo_pa_apply_scheme
-> damon_pa_reclaim
-> reclaim_pages
-> reclaim_folio_list
-> shrink_folio_list

  DAMOS_DEMOTE action
damo_pa_apply_scheme
-> damon_pa_reclaim
-> demote_pages
-> do_demote_folio_list
-> __demote_folio_list
-> demote_folio_list

__demote_folio_list() is a minimized version of shrink_folio_list(), but
it's minified only for demotion.

Signed-off-by: Honggyu Kim 
---
 include/linux/damon.h|  2 +
 mm/damon/paddr.c | 17 +---
 mm/damon/sysfs-schemes.c |  1 +
 mm/internal.h|  1 +
 mm/vmscan.c  | 84 
 5 files changed, 99 insertions(+), 6 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index e00ddf1ed39c..4c0a0fef09c5 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -106,6 +106,7 @@ struct damon_target {
  * @DAMOS_LRU_PRIO:Prioritize the region on its LRU lists.
  * @DAMOS_LRU_DEPRIO:  Deprioritize the region on its LRU lists.
  * @DAMOS_STAT:Do nothing but count the stat.
+ * @DAMOS_DEMOTE:  Do demotion for the current region.
  * @NR_DAMOS_ACTIONS:  Total number of DAMOS actions
  *
  * The support of each action is up to running  damon_operations.
@@ -123,6 +124,7 @@ enum damos_action {
DAMOS_LRU_PRIO,
DAMOS_LRU_DEPRIO,
DAMOS_STAT, /* Do nothing but only record the stat */
+   DAMOS_DEMOTE,
NR_DAMOS_ACTIONS,
 };
 
diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
index 081e2a325778..d3e3f077cd00 100644
--- a/mm/damon/paddr.c
+++ b/mm/damon/paddr.c
@@ -224,7 +224,7 @@ static bool damos_pa_filter_out(struct damos *scheme, 
struct folio *folio)
return false;
 }
 
-static unsigned long damon_pa_pageout(struct damon_region *r, struct damos *s)
+static unsigned long damon_pa_reclaim(struct damon_region *r, struct damos *s, 
bool is_demote)
 {
unsigned long addr, applied;
LIST_HEAD(folio_list);
@@ -242,14 +242,17 @@ static unsigned long damon_pa_pageout(struct damon_region 
*r, struct damos *s)
folio_test_clear_young(folio);
if (!folio_isolate_lru(folio))
goto put_folio;
-   if (folio_test_unevictable(folio))
+   if (folio_test_unevictable(folio) && !is_demote)
folio_putback_lru(folio);
else
list_add(>lru, _list);
 put_folio:
folio_put(folio);
}
-   applied = reclaim_pages(_list);
+   if (is_demote)
+   applied = demote_pages(_list);
+   else
+   applied = reclaim_pages(_list);
cond_resched();
return applied * PAGE_SIZE;
 }
@@ -297,13 +300,15 @@ static unsigned long damon_pa_apply_scheme(struct 
damon_ctx *ctx,
 {
switch (scheme->action) {
case DAMOS_PAGEOUT:
-   return damon_pa_pageout(r, scheme);
+   return damon_pa_reclaim(r, scheme, false);
case DAMOS_LRU_PRIO:
return damon_pa_mark_accessed(r, scheme);
case DAMOS_LRU_DEPRIO:
return damon_pa_deactivate_pages(r, scheme);
case DAMOS_STAT:
break;
+   case DAMOS_DEMOTE:
+   return damon_pa_reclaim(r, scheme, true);
default:
/* DAMOS actions that not yet supported by 'paddr'. */
break;
@@ -317,11 +322,11 @@ static int damon_pa_scheme_score(struct damon_ctx 
*context,
 {
switch (scheme->action) {
case DAMOS_PAGEOUT:
+   case DAMOS_LRU_DEPRIO:
+   case DAMOS_DEMOTE:
return damon_cold_score(context, r, scheme);
case DAMOS_LRU_PRIO:
return damon_hot_score(context, r, scheme);
-   case DAMOS_LRU_DEPRIO:
-   return damon_cold_score(context, r, scheme);
default:
break;
}
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index fe0fe2562000..ac7cd3f17b12 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -1187,6 +1187,7 @@ static const char * const damon_sysfs_damos_action_strs[] 
= {
"lru_prio",
"lru_deprio",
"stat",
+   "demote",
 };
 
 static struct damon_sysfs_scheme *damon_sysfs_scheme_alloc(
diff --git a/mm/internal.h b/mm/internal.h
index b61034bd50f5..2380397ec2f3 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -869,6 +869,7 @@ extern void set_pageblock_order(void);
 unsigned long reclaim_pages(struct list_head *folio_list);
 unsigned int reclaim_clean_pages_from_list(struct zone *zone,
  

[RFC PATCH 3/4] mm/memory-tiers: add next_promotion_node to find promotion target

2024-01-14 Thread Honggyu Kim
From: Hyeongtak Ji 

This patch adds next_promotion_node that can be used to identify the
appropriate promotion target based on memory tiers.  When multiple
promotion target nodes are available, the nearest node is selected based
on numa distance.

Signed-off-by: Hyeongtak Ji 
---
 include/linux/memory-tiers.h | 11 +
 mm/memory-tiers.c| 43 
 2 files changed, 54 insertions(+)

diff --git a/include/linux/memory-tiers.h b/include/linux/memory-tiers.h
index 1e39d27bee41..0788e435fc50 100644
--- a/include/linux/memory-tiers.h
+++ b/include/linux/memory-tiers.h
@@ -50,6 +50,7 @@ int mt_set_default_dram_perf(int nid, struct node_hmem_attrs 
*perf,
 int mt_perf_to_adistance(struct node_hmem_attrs *perf, int *adist);
 #ifdef CONFIG_MIGRATION
 int next_demotion_node(int node);
+int next_promotion_node(int node);
 void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets);
 bool node_is_toptier(int node);
 #else
@@ -58,6 +59,11 @@ static inline int next_demotion_node(int node)
return NUMA_NO_NODE;
 }
 
+static inline int next_promotion_node(int node)
+{
+   return NUMA_NO_NODE;
+}
+
 static inline void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t 
*targets)
 {
*targets = NODE_MASK_NONE;
@@ -101,6 +107,11 @@ static inline int next_demotion_node(int node)
return NUMA_NO_NODE;
 }
 
+static inline int next_promotion_node(int node)
+{
+   return NUMA_NO_NODE;
+}
+
 static inline void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t 
*targets)
 {
*targets = NODE_MASK_NONE;
diff --git a/mm/memory-tiers.c b/mm/memory-tiers.c
index 8d5291add2bc..0060ee571cf4 100644
--- a/mm/memory-tiers.c
+++ b/mm/memory-tiers.c
@@ -335,6 +335,49 @@ int next_demotion_node(int node)
return target;
 }
 
+/*
+ * Select a promotion target that is close to the from node among the given
+ * two nodes.
+ *
+ * TODO: consider other decision policy as node_distance may not be precise.
+ */
+static int select_promotion_target(int a, int b, int from)
+{
+   if (node_distance(from, a) < node_distance(from, b))
+   return a;
+   else
+   return b;
+}
+
+/**
+ * next_promotion_node() - Get the next node in the promotion path
+ * @node: The starting node to lookup the next node
+ *
+ * Return: node id for next memory node in the promotion path hierarchy
+ * from @node; NUMA_NO_NODE if @node is the toptier.
+ */
+int next_promotion_node(int node)
+{
+   int target = NUMA_NO_NODE;
+   int nid;
+
+   if (node_is_toptier(node))
+   return NUMA_NO_NODE;
+
+   rcu_read_lock();
+   for_each_node_state(nid, N_MEMORY) {
+   if (node_isset(node, node_demotion[nid].preferred)) {
+   if (target == NUMA_NO_NODE)
+   target = nid;
+   else
+   target = select_promotion_target(nid, target, 
node);
+   }
+   }
+   rcu_read_unlock();
+
+   return target;
+}
+
 static void disable_all_demotion_targets(void)
 {
struct memory_tier *memtier;
-- 
2.34.1




[RFC PATCH 1/4] mm/vmscan: refactor reclaim_pages with reclaim_or_migrate_folios

2024-01-14 Thread Honggyu Kim
Since we will introduce reclaim_pages like functions such as
demote_pages and promote_pages, the most of the code can be shared.

This is a preparation patch that introduces reclaim_or_migrate_folios()
to cover all the logics, but it provides a handler for the different
actions.

No functional changes applied.

Signed-off-by: Honggyu Kim 
---
 mm/vmscan.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index bba207f41b14..7ca2396ccc3b 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2107,15 +2107,16 @@ static unsigned int reclaim_folio_list(struct list_head 
*folio_list,
return nr_reclaimed;
 }
 
-unsigned long reclaim_pages(struct list_head *folio_list)
+static unsigned long reclaim_or_migrate_folios(struct list_head *folio_list,
+   unsigned int (*handler)(struct list_head *, struct pglist_data 
*))
 {
int nid;
-   unsigned int nr_reclaimed = 0;
+   unsigned int nr_folios = 0;
LIST_HEAD(node_folio_list);
unsigned int noreclaim_flag;
 
if (list_empty(folio_list))
-   return nr_reclaimed;
+   return nr_folios;
 
noreclaim_flag = memalloc_noreclaim_save();
 
@@ -2129,15 +2130,20 @@ unsigned long reclaim_pages(struct list_head 
*folio_list)
continue;
}
 
-   nr_reclaimed += reclaim_folio_list(_folio_list, 
NODE_DATA(nid));
+   nr_folios += handler(_folio_list, NODE_DATA(nid));
nid = folio_nid(lru_to_folio(folio_list));
} while (!list_empty(folio_list));
 
-   nr_reclaimed += reclaim_folio_list(_folio_list, NODE_DATA(nid));
+   nr_folios += handler(_folio_list, NODE_DATA(nid));
 
memalloc_noreclaim_restore(noreclaim_flag);
 
-   return nr_reclaimed;
+   return nr_folios;
+}
+
+unsigned long reclaim_pages(struct list_head *folio_list)
+{
+   return reclaim_or_migrate_folios(folio_list, reclaim_folio_list);
 }
 
 static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
-- 
2.34.1




[RFC PATCH 0/4] DAMON based 2-tier memory management for CXL memory

2024-01-14 Thread Honggyu Kim
There was an RFC IDEA "DAMOS-based Tiered-Memory Management" previously
posted at [1].

It says there is no implementation of the demote/promote DAMOS action
are made.  This RFC is about its implementation for physical address
space.


Introduction


With the advent of CXL/PCIe attached DRAM, which will be called simply
as CXL memory in this cover letter, some systems are becoming more
heterogenous having memory systems with different latency and bandwidth
characteristics.  They are usually handled as different NUMA nodes in
separate memory tiers and CXL memory is used as slow tiers because of
its protocol overhead compared to local DRAM.

In this kind of systems, we need to be careful placing memory pages on
proper NUMA nodes based on the memory access frequency.  Otherwise, some
frequently accessed pages might reside on slow tiers and it makes
performance degradation unexpectedly.  Moreover, the memory access
patterns can be changed at runtime.

To handle this problem, we need a way to monitor the memory access
patterns and migrate pages based on their access temperature.  The
DAMON(Data Access MONitor) framework and its DAMOS(DAMON-based Operation
Schemes) can be useful features for monitoring and migrating pages.
DAMOS provides multiple actions based on DAMON monitoring results and it
can be used for proactive reclaim, which means swapping cold pages out
with DAMOS_PAGEOUT action, but it doesn't support migration actions such
as demotion and promotion between tiered memory nodes.

This series supports two new DAMOS actions; DAMOS_DEMOTE for demotion
from fast tiers and DAMOS_PROMOTE for promotion from slow tiers.  This
prevents hot pages from being stuck on slow tiers, which makes
performance degradation and cold pages can be proactively demoted to
slow tiers so that the system can increase the chance to allocate more
hot pages to fast tiers.

The DAMON provides various tuning knobs but we found that the proactive
demotion for cold pages is especially useful when the system is running
out of memory on its fast tier nodes.

Our evaluation result shows that it reduces the performance slowdown
compared to the default memory policy from 15~17% to 4~5% when the
system runs under high memory pressure on its fast tier DRAM nodes.


DAMON configuration
===
The specific DAMON configuration doesn't have to be in the scope of this
patch series, but some rough idea is better to be shared to explain the
evaluation result.

The DAMON provides many knobs for fine tuning but its configuration file
is generated by HMSDK[2].  It includes gen_config.py script that
generates a json file with the full config of DAMON knobs and it creates
multiple kdamonds for each NUMA node when the DAMON is enabled so that
it can run hot/cold based migration for tiered memory.


Evaluation Workload
===

The performance evaluation is done with redis[3], which is a widely used
in-memory database and the memory access patterns are generated via
YCSB[4].  We have measured two different workloads with zipfian and
latest distributions but their configs are slightly modified to make
memory usage higher and execution time longer for better evaluation.

The idea of evaluation using these demote and promote actions covers
system-wide memory management rather than partitioning hot/cold pages of
a single workload.  The default memory allocation policy creates pages
to the fast tier DRAM node first, then allocates newly created pages to
the slow tier CXL node when the DRAM node has insufficient free space.
Once the page allocation is done then those pages never move between
NUMA nodes.  It's not true when using numa balancing, but it is not the
scope of this DAMON based 2-tier memory management support.

If the working set of redis can be fit fully into the DRAM node, then
the redis will access the fast DRAM only.  Since the performance of DRAM
only is faster than partially accessing CXL memory in slow tiers, this
environment is not useful to evaluate this patch series.

To make pages of redis be distributed across fast DRAM node and slow
CXL node to evaluate our demote and promote actions, we pre-allocate
some cold memory externally using mmap and memset before launching
redis-server.  We assumed that there are enough amount of cold memory in
datacenters as TMO[5] and TPP[6] papers mentioned.

The evaluation sequence is as follows.

1. Turn on DAMON with DAMOS_DEMOTE action for DRAM node and
   DAMOS_PROMOTE action for CXL node.  It demotes cold pages on DRAM
   node and promotes hot pages on CXL node in a regular interval.
2. Allocate a huge block of cold memory by calling mmap and memset at
   the fast tier DRAM node, then make the process sleep to make the fast
   tier has insufficient memory for redis-server.
3. Launch redis-server and load prebaked snapshot image, dump.rdb.  The
   redis-server consumes 52GB of anon pages and 33GB of file pages, but
   due to the cold memory allocated at 2, it fails 

Re: [PATCH v11 2/5] ring-buffer: Introducing ring-buffer mapping functions

2024-01-14 Thread Google
On Thu, 11 Jan 2024 16:17:09 +
Vincent Donnefort  wrote:

> In preparation for allowing the user-space to map a ring-buffer, add
> a set of mapping functions:
> 
>   ring_buffer_{map,unmap}()
>   ring_buffer_map_fault()
> 
> And controls on the ring-buffer:
> 
>   ring_buffer_map_get_reader()  /* swap reader and head */
> 
> Mapping the ring-buffer also involves:
> 
>   A unique ID for each subbuf of the ring-buffer, currently they are
>   only identified through their in-kernel VA.
> 
>   A meta-page, where are stored ring-buffer statistics and a
>   description for the current reader
> 
> The linear mapping exposes the meta-page, and each subbuf of the
> ring-buffer, ordered following their unique ID, assigned during the
> first mapping.
> 
> Once mapped, no subbuf can get in or out of the ring-buffer: the buffer
> size will remain unmodified and the splice enabling functions will in
> reality simply memcpy the data instead of swapping subbufs.
> 
> Signed-off-by: Vincent Donnefort 
> 
> diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
> index fa802db216f9..0841ba8bab14 100644
> --- a/include/linux/ring_buffer.h
> +++ b/include/linux/ring_buffer.h
> @@ -6,6 +6,8 @@
>  #include 
>  #include 
>  
> +#include 
> +
>  struct trace_buffer;
>  struct ring_buffer_iter;
>  
> @@ -221,4 +223,9 @@ int trace_rb_cpu_prepare(unsigned int cpu, struct 
> hlist_node *node);
>  #define trace_rb_cpu_prepare NULL
>  #endif
>  
> +int ring_buffer_map(struct trace_buffer *buffer, int cpu);
> +int ring_buffer_unmap(struct trace_buffer *buffer, int cpu);
> +struct page *ring_buffer_map_fault(struct trace_buffer *buffer, int cpu,
> +unsigned long pgoff);
> +int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu);
>  #endif /* _LINUX_RING_BUFFER_H */
> diff --git a/include/uapi/linux/trace_mmap.h b/include/uapi/linux/trace_mmap.h
> new file mode 100644
> index ..bde39a73ce65
> --- /dev/null
> +++ b/include/uapi/linux/trace_mmap.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _TRACE_MMAP_H_
> +#define _TRACE_MMAP_H_
> +
> +#include 
> +
> +/**
> + * struct trace_buffer_meta - Ring-buffer Meta-page description
> + * @entries: Number of entries in the ring-buffer.
> + * @overrun: Number of entries lost in the ring-buffer.
> + * @read:Number of entries that have been read.
> + * @subbufs_touched: Number of subbufs that have been filled.
> + * @subbufs_lost:Number of subbufs lost to overrun.
> + * @subbufs_read:Number of subbufs that have been read.
> + * @reader.lost_events:  Number of events lost at the time of the reader 
> swap.
> + * @reader.id:   subbuf ID of the current reader. From 0 to 
> @nr_subbufs - 1
> + * @reader.read: Number of bytes read on the reader subbuf.
> + * @subbuf_size: Size of each subbuf, including the header.
> + * @nr_subbufs:  Number of subbfs in the ring-buffer.
> + * @meta_page_size:  Size of this meta-page.
> + * @meta_struct_len: Size of this structure.
> + */
> +struct trace_buffer_meta {
> + unsigned long   entries;
> + unsigned long   overrun;
> + unsigned long   read;
> +
> + unsigned long   subbufs_touched;
> + unsigned long   subbufs_lost;
> + unsigned long   subbufs_read;
> +
> + struct {
> + unsigned long   lost_events;
> + __u32   id;
> + __u32   read;
> + } reader;
> +
> + __u32   subbuf_size;
> + __u32   nr_subbufs;
> +
> + __u32   meta_page_size;
> + __u32   meta_struct_len;
> +};
> +
> +#endif /* _TRACE_MMAP_H_ */
> diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> index db73e326fa04..e9ff1c95e896 100644
> --- a/kernel/trace/ring_buffer.c
> +++ b/kernel/trace/ring_buffer.c
> @@ -338,6 +338,7 @@ struct buffer_page {
>   local_t  entries;   /* entries on this page */
>   unsigned longreal_end;  /* real end of data */
>   unsigned order; /* order of the page */
> + u32  id;/* ID for external mapping */
>   struct buffer_data_page *page;  /* Actual data page */
>  };
>  
> @@ -484,6 +485,12 @@ struct ring_buffer_per_cpu {
>   u64 read_stamp;
>   /* pages removed since last reset */
>   unsigned long   pages_removed;
> +
> + int mapped;
> + struct mutexmapping_lock;
> + unsigned long   *subbuf_ids;/* ID to addr */
> + struct trace_buffer_meta*meta_page;
> +
>   /* ring buffer pages to update, > 0 to add, < 0 to remove */
>   longnr_pages_to_update;
>   struct list_headnew_pages; /* new pages to add */
> @@ -1542,6 +1549,7 @@ rb_allocate_cpu_buffer(struct 

[GIT PULL] hwspinlock updates to v6.8

2024-01-14 Thread Bjorn Andersson


The following changes since commit b85ea95d086471afb4ad062012a4d73cd328fa86:

  Linux 6.7-rc1 (2023-11-12 16:19:07 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git 
tags/hwlock-v6.8

for you to fetch changes up to bcd0f5d18b0b1134ccf9ef68e7a0cf637aab380d:

  hwspinlock/core: fix kernel-doc warnings (2023-12-07 14:51:38 -0800)


hwspinlock updates to v6.8

Correct kernel-doc through the hwspinlock core, to address build
warnings (and improve the documentation).

Drop unused compatible in the Qualcomm TCSR mutex driver.


Randy Dunlap (1):
  hwspinlock/core: fix kernel-doc warnings

Vignesh Viswanathan (1):
  hwspinlock: qcom: Remove IPQ6018 SOC specific compatible

 drivers/hwspinlock/hwspinlock_core.c | 53 
 drivers/hwspinlock/qcom_hwspinlock.c |  1 -
 2 files changed, 29 insertions(+), 25 deletions(-)



[GIT PULL] remoteproc updates for v6.8

2024-01-14 Thread Bjorn Andersson


The following changes since commit 98b1cc82c4affc16f5598d4fa14b1858671b2263:

  Linux 6.7-rc2 (2023-11-19 15:02:14 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git 
tags/rproc-v6.8

for you to fetch changes up to 300ed425dfa99f6926299ec196a1eedf05f47b21:

  remoteproc: qcom_q6v5_pas: Add SC7280 ADSP, CDSP & WPSS (2023-12-17 10:06:32 
-0800)


remoteproc updates for v6.8

The i.MX DSP remoteproc driver adds support for providing a resource
table, in order to enable IPC with the core.

The TI K3 DSP driver is transitioned to remove_new, error messages are
changed to use symbolic error codes, and dev_err_probe() is used where
applicable.

Support for the Qualcomm SC7280 audio, compute and WiFi co-processors
are added to the Qualcomm TrustZone based remoteproc driver.


Iuliana Prodan (2):
  remoteproc: imx_dsp_rproc: Add mandatory find_loaded_rsc_table op
  arm64: dts: imx8mp: Add reserve-memory nodes for DSP

Luca Weiss (3):
  dt-bindings: remoteproc: qcom: sc7180-pas: Fix SC7280 MPSS PD-names
  dt-bindings: remoteproc: qcom: sc7180-pas: Add SC7280 compatibles
  remoteproc: qcom_q6v5_pas: Add SC7280 ADSP, CDSP & WPSS

Uwe Kleine-König (3):
  remoteproc: k3-dsp: Suppress duplicate error message in .remove()
  remoteproc: k3-dsp: Use symbolic error codes in error messages
  remoteproc: k3-dsp: Convert to platform remove callback returning void

 .../bindings/remoteproc/qcom,sc7180-pas.yaml   | 21 ++
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts   | 22 ++
 drivers/remoteproc/imx_dsp_rproc.c |  1 +
 drivers/remoteproc/qcom_q6v5_pas.c | 19 +
 drivers/remoteproc/ti_k3_dsp_remoteproc.c  | 87 ++
 5 files changed, 101 insertions(+), 49 deletions(-)



[GIT PULL] rpmsg updates for v6.8

2024-01-14 Thread Bjorn Andersson


The following changes since commit 98b1cc82c4affc16f5598d4fa14b1858671b2263:

  Linux 6.7-rc2 (2023-11-19 15:02:14 -0800)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git 
tags/rpmsg-v6.8

for you to fetch changes up to d5362c37e1f8a40096452fc201c30e705750e687:

  rpmsg: virtio: Free driver_override when rpmsg_remove() (2023-12-18 10:56:03 
-0700)


rpmsg updates for v6.8

This make virtio free driver_override upon removal. It also updates the
rpmsg documentation after earlier API updates.


Adrien Leravat (1):
  doc: rmpsg: Update with rpmsg_endpoint

Xiaolei Wang (1):
  rpmsg: virtio: Free driver_override when rpmsg_remove()

 Documentation/staging/rpmsg.rst  | 50 ++--
 drivers/rpmsg/virtio_rpmsg_bus.c |  1 +
 2 files changed, 28 insertions(+), 23 deletions(-)



Re: [PATCH v11 4/5] Documentation: tracing: Add ring-buffer mapping

2024-01-14 Thread Google
On Sun, 14 Jan 2024 11:23:24 -0500
Steven Rostedt  wrote:

> On Sun, 14 Jan 2024 23:26:43 +0900
> Masami Hiramatsu (Google)  wrote:
> 
> > Hi Vincent,
> > 
> > On Thu, 11 Jan 2024 16:17:11 +
> > Vincent Donnefort  wrote:
> > 
> > > It is now possible to mmap() a ring-buffer to stream its content. Add
> > > some documentation and a code example.
> > > 
> > > Signed-off-by: Vincent Donnefort 
> > > 
> > > diff --git a/Documentation/trace/index.rst b/Documentation/trace/index.rst
> > > index 5092d6c13af5..0b300901fd75 100644
> > > --- a/Documentation/trace/index.rst
> > > +++ b/Documentation/trace/index.rst
> > > @@ -29,6 +29,7 @@ Linux Tracing Technologies
> > > timerlat-tracer
> > > intel_th
> > > ring-buffer-design
> > > +   ring-buffer-map
> > > stm
> > > sys-t
> > > coresight/index
> > > diff --git a/Documentation/trace/ring-buffer-map.rst 
> > > b/Documentation/trace/ring-buffer-map.rst
> > > new file mode 100644
> > > index ..2ba7b5339178
> > > --- /dev/null
> > > +++ b/Documentation/trace/ring-buffer-map.rst
> > > @@ -0,0 +1,105 @@
> > > +.. SPDX-License-Identifier: GPL-2.0
> > > +
> > > +==
> > > +Tracefs ring-buffer memory mapping
> > > +==
> > > +
> > > +:Author: Vincent Donnefort 
> > > +
> > > +Overview
> > > +
> > > +Tracefs ring-buffer memory map provides an efficient method to stream 
> > > data
> > > +as no memory copy is necessary. The application mapping the ring-buffer 
> > > becomes
> > > +then a consumer for that ring-buffer, in a similar fashion to trace_pipe.
> > > +
> > > +Memory mapping setup
> > > +
> > > +The mapping works with a mmap() of the trace_pipe_raw interface.
> > > +
> > > +The first system page of the mapping contains ring-buffer statistics and
> > > +description. It is referred as the meta-page. One of the most important 
> > > field of
> > > +the meta-page is the reader. It contains the subbuf ID which can be 
> > > safely read
> > > +by the mapper (see ring-buffer-design.rst).
> > > +
> > > +The meta-page is followed by all the subbuf, ordered by ascendant ID. It 
> > > is
> > > +therefore effortless to know where the reader starts in the mapping:
> > > +
> > > +.. code-block:: c
> > > +
> > > +reader_id = meta->reader->id;
> > > +reader_offset = meta->meta_page_size + reader_id * 
> > > meta->subbuf_size;
> > > +
> > > +When the application is done with the current reader, it can get a new 
> > > one using
> > > +the trace_pipe_raw ioctl() TRACE_MMAP_IOCTL_GET_READER. This ioctl also 
> > > updates
> > > +the meta-page fields.
> > > +
> > > +Limitations
> > > +===
> > > +When a mapping is in place on a Tracefs ring-buffer, it is not possible 
> > > to
> > > +either resize it (either by increasing the entire size of the 
> > > ring-buffer or
> > > +each subbuf). It is also not possible to use snapshot or splice.  
> > 
> > I've played with the sample code.
> > 
> > - "free_buffer" just doesn't work when the process is mmap the ring buffer.
> > - After mmap the buffers, when the snapshot took, the IOCTL returns an 
> > error.
> > 
> > OK, but I rather like to fail snapshot with -EBUSY when the buffer is 
> > mmaped.
> > 
> > > +
> > > +Concurrent readers (either another application mapping that ring-buffer 
> > > or the
> > > +kernel with trace_pipe) are allowed but not recommended. They will 
> > > compete for
> > > +the ring-buffer and the output is unpredictable.
> > > +
> > > +Example
> > > +===
> > > +
> > > +.. code-block:: c
> > > +
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +
> > > +#include 
> > > +
> > > +#include 
> > > +#include 
> > > +
> > > +#define TRACE_PIPE_RAW 
> > > "/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw"
> > > +
> > > +int main(void)
> > > +{
> > > +int page_size = getpagesize(), fd, reader_id;
> > > +unsigned long meta_len, data_len;
> > > +struct trace_buffer_meta *meta;
> > > +void *map, *reader, *data;
> > > +
> > > +fd = open(TRACE_PIPE_RAW, O_RDONLY);
> > > +if (fd < 0)
> > > +exit(EXIT_FAILURE);
> > > +
> > > +map = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 
> > > 0);
> > > +if (map == MAP_FAILED)
> > > +exit(EXIT_FAILURE);
> > > +
> > > +meta = (struct trace_buffer_meta *)map;
> > > +meta_len = meta->meta_page_size;
> > > +
> > > +printf("entries:%lu\n", meta->entries);
> > > +printf("overrun:%lu\n", meta->overrun);
> > > +printf("read:   %lu\n", meta->read);
> > > +printf("subbufs_touched:%lu\n", meta->subbufs_touched);
> > > +printf("subbufs_lost:   

Re: [PATCH v11 4/5] Documentation: tracing: Add ring-buffer mapping

2024-01-14 Thread Steven Rostedt
On Sun, 14 Jan 2024 23:26:43 +0900
Masami Hiramatsu (Google)  wrote:

> Hi Vincent,
> 
> On Thu, 11 Jan 2024 16:17:11 +
> Vincent Donnefort  wrote:
> 
> > It is now possible to mmap() a ring-buffer to stream its content. Add
> > some documentation and a code example.
> > 
> > Signed-off-by: Vincent Donnefort 
> > 
> > diff --git a/Documentation/trace/index.rst b/Documentation/trace/index.rst
> > index 5092d6c13af5..0b300901fd75 100644
> > --- a/Documentation/trace/index.rst
> > +++ b/Documentation/trace/index.rst
> > @@ -29,6 +29,7 @@ Linux Tracing Technologies
> > timerlat-tracer
> > intel_th
> > ring-buffer-design
> > +   ring-buffer-map
> > stm
> > sys-t
> > coresight/index
> > diff --git a/Documentation/trace/ring-buffer-map.rst 
> > b/Documentation/trace/ring-buffer-map.rst
> > new file mode 100644
> > index ..2ba7b5339178
> > --- /dev/null
> > +++ b/Documentation/trace/ring-buffer-map.rst
> > @@ -0,0 +1,105 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +==
> > +Tracefs ring-buffer memory mapping
> > +==
> > +
> > +:Author: Vincent Donnefort 
> > +
> > +Overview
> > +
> > +Tracefs ring-buffer memory map provides an efficient method to stream data
> > +as no memory copy is necessary. The application mapping the ring-buffer 
> > becomes
> > +then a consumer for that ring-buffer, in a similar fashion to trace_pipe.
> > +
> > +Memory mapping setup
> > +
> > +The mapping works with a mmap() of the trace_pipe_raw interface.
> > +
> > +The first system page of the mapping contains ring-buffer statistics and
> > +description. It is referred as the meta-page. One of the most important 
> > field of
> > +the meta-page is the reader. It contains the subbuf ID which can be safely 
> > read
> > +by the mapper (see ring-buffer-design.rst).
> > +
> > +The meta-page is followed by all the subbuf, ordered by ascendant ID. It is
> > +therefore effortless to know where the reader starts in the mapping:
> > +
> > +.. code-block:: c
> > +
> > +reader_id = meta->reader->id;
> > +reader_offset = meta->meta_page_size + reader_id * 
> > meta->subbuf_size;
> > +
> > +When the application is done with the current reader, it can get a new one 
> > using
> > +the trace_pipe_raw ioctl() TRACE_MMAP_IOCTL_GET_READER. This ioctl also 
> > updates
> > +the meta-page fields.
> > +
> > +Limitations
> > +===
> > +When a mapping is in place on a Tracefs ring-buffer, it is not possible to
> > +either resize it (either by increasing the entire size of the ring-buffer 
> > or
> > +each subbuf). It is also not possible to use snapshot or splice.  
> 
> I've played with the sample code.
> 
> - "free_buffer" just doesn't work when the process is mmap the ring buffer.
> - After mmap the buffers, when the snapshot took, the IOCTL returns an error.
> 
> OK, but I rather like to fail snapshot with -EBUSY when the buffer is mmaped.
> 
> > +
> > +Concurrent readers (either another application mapping that ring-buffer or 
> > the
> > +kernel with trace_pipe) are allowed but not recommended. They will compete 
> > for
> > +the ring-buffer and the output is unpredictable.
> > +
> > +Example
> > +===
> > +
> > +.. code-block:: c
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +
> > +#include 
> > +#include 
> > +
> > +#define TRACE_PIPE_RAW 
> > "/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw"
> > +
> > +int main(void)
> > +{
> > +int page_size = getpagesize(), fd, reader_id;
> > +unsigned long meta_len, data_len;
> > +struct trace_buffer_meta *meta;
> > +void *map, *reader, *data;
> > +
> > +fd = open(TRACE_PIPE_RAW, O_RDONLY);
> > +if (fd < 0)
> > +exit(EXIT_FAILURE);
> > +
> > +map = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
> > +if (map == MAP_FAILED)
> > +exit(EXIT_FAILURE);
> > +
> > +meta = (struct trace_buffer_meta *)map;
> > +meta_len = meta->meta_page_size;
> > +
> > +printf("entries:%lu\n", meta->entries);
> > +printf("overrun:%lu\n", meta->overrun);
> > +printf("read:   %lu\n", meta->read);
> > +printf("subbufs_touched:%lu\n", meta->subbufs_touched);
> > +printf("subbufs_lost:   %lu\n", meta->subbufs_lost);
> > +printf("subbufs_read:   %lu\n", meta->subbufs_read);
> > +printf("nr_subbufs: %u\n", meta->nr_subbufs);
> > +
> > +data_len = meta->subbuf_size * meta->nr_subbufs;
> > +data = mmap(NULL, data_len, PROT_READ, MAP_SHARED, fd, 
> > data_len);

The above is buggy. It 

Re: [PATCH v11 4/5] Documentation: tracing: Add ring-buffer mapping

2024-01-14 Thread Google
Hi Vincent,

On Thu, 11 Jan 2024 16:17:11 +
Vincent Donnefort  wrote:

> It is now possible to mmap() a ring-buffer to stream its content. Add
> some documentation and a code example.
> 
> Signed-off-by: Vincent Donnefort 
> 
> diff --git a/Documentation/trace/index.rst b/Documentation/trace/index.rst
> index 5092d6c13af5..0b300901fd75 100644
> --- a/Documentation/trace/index.rst
> +++ b/Documentation/trace/index.rst
> @@ -29,6 +29,7 @@ Linux Tracing Technologies
> timerlat-tracer
> intel_th
> ring-buffer-design
> +   ring-buffer-map
> stm
> sys-t
> coresight/index
> diff --git a/Documentation/trace/ring-buffer-map.rst 
> b/Documentation/trace/ring-buffer-map.rst
> new file mode 100644
> index ..2ba7b5339178
> --- /dev/null
> +++ b/Documentation/trace/ring-buffer-map.rst
> @@ -0,0 +1,105 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +==
> +Tracefs ring-buffer memory mapping
> +==
> +
> +:Author: Vincent Donnefort 
> +
> +Overview
> +
> +Tracefs ring-buffer memory map provides an efficient method to stream data
> +as no memory copy is necessary. The application mapping the ring-buffer 
> becomes
> +then a consumer for that ring-buffer, in a similar fashion to trace_pipe.
> +
> +Memory mapping setup
> +
> +The mapping works with a mmap() of the trace_pipe_raw interface.
> +
> +The first system page of the mapping contains ring-buffer statistics and
> +description. It is referred as the meta-page. One of the most important 
> field of
> +the meta-page is the reader. It contains the subbuf ID which can be safely 
> read
> +by the mapper (see ring-buffer-design.rst).
> +
> +The meta-page is followed by all the subbuf, ordered by ascendant ID. It is
> +therefore effortless to know where the reader starts in the mapping:
> +
> +.. code-block:: c
> +
> +reader_id = meta->reader->id;
> +reader_offset = meta->meta_page_size + reader_id * meta->subbuf_size;
> +
> +When the application is done with the current reader, it can get a new one 
> using
> +the trace_pipe_raw ioctl() TRACE_MMAP_IOCTL_GET_READER. This ioctl also 
> updates
> +the meta-page fields.
> +
> +Limitations
> +===
> +When a mapping is in place on a Tracefs ring-buffer, it is not possible to
> +either resize it (either by increasing the entire size of the ring-buffer or
> +each subbuf). It is also not possible to use snapshot or splice.

I've played with the sample code.

- "free_buffer" just doesn't work when the process is mmap the ring buffer.
- After mmap the buffers, when the snapshot took, the IOCTL returns an error.

OK, but I rather like to fail snapshot with -EBUSY when the buffer is mmaped.

> +
> +Concurrent readers (either another application mapping that ring-buffer or 
> the
> +kernel with trace_pipe) are allowed but not recommended. They will compete 
> for
> +the ring-buffer and the output is unpredictable.
> +
> +Example
> +===
> +
> +.. code-block:: c
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include 
> +#include 
> +
> +#define TRACE_PIPE_RAW 
> "/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw"
> +
> +int main(void)
> +{
> +int page_size = getpagesize(), fd, reader_id;
> +unsigned long meta_len, data_len;
> +struct trace_buffer_meta *meta;
> +void *map, *reader, *data;
> +
> +fd = open(TRACE_PIPE_RAW, O_RDONLY);
> +if (fd < 0)
> +exit(EXIT_FAILURE);
> +
> +map = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
> +if (map == MAP_FAILED)
> +exit(EXIT_FAILURE);
> +
> +meta = (struct trace_buffer_meta *)map;
> +meta_len = meta->meta_page_size;
> +
> +printf("entries:%lu\n", meta->entries);
> +printf("overrun:%lu\n", meta->overrun);
> +printf("read:   %lu\n", meta->read);
> +printf("subbufs_touched:%lu\n", meta->subbufs_touched);
> +printf("subbufs_lost:   %lu\n", meta->subbufs_lost);
> +printf("subbufs_read:   %lu\n", meta->subbufs_read);
> +printf("nr_subbufs: %u\n", meta->nr_subbufs);
> +
> +data_len = meta->subbuf_size * meta->nr_subbufs;
> +data = mmap(NULL, data_len, PROT_READ, MAP_SHARED, fd, 
> data_len);
> +if (data == MAP_FAILED)
> +exit(EXIT_FAILURE);
> +
> +if (ioctl(fd, TRACE_MMAP_IOCTL_GET_READER) < 0)
> +exit(EXIT_FAILURE);
> +
> +reader_id = meta->reader.id;
> +reader = data + meta->subbuf_size * reader_id;

Also, this caused a bus error if I add below 2 

[PATCH] rpmsg: Remove usage of the deprecated ida_simple_xx() API

2024-01-14 Thread Christophe JAILLET
ida_alloc() and ida_free() should be preferred to the deprecated
ida_simple_get() and ida_simple_remove().

Note that the upper limit of ida_simple_get() is exclusive, but the one of
ida_alloc_max() is inclusive. So a -1 has been added when needed.

Signed-off-by: Christophe JAILLET 
---
 drivers/rpmsg/rpmsg_char.c | 12 ++--
 drivers/rpmsg/rpmsg_ctrl.c | 12 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
index 09833ad05da7..1cb8d7474428 100644
--- a/drivers/rpmsg/rpmsg_char.c
+++ b/drivers/rpmsg/rpmsg_char.c
@@ -399,8 +399,8 @@ static void rpmsg_eptdev_release_device(struct device *dev)
 {
struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
 
-   ida_simple_remove(_ept_ida, dev->id);
-   ida_simple_remove(_minor_ida, MINOR(eptdev->dev.devt));
+   ida_free(_ept_ida, dev->id);
+   ida_free(_minor_ida, MINOR(eptdev->dev.devt));
kfree(eptdev);
 }
 
@@ -441,12 +441,12 @@ static int rpmsg_chrdev_eptdev_add(struct rpmsg_eptdev 
*eptdev, struct rpmsg_cha
 
eptdev->chinfo = chinfo;
 
-   ret = ida_simple_get(_minor_ida, 0, RPMSG_DEV_MAX, GFP_KERNEL);
+   ret = ida_alloc_max(_minor_ida, RPMSG_DEV_MAX - 1, GFP_KERNEL);
if (ret < 0)
goto free_eptdev;
dev->devt = MKDEV(MAJOR(rpmsg_major), ret);
 
-   ret = ida_simple_get(_ept_ida, 0, 0, GFP_KERNEL);
+   ret = ida_alloc(_ept_ida, GFP_KERNEL);
if (ret < 0)
goto free_minor_ida;
dev->id = ret;
@@ -462,9 +462,9 @@ static int rpmsg_chrdev_eptdev_add(struct rpmsg_eptdev 
*eptdev, struct rpmsg_cha
return ret;
 
 free_ept_ida:
-   ida_simple_remove(_ept_ida, dev->id);
+   ida_free(_ept_ida, dev->id);
 free_minor_ida:
-   ida_simple_remove(_minor_ida, MINOR(dev->devt));
+   ida_free(_minor_ida, MINOR(dev->devt));
 free_eptdev:
put_device(dev);
kfree(eptdev);
diff --git a/drivers/rpmsg/rpmsg_ctrl.c b/drivers/rpmsg/rpmsg_ctrl.c
index 433253835690..c312794ba4b3 100644
--- a/drivers/rpmsg/rpmsg_ctrl.c
+++ b/drivers/rpmsg/rpmsg_ctrl.c
@@ -130,8 +130,8 @@ static void rpmsg_ctrldev_release_device(struct device *dev)
 {
struct rpmsg_ctrldev *ctrldev = dev_to_ctrldev(dev);
 
-   ida_simple_remove(_ctrl_ida, dev->id);
-   ida_simple_remove(_minor_ida, MINOR(dev->devt));
+   ida_free(_ctrl_ida, dev->id);
+   ida_free(_minor_ida, MINOR(dev->devt));
kfree(ctrldev);
 }
 
@@ -156,12 +156,12 @@ static int rpmsg_ctrldev_probe(struct rpmsg_device *rpdev)
cdev_init(>cdev, _ctrldev_fops);
ctrldev->cdev.owner = THIS_MODULE;
 
-   ret = ida_simple_get(_minor_ida, 0, RPMSG_DEV_MAX, GFP_KERNEL);
+   ret = ida_alloc_max(_minor_ida, RPMSG_DEV_MAX - 1, GFP_KERNEL);
if (ret < 0)
goto free_ctrldev;
dev->devt = MKDEV(MAJOR(rpmsg_major), ret);
 
-   ret = ida_simple_get(_ctrl_ida, 0, 0, GFP_KERNEL);
+   ret = ida_alloc(_ctrl_ida, GFP_KERNEL);
if (ret < 0)
goto free_minor_ida;
dev->id = ret;
@@ -179,9 +179,9 @@ static int rpmsg_ctrldev_probe(struct rpmsg_device *rpdev)
return ret;
 
 free_ctrl_ida:
-   ida_simple_remove(_ctrl_ida, dev->id);
+   ida_free(_ctrl_ida, dev->id);
 free_minor_ida:
-   ida_simple_remove(_minor_ida, MINOR(dev->devt));
+   ida_free(_minor_ida, MINOR(dev->devt));
 free_ctrldev:
put_device(dev);
kfree(ctrldev);
-- 
2.43.0