[v2] mem: telemetry support for memseg and element information

Message ID 20220519185712.879487-1-amitprakashs@marvell.com (mailing list archive)
State Superseded, archived
Delegated to: David Marchand
Headers
Series [v2] mem: telemetry support for memseg and element information |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK
ci/github-robot: build success github build: passed
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/intel-Testing fail Testing issues

Commit Message

Amit Prakash Shukla May 19, 2022, 6:57 p.m. UTC
  Changes adds telemetry support to display memory occupancy
in memseg and the information of the elements allocated from
a memseg based on arguments provided by user. This patch
adds following endpoints:

1. /eal/active_memseg_list
The command displays the memseg list from which the memory
has been allocated.
Example:
--> /eal/active_memseg_list
{"/eal/active_memseg_list": [0, 1]}

2. /eal/memseg_list,<memseg-list-id>
The command outputs the memsegs, from which the memory is
allocated, for the memseg_list given as input. Command also
supports help.
Example:
--> /eal/memseg_list,help
{"/eal/memseg_list": "/eal/memseg_list,<memseg-list-id>"}

--> /eal/memseg_list,1
{"/eal/memseg_list": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, \
 12, 13, 14, 15]}

3. /eal/memseg_info,<memseg-list-id>:<memseg-id>
The command outputs the memseg information based on the
memseg-list and the memseg-id given as input. Command also
supports help.
Example:
--> /eal/memseg_info,help
{"/eal/memseg_info": "/eal/memseg_info,<memseg-list-id>: \
<memseg-id>"}

--> /eal/memseg_info,0:10
{"/eal/memseg_info": {"Memseg_list_index": 0,  \
"Memseg_index": 10, "Memseg_list_len": 64,     \
"Start_addr": "0x260000000", "End_addr": "0x280000000",  \
"Size": 536870912}}

--> /eal/memseg_info,1:15
{"/eal/memseg_info": {"Memseg_list_index": 1,   \
"Memseg_index": 15, "Memseg_list_len": 64,      \
"Start_addr": "0xb20000000", "End_addr": "0xb40000000",  \
"Size": 536870912}}

4. /eal/elem_list,<heap-id>:<memseg-list-id>:<memseg-id>
The command outputs number of elements in a memseg based
on the heap-id, memseg-list-id and memseg-id given as input.
Command also supports help.
Example:
--> /eal/elem_list,help
{"/eal/elem_list": "/eal/elem_list,<heap-id>:  \
<memseg-list-id>:<memseg-id>"}

--> /eal/elem_list,0:0:63
{"/eal/elem_list": {"Element_count": 52}}

--> /eal/elem_list,0:1:15
{"/eal/elem_list": {"Element_count": 52}}

5. /eal/elem_info,<heap-id>:<memseg-list-id>:<memseg-id>:  \
   <elem-start-id>-<elem-end-id>
The command outputs element information like element start
address, end address, to which memseg it belongs, element
state, element size. User can give a range of elements to be
printed. Command also supports help.
Example:
--> /eal/elem_info,help
{"/eal/elem_info": "/eal/elem_info,<heap-id>:  \
<memseg-list-id>:<memseg-id>: <elem-start-id>-<elem-end-id>"}

--> /eal/elem_info,0:1:15:1-2
{"/eal/elem_info": {"elem_info.1": {"msl_id": 1,     \
"ms_id": 15, "memseg_start_addr": "0xb20000000",     \
"memseg_end_addr": "0xb40000000",                    \
"element_start_addr": "0xb201fe680",                 \
"element_end_addr": "0xb20bfe700",                   \
"element_size": 10485888, "element_state": "Busy"},  \
"elem_info.2": {"msl_id": 1, "ms_id": 15,            \
"memseg_start_addr": "0xb20000000",                  \
"memseg_end_addr": "0xb40000000",                    \
"element_start_addr": "0xb20bfe700",                 \
"element_end_addr": "0xb215fe780", "element_size": 10485888, \
"element_state": "Busy"}, "Element_count": 2}}

Increased telemetry output buffer to 64K to support large
size telemetry data output.

Signed-off-by: Amit Prakash Shukla <amitprakashs@marvell.com>
---
v2:
- Fixed compilation error related int-to-pointer-cast
- Changes for code review suggestions

 lib/eal/common/eal_common_memory.c | 481 ++++++++++++++++++++++++++++-
 lib/telemetry/telemetry.c          |   2 +-
 2 files changed, 477 insertions(+), 6 deletions(-)
  

Comments

Bruce Richardson May 23, 2022, 11:14 a.m. UTC | #1
On Fri, May 20, 2022 at 12:27:12AM +0530, Amit Prakash Shukla wrote:
> Changes adds telemetry support to display memory occupancy
> in memseg and the information of the elements allocated from
> a memseg based on arguments provided by user. This patch
> adds following endpoints:
> 
> 1. /eal/active_memseg_list
> The command displays the memseg list from which the memory
> has been allocated.
> Example:
> --> /eal/active_memseg_list
> {"/eal/active_memseg_list": [0, 1]}
> 
> 2. /eal/memseg_list,<memseg-list-id>
> The command outputs the memsegs, from which the memory is
> allocated, for the memseg_list given as input. Command also
> supports help.
> Example:
> --> /eal/memseg_list,help
> {"/eal/memseg_list": "/eal/memseg_list,<memseg-list-id>"}
> 
> --> /eal/memseg_list,1
> {"/eal/memseg_list": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, \
>  12, 13, 14, 15]}
> 

This is really confusing because, if I understand this correctly,  we have
a conflict of terms here - in telemetry "list" is generally used to get the
possible values of ids at the top level, with the info and other commands
used to get the next level of detail down, while the initial command here
returns details on the memseg lists, i.e. it should really be
"memseg_list_list" command, i.e. list the memseg lists. Can we perhaps come
up with a different term for the memseg list, because right now I think the
above commands should be "memseg_list_list" and "memseg_list_info"?


> 3. /eal/memseg_info,<memseg-list-id>:<memseg-id>
> The command outputs the memseg information based on the
> memseg-list and the memseg-id given as input. Command also
> supports help.
> Example:
> --> /eal/memseg_info,help
> {"/eal/memseg_info": "/eal/memseg_info,<memseg-list-id>: \
> <memseg-id>"}
> 
> --> /eal/memseg_info,0:10
> {"/eal/memseg_info": {"Memseg_list_index": 0,  \
> "Memseg_index": 10, "Memseg_list_len": 64,     \
> "Start_addr": "0x260000000", "End_addr": "0x280000000",  \
> "Size": 536870912}}
> 
> --> /eal/memseg_info,1:15
> {"/eal/memseg_info": {"Memseg_list_index": 1,   \
> "Memseg_index": 15, "Memseg_list_len": 64,      \
> "Start_addr": "0xb20000000", "End_addr": "0xb40000000",  \
> "Size": 536870912}}
> 

For telemetry library, the parameters should all be comma-separated rather
than colon-separated.

> 4. /eal/elem_list,<heap-id>:<memseg-list-id>:<memseg-id>
> The command outputs number of elements in a memseg based
> on the heap-id, memseg-list-id and memseg-id given as input.
> Command also supports help.
> Example:
> --> /eal/elem_list,help
> {"/eal/elem_list": "/eal/elem_list,<heap-id>:  \
> <memseg-list-id>:<memseg-id>"}
> 
> --> /eal/elem_list,0:0:63
> {"/eal/elem_list": {"Element_count": 52}}
> 
> --> /eal/elem_list,0:1:15
> {"/eal/elem_list": {"Element_count": 52}}
> 
> 5. /eal/elem_info,<heap-id>:<memseg-list-id>:<memseg-id>:  \
>    <elem-start-id>-<elem-end-id>
> The command outputs element information like element start
> address, end address, to which memseg it belongs, element
> state, element size. User can give a range of elements to be
> printed. Command also supports help.
> Example:
> --> /eal/elem_info,help
> {"/eal/elem_info": "/eal/elem_info,<heap-id>:  \
> <memseg-list-id>:<memseg-id>: <elem-start-id>-<elem-end-id>"}
> 
> --> /eal/elem_info,0:1:15:1-2
> {"/eal/elem_info": {"elem_info.1": {"msl_id": 1,     \
> "ms_id": 15, "memseg_start_addr": "0xb20000000",     \
> "memseg_end_addr": "0xb40000000",                    \
> "element_start_addr": "0xb201fe680",                 \
> "element_end_addr": "0xb20bfe700",                   \
> "element_size": 10485888, "element_state": "Busy"},  \
> "elem_info.2": {"msl_id": 1, "ms_id": 15,            \
> "memseg_start_addr": "0xb20000000",                  \
> "memseg_end_addr": "0xb40000000",                    \
> "element_start_addr": "0xb20bfe700",                 \
> "element_end_addr": "0xb215fe780", "element_size": 10485888, \
> "element_state": "Busy"}, "Element_count": 2}}
> 

The "elem" name is ambiguous, I think. Are these malloc elements or some
other type of elements.


> Increased telemetry output buffer to 64K to support large
> size telemetry data output.
> 

That's a 4x increase in max size. Is it really necessary? Is telemetry the
best way to output this info, and do you see users really needing it?
  
Amit Prakash Shukla May 23, 2022, 1:35 p.m. UTC | #2
Thanks Bruce for the review suggestions. I make the changes as suggested in next version of the patch.

> -----Original Message-----
> From: Bruce Richardson <bruce.richardson@intel.com>
> Sent: Monday, May 23, 2022 4:45 PM
> To: Amit Prakash Shukla <amitprakashs@marvell.com>
> Cc: Anatoly Burakov <anatoly.burakov@intel.com>; Ciara Power
> <ciara.power@intel.com>; dev@dpdk.org; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>
> Subject: [EXT] Re: [PATCH v2] mem: telemetry support for memseg and
> element information
> 
> External Email
> 
> ----------------------------------------------------------------------
> On Fri, May 20, 2022 at 12:27:12AM +0530, Amit Prakash Shukla wrote:
> > Changes adds telemetry support to display memory occupancy in memseg
> > and the information of the elements allocated from a memseg based on
> > arguments provided by user. This patch adds following endpoints:
> >
> > 1. /eal/active_memseg_list
> > The command displays the memseg list from which the memory has been
> > allocated.
> > Example:
> > --> /eal/active_memseg_list
> > {"/eal/active_memseg_list": [0, 1]}
> >
> > 2. /eal/memseg_list,<memseg-list-id>
> > The command outputs the memsegs, from which the memory is allocated,
> > for the memseg_list given as input. Command also supports help.
> > Example:
> > --> /eal/memseg_list,help
> > {"/eal/memseg_list": "/eal/memseg_list,<memseg-list-id>"}
> >
> > --> /eal/memseg_list,1
> > {"/eal/memseg_list": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, \  12, 13,
> > 14, 15]}
> >
> 
> This is really confusing because, if I understand this correctly,  we have a
> conflict of terms here - in telemetry "list" is generally used to get the possible
> values of ids at the top level, with the info and other commands used to get
> the next level of detail down, while the initial command here returns details
> on the memseg lists, i.e. it should really be "memseg_list_list" command, i.e.
> list the memseg lists. Can we perhaps come up with a different term for the
> memseg list, because right now I think the above commands should be
> "memseg_list_list" and "memseg_list_info"?
> 

Sure, will change the naming.

> 
> > 3. /eal/memseg_info,<memseg-list-id>:<memseg-id>
> > The command outputs the memseg information based on the memseg-list
> > and the memseg-id given as input. Command also supports help.
> > Example:
> > --> /eal/memseg_info,help
> > {"/eal/memseg_info": "/eal/memseg_info,<memseg-list-id>: \
> > <memseg-id>"}
> >
> > --> /eal/memseg_info,0:10
> > {"/eal/memseg_info": {"Memseg_list_index": 0,  \
> > "Memseg_index": 10, "Memseg_list_len": 64,     \
> > "Start_addr": "0x260000000", "End_addr": "0x280000000",  \
> > "Size": 536870912}}
> >
> > --> /eal/memseg_info,1:15
> > {"/eal/memseg_info": {"Memseg_list_index": 1,   \
> > "Memseg_index": 15, "Memseg_list_len": 64,      \
> > "Start_addr": "0xb20000000", "End_addr": "0xb40000000",  \
> > "Size": 536870912}}
> >
> 
> For telemetry library, the parameters should all be comma-separated rather
> than colon-separated.
> 

Sure, will change it to comma-separated.

> > 4. /eal/elem_list,<heap-id>:<memseg-list-id>:<memseg-id>
> > The command outputs number of elements in a memseg based on the
> > heap-id, memseg-list-id and memseg-id given as input.
> > Command also supports help.
> > Example:
> > --> /eal/elem_list,help
> > {"/eal/elem_list": "/eal/elem_list,<heap-id>:  \
> > <memseg-list-id>:<memseg-id>"}
> >
> > --> /eal/elem_list,0:0:63
> > {"/eal/elem_list": {"Element_count": 52}}
> >
> > --> /eal/elem_list,0:1:15
> > {"/eal/elem_list": {"Element_count": 52}}
> >
> > 5. /eal/elem_info,<heap-id>:<memseg-list-id>:<memseg-id>:  \
> >    <elem-start-id>-<elem-end-id>
> > The command outputs element information like element start address,
> > end address, to which memseg it belongs, element state, element size.
> > User can give a range of elements to be printed. Command also supports
> > help.
> > Example:
> > --> /eal/elem_info,help
> > {"/eal/elem_info": "/eal/elem_info,<heap-id>:  \
> > <memseg-list-id>:<memseg-id>: <elem-start-id>-<elem-end-id>"}
> >

The last 2 arguments "<elem-start-id>-<elem-end-id>" is to print range of elements. Can I use hyphen here ?

> > --> /eal/elem_info,0:1:15:1-2
> > {"/eal/elem_info": {"elem_info.1": {"msl_id": 1,     \
> > "ms_id": 15, "memseg_start_addr": "0xb20000000",     \
> > "memseg_end_addr": "0xb40000000",                    \
> > "element_start_addr": "0xb201fe680",                 \
> > "element_end_addr": "0xb20bfe700",                   \
> > "element_size": 10485888, "element_state": "Busy"},  \
> > "elem_info.2": {"msl_id": 1, "ms_id": 15,            \
> > "memseg_start_addr": "0xb20000000",                  \
> > "memseg_end_addr": "0xb40000000",                    \
> > "element_start_addr": "0xb20bfe700",                 \
> > "element_end_addr": "0xb215fe780", "element_size": 10485888, \
> > "element_state": "Busy"}, "Element_count": 2}}
> >
> 
> The "elem" name is ambiguous, I think. Are these malloc elements or some
> other type of elements.
> 

These are malloc elements. I will change the naming.

> 
> > Increased telemetry output buffer to 64K to support large size
> > telemetry data output.
> >
> 
> That's a 4x increase in max size. Is it really necessary? Is telemetry the best
> way to output this info, and do you see users really needing it?

This change is not required now. The code has been internally optimized. I will revert this change.
  
Bruce Richardson May 23, 2022, 1:43 p.m. UTC | #3
On Mon, May 23, 2022 at 01:35:06PM +0000, Amit Prakash Shukla wrote:
> Thanks Bruce for the review suggestions. I make the changes as suggested in next version of the patch.
> 
> > -----Original Message-----
> > From: Bruce Richardson <bruce.richardson@intel.com>
> > Sent: Monday, May 23, 2022 4:45 PM
> > To: Amit Prakash Shukla <amitprakashs@marvell.com>
> > Cc: Anatoly Burakov <anatoly.burakov@intel.com>; Ciara Power
> > <ciara.power@intel.com>; dev@dpdk.org; Jerin Jacob Kollanukkaran
> > <jerinj@marvell.com>
> > Subject: [EXT] Re: [PATCH v2] mem: telemetry support for memseg and
> > element information
> > 
> > External Email
> > 
> > ----------------------------------------------------------------------
> > On Fri, May 20, 2022 at 12:27:12AM +0530, Amit Prakash Shukla wrote:
> > > Changes adds telemetry support to display memory occupancy in memseg
> > > and the information of the elements allocated from a memseg based on
> > > arguments provided by user. This patch adds following endpoints:
> > >
> > > 1. /eal/active_memseg_list
> > > The command displays the memseg list from which the memory has been
> > > allocated.
> > > Example:
> > > --> /eal/active_memseg_list
> > > {"/eal/active_memseg_list": [0, 1]}
> > >
> > > 2. /eal/memseg_list,<memseg-list-id>
> > > The command outputs the memsegs, from which the memory is allocated,
> > > for the memseg_list given as input. Command also supports help.
> > > Example:
> > > --> /eal/memseg_list,help
> > > {"/eal/memseg_list": "/eal/memseg_list,<memseg-list-id>"}
> > >
> > > --> /eal/memseg_list,1
> > > {"/eal/memseg_list": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, \  12, 13,
> > > 14, 15]}
> > >
> > 
> > This is really confusing because, if I understand this correctly,  we have a
> > conflict of terms here - in telemetry "list" is generally used to get the possible
> > values of ids at the top level, with the info and other commands used to get
> > the next level of detail down, while the initial command here returns details
> > on the memseg lists, i.e. it should really be "memseg_list_list" command, i.e.
> > list the memseg lists. Can we perhaps come up with a different term for the
> > memseg list, because right now I think the above commands should be
> > "memseg_list_list" and "memseg_list_info"?
> > 
> 
> Sure, will change the naming.
> 

Have a think about it too, because my suggested naming is still rather
unwieldy and not very nice. I'm not sure what the best naming here is.

Are the memsegs only identified by number inside each memseg list? Are
there no names that could be used instead? Could you merge the
memseg_list_list and memseg_list_info into one to print out a list of all
memsegs in one go across multiple lists? How many memsegs are there likely
to be?

> > 
> > > 3. /eal/memseg_info,<memseg-list-id>:<memseg-id>
> > > The command outputs the memseg information based on the memseg-list
> > > and the memseg-id given as input. Command also supports help.
> > > Example:
> > > --> /eal/memseg_info,help
> > > {"/eal/memseg_info": "/eal/memseg_info,<memseg-list-id>: \
> > > <memseg-id>"}
> > >
> > > --> /eal/memseg_info,0:10
> > > {"/eal/memseg_info": {"Memseg_list_index": 0,  \
> > > "Memseg_index": 10, "Memseg_list_len": 64,     \
> > > "Start_addr": "0x260000000", "End_addr": "0x280000000",  \
> > > "Size": 536870912}}
> > >
> > > --> /eal/memseg_info,1:15
> > > {"/eal/memseg_info": {"Memseg_list_index": 1,   \
> > > "Memseg_index": 15, "Memseg_list_len": 64,      \
> > > "Start_addr": "0xb20000000", "End_addr": "0xb40000000",  \
> > > "Size": 536870912}}
> > >
> > 
> > For telemetry library, the parameters should all be comma-separated rather
> > than colon-separated.
> > 
> 
> Sure, will change it to comma-separated.
> 
> > > 4. /eal/elem_list,<heap-id>:<memseg-list-id>:<memseg-id>
> > > The command outputs number of elements in a memseg based on the
> > > heap-id, memseg-list-id and memseg-id given as input.
> > > Command also supports help.
> > > Example:
> > > --> /eal/elem_list,help
> > > {"/eal/elem_list": "/eal/elem_list,<heap-id>:  \
> > > <memseg-list-id>:<memseg-id>"}
> > >
> > > --> /eal/elem_list,0:0:63
> > > {"/eal/elem_list": {"Element_count": 52}}
> > >
> > > --> /eal/elem_list,0:1:15
> > > {"/eal/elem_list": {"Element_count": 52}}
> > >
> > > 5. /eal/elem_info,<heap-id>:<memseg-list-id>:<memseg-id>:  \
> > >    <elem-start-id>-<elem-end-id>
> > > The command outputs element information like element start address,
> > > end address, to which memseg it belongs, element state, element size.
> > > User can give a range of elements to be printed. Command also supports
> > > help.
> > > Example:
> > > --> /eal/elem_info,help
> > > {"/eal/elem_info": "/eal/elem_info,<heap-id>:  \
> > > <memseg-list-id>:<memseg-id>: <elem-start-id>-<elem-end-id>"}
> > >
> 
> The last 2 arguments "<elem-start-id>-<elem-end-id>" is to print range of elements. Can I use hyphen here ?
> 

I'm not sure I like printing based off a range, especially since doing so
can lead to very large outputs. I would still tend towards separating with
a comma here, if you only support a single range at a time. I would only
support using a "-" in the specifier, if you supported multiple range
options in one go, e.g. as is done with DPDK -l EAL flag.

> > > --> /eal/elem_info,0:1:15:1-2
> > > {"/eal/elem_info": {"elem_info.1": {"msl_id": 1,     \
> > > "ms_id": 15, "memseg_start_addr": "0xb20000000",     \
> > > "memseg_end_addr": "0xb40000000",                    \
> > > "element_start_addr": "0xb201fe680",                 \
> > > "element_end_addr": "0xb20bfe700",                   \
> > > "element_size": 10485888, "element_state": "Busy"},  \
> > > "elem_info.2": {"msl_id": 1, "ms_id": 15,            \
> > > "memseg_start_addr": "0xb20000000",                  \
> > > "memseg_end_addr": "0xb40000000",                    \
> > > "element_start_addr": "0xb20bfe700",                 \
> > > "element_end_addr": "0xb215fe780", "element_size": 10485888, \
> > > "element_state": "Busy"}, "Element_count": 2}}
> > >
> > 
> > The "elem" name is ambiguous, I think. Are these malloc elements or some
> > other type of elements.
> > 
> 
> These are malloc elements. I will change the naming.
> 
> > 
> > > Increased telemetry output buffer to 64K to support large size
> > > telemetry data output.
> > >
> > 
> > That's a 4x increase in max size. Is it really necessary? Is telemetry the best
> > way to output this info, and do you see users really needing it?
> 
> This change is not required now. The code has been internally optimized. I will revert this change.

Thanks,
/Bruce
  
Amit Prakash Shukla May 24, 2022, 10:30 a.m. UTC | #4
> -----Original Message-----
> From: Bruce Richardson <bruce.richardson@intel.com>
> Sent: Monday, May 23, 2022 7:14 PM
> To: Amit Prakash Shukla <amitprakashs@marvell.com>
> Cc: Anatoly Burakov <anatoly.burakov@intel.com>; Ciara Power
> <ciara.power@intel.com>; dev@dpdk.org; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>
> Subject: Re: [EXT] Re: [PATCH v2] mem: telemetry support for memseg and
> element information
> 
> On Mon, May 23, 2022 at 01:35:06PM +0000, Amit Prakash Shukla wrote:
> > Thanks Bruce for the review suggestions. I make the changes as suggested
> in next version of the patch.
> >
> > > -----Original Message-----
> > > From: Bruce Richardson <bruce.richardson@intel.com>
> > > Sent: Monday, May 23, 2022 4:45 PM
> > > To: Amit Prakash Shukla <amitprakashs@marvell.com>
> > > Cc: Anatoly Burakov <anatoly.burakov@intel.com>; Ciara Power
> > > <ciara.power@intel.com>; dev@dpdk.org; Jerin Jacob Kollanukkaran
> > > <jerinj@marvell.com>
> > > Subject: [EXT] Re: [PATCH v2] mem: telemetry support for memseg and
> > > element information
> > >
> > > External Email
> > >
> > > --------------------------------------------------------------------
> > > -- On Fri, May 20, 2022 at 12:27:12AM +0530, Amit Prakash Shukla
> > > wrote:
> > > > Changes adds telemetry support to display memory occupancy in
> > > > memseg and the information of the elements allocated from a memseg
> > > > based on arguments provided by user. This patch adds following
> endpoints:
> > > >
> > > > 1. /eal/active_memseg_list
> > > > The command displays the memseg list from which the memory has
> > > > been allocated.
> > > > Example:
> > > > --> /eal/active_memseg_list
> > > > {"/eal/active_memseg_list": [0, 1]}
> > > >
> > > > 2. /eal/memseg_list,<memseg-list-id> The command outputs the
> > > > memsegs, from which the memory is allocated, for the memseg_list
> > > > given as input. Command also supports help.
> > > > Example:
> > > > --> /eal/memseg_list,help
> > > > {"/eal/memseg_list": "/eal/memseg_list,<memseg-list-id>"}
> > > >
> > > > --> /eal/memseg_list,1
> > > > {"/eal/memseg_list": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, \  12,
> > > > 13, 14, 15]}
> > > >
> > >
> > > This is really confusing because, if I understand this correctly,
> > > we have a conflict of terms here - in telemetry "list" is generally
> > > used to get the possible values of ids at the top level, with the
> > > info and other commands used to get the next level of detail down,
> > > while the initial command here returns details on the memseg lists, i.e. it
> should really be "memseg_list_list" command, i.e.
> > > list the memseg lists. Can we perhaps come up with a different term
> > > for the memseg list, because right now I think the above commands
> > > should be "memseg_list_list" and "memseg_list_info"?
> > >
> >
> > Sure, will change the naming.
> >
> 
> Have a think about it too, because my suggested naming is still rather
> unwieldy and not very nice. I'm not sure what the best naming here is.

Sure.

> 
> Are the memsegs only identified by number inside each memseg list? Are
> there no names that could be used instead?

Each memseg-list contains a fbarray and fbarray contains list of memsegs.
Memsegs in fbarray are identified by numbers.

> Could you merge the
> memseg_list_list and memseg_list_info into one to print out a list of all
> memsegs in one go across multiple lists? 

Have kept memseg_list_list and memseg_list_info separate for users to identify, 
while requesting memseg info, which memseg list a memseg belongs to.

>How many memsegs are there likely
> to be?

Max memsegs per list is 8192.
#define RTE_MAX_MEMSEG_LISTS 128
#define RTE_MAX_MEMSEG_PER_LIST 8192 

> > >
> > > > 3. /eal/memseg_info,<memseg-list-id>:<memseg-id>
> > > > The command outputs the memseg information based on the
> > > > memseg-list and the memseg-id given as input. Command also
> supports help.
> > > > Example:
> > > > --> /eal/memseg_info,help
> > > > {"/eal/memseg_info": "/eal/memseg_info,<memseg-list-id>: \
> > > > <memseg-id>"}
> > > >
> > > > --> /eal/memseg_info,0:10
> > > > {"/eal/memseg_info": {"Memseg_list_index": 0,  \
> > > > "Memseg_index": 10, "Memseg_list_len": 64,     \
> > > > "Start_addr": "0x260000000", "End_addr": "0x280000000",  \
> > > > "Size": 536870912}}
> > > >
> > > > --> /eal/memseg_info,1:15
> > > > {"/eal/memseg_info": {"Memseg_list_index": 1,   \
> > > > "Memseg_index": 15, "Memseg_list_len": 64,      \
> > > > "Start_addr": "0xb20000000", "End_addr": "0xb40000000",  \
> > > > "Size": 536870912}}
> > > >
> > >
> > > For telemetry library, the parameters should all be comma-separated
> > > rather than colon-separated.
> > >
> >
> > Sure, will change it to comma-separated.
> >
> > > > 4. /eal/elem_list,<heap-id>:<memseg-list-id>:<memseg-id>
> > > > The command outputs number of elements in a memseg based on the
> > > > heap-id, memseg-list-id and memseg-id given as input.
> > > > Command also supports help.
> > > > Example:
> > > > --> /eal/elem_list,help
> > > > {"/eal/elem_list": "/eal/elem_list,<heap-id>:  \
> > > > <memseg-list-id>:<memseg-id>"}
> > > >
> > > > --> /eal/elem_list,0:0:63
> > > > {"/eal/elem_list": {"Element_count": 52}}
> > > >
> > > > --> /eal/elem_list,0:1:15
> > > > {"/eal/elem_list": {"Element_count": 52}}
> > > >
> > > > 5. /eal/elem_info,<heap-id>:<memseg-list-id>:<memseg-id>:  \
> > > >    <elem-start-id>-<elem-end-id>
> > > > The command outputs element information like element start
> > > > address, end address, to which memseg it belongs, element state,
> element size.
> > > > User can give a range of elements to be printed. Command also
> > > > supports help.
> > > > Example:
> > > > --> /eal/elem_info,help
> > > > {"/eal/elem_info": "/eal/elem_info,<heap-id>:  \
> > > > <memseg-list-id>:<memseg-id>: <elem-start-id>-<elem-end-id>"}
> > > >
> >
> > The last 2 arguments "<elem-start-id>-<elem-end-id>" is to print range of
> elements. Can I use hyphen here ?
> >
> 
> I'm not sure I like printing based off a range, especially since doing so can lead
> to very large outputs. I would still tend towards separating with a comma
> here, if you only support a single range at a time. I would only support using a
> "-" in the specifier, if you supported multiple range options in one go, e.g. as
> is done with DPDK -l EAL flag.
> 
> > > > --> /eal/elem_info,0:1:15:1-2
> > > > {"/eal/elem_info": {"elem_info.1": {"msl_id": 1,     \
> > > > "ms_id": 15, "memseg_start_addr": "0xb20000000",     \
> > > > "memseg_end_addr": "0xb40000000",                    \
> > > > "element_start_addr": "0xb201fe680",                 \
> > > > "element_end_addr": "0xb20bfe700",                   \
> > > > "element_size": 10485888, "element_state": "Busy"},  \
> > > > "elem_info.2": {"msl_id": 1, "ms_id": 15,            \
> > > > "memseg_start_addr": "0xb20000000",                  \
> > > > "memseg_end_addr": "0xb40000000",                    \
> > > > "element_start_addr": "0xb20bfe700",                 \
> > > > "element_end_addr": "0xb215fe780", "element_size": 10485888, \
> > > > "element_state": "Busy"}, "Element_count": 2}}
> > > >
> > >
> > > The "elem" name is ambiguous, I think. Are these malloc elements or
> > > some other type of elements.
> > >
> >
> > These are malloc elements. I will change the naming.
> >
> > >
> > > > Increased telemetry output buffer to 64K to support large size
> > > > telemetry data output.
> > > >
> > >
> > > That's a 4x increase in max size. Is it really necessary? Is
> > > telemetry the best way to output this info, and do you see users really
> needing it?
> >
> > This change is not required now. The code has been internally optimized. I
> will revert this change.
> 
> Thanks,
> /Bruce

Thanks,
Amit Shukla
  

Patch

diff --git a/lib/eal/common/eal_common_memory.c b/lib/eal/common/eal_common_memory.c
index 688dc615d7..820fe8cf2c 100644
--- a/lib/eal/common/eal_common_memory.c
+++ b/lib/eal/common/eal_common_memory.c
@@ -26,6 +26,7 @@ 
 #include "eal_memcfg.h"
 #include "eal_options.h"
 #include "malloc_heap.h"
+#include "malloc_elem.h"
 
 /*
  * Try to mmap *size bytes in /dev/zero. If it is successful, return the
@@ -1113,11 +1114,17 @@  rte_eal_memory_init(void)
 }
 
 #ifndef RTE_EXEC_ENV_WINDOWS
-#define EAL_MEMZONE_LIST_REQ	"/eal/memzone_list"
-#define EAL_MEMZONE_INFO_REQ	"/eal/memzone_info"
-#define EAL_HEAP_LIST_REQ	"/eal/heap_list"
-#define EAL_HEAP_INFO_REQ	"/eal/heap_info"
-#define ADDR_STR		15
+#define EAL_MEMZONE_LIST_REQ		"/eal/memzone_list"
+#define EAL_MEMZONE_INFO_REQ		"/eal/memzone_info"
+#define EAL_HEAP_LIST_REQ		"/eal/heap_list"
+#define EAL_HEAP_INFO_REQ		"/eal/heap_info"
+#define EAL_MEMSEG_REQ			"/eal/memseg_list"
+#define EAL_MEMSEG_INFO_REQ		"/eal/memseg_info"
+#define EAL_ACTIVE_MEMSEG_LIST_REQ	"/eal/active_memseg_list"
+#define EAL_ELEMENT_LIST_REQ		"/eal/elem_list"
+#define EAL_ELEMENT_INFO_REQ		"/eal/elem_info"
+#define ADDR_STR			15
+
 
 /* Telemetry callback handler to return heap stats for requested heap id. */
 static int
@@ -1265,6 +1272,455 @@  handle_eal_memzone_list_request(const char *cmd __rte_unused,
 	return 0;
 }
 
+static int
+handle_eal_active_memseg_request(const char *cmd __rte_unused,
+				 const char *params __rte_unused,
+				 struct rte_tel_data *d)
+{
+	struct rte_mem_config *mcfg;
+	int i;
+
+	rte_tel_data_start_array(d, RTE_TEL_INT_VAL);
+
+	rte_mcfg_mem_read_lock();
+	mcfg = rte_eal_get_configuration()->mem_config;
+
+	for (i = 0; i < RTE_MAX_MEMSEG_LISTS; i++) {
+		struct rte_memseg_list *msl = &mcfg->memsegs[i];
+		if (msl->memseg_arr.count == 0)
+			continue;
+
+		rte_tel_data_add_array_int(d, i);
+	}
+	rte_mcfg_mem_read_unlock();
+
+	return 0;
+}
+
+static int
+handle_eal_memseg_request(const char *cmd __rte_unused, const char *params,
+			  struct rte_tel_data *d)
+{
+	struct rte_mem_config *mcfg;
+	struct rte_memseg_list *msl;
+	struct rte_fbarray *arr;
+	uint32_t ms_list_idx;
+	int ms_idx;
+
+	if (params == NULL || strlen(params) == 0)
+		return -1;
+
+	if (strncasecmp(params, "help", strlen(params)) == 0) {
+		char buff[RTE_TEL_MAX_SINGLE_STRING_LEN];
+		snprintf(buff, RTE_TEL_MAX_SINGLE_STRING_LEN,
+			 "%s,<memseg-list-id>", EAL_MEMSEG_REQ);
+		rte_tel_data_string(d, buff);
+		return 0;
+	}
+
+	if (!isdigit(*params))
+		return -1;
+
+	ms_list_idx = strtoul(params, NULL, 10);
+	if (ms_list_idx >= RTE_MAX_MEMSEG_LISTS)
+		return -1;
+
+	rte_tel_data_start_array(d, RTE_TEL_INT_VAL);
+
+	rte_mcfg_mem_read_lock();
+	mcfg = rte_eal_get_configuration()->mem_config;
+	msl = &mcfg->memsegs[ms_list_idx];
+	if (msl->memseg_arr.count == 0)
+		goto done;
+
+	arr = &msl->memseg_arr;
+
+	ms_idx = rte_fbarray_find_next_used(arr, 0);
+	while (ms_idx >= 0) {
+		rte_tel_data_add_array_int(d, ms_idx);
+		ms_idx = rte_fbarray_find_next_used(arr, ms_idx + 1);
+	}
+
+done:
+	rte_mcfg_mem_read_unlock();
+
+	return 0;
+}
+
+static int
+handle_eal_memseg_info_request(const char *cmd __rte_unused,
+			       const char *params, struct rte_tel_data *d)
+{
+	struct rte_mem_config *mcfg;
+	uint64_t ms_start_addr, ms_end_addr, ms_size;
+	struct rte_memseg_list *msl;
+	const struct rte_memseg *ms;
+	struct rte_fbarray *arr;
+	char addr[ADDR_STR];
+	uint32_t ms_list_idx = 0;
+	uint32_t ms_idx = 0;
+	uint32_t msl_len;
+	char dlim[2] = ":";
+	char *token;
+	char *params_args;
+
+	if (params == NULL || strlen(params) == 0)
+		return -1;
+
+	if (strncasecmp(params, "help", strlen(params)) == 0) {
+		char buff[RTE_TEL_MAX_SINGLE_STRING_LEN];
+		snprintf(buff, RTE_TEL_MAX_SINGLE_STRING_LEN,
+			 "%s,<memseg-list-id>:<memseg-id>",
+			 EAL_MEMSEG_INFO_REQ);
+		rte_tel_data_string(d, buff);
+		return 0;
+	}
+
+	/* strtok expects char * and param is const char *. Hence on using
+	 * params as "const char *" compiler throws warning.
+	 */
+	params_args = strdup(params);
+	token = strtok(params_args, dlim);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+
+	ms_list_idx = strtoul(token, NULL, 10);
+	if (ms_list_idx >= RTE_MAX_MEMSEG_LISTS) {
+		free(params_args);
+		return -1;
+	}
+
+	token = strtok(NULL, dlim);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+	ms_idx = strtoul(token, NULL, 10);
+
+	free(params_args);
+
+	rte_mcfg_mem_read_lock();
+
+	mcfg = rte_eal_get_configuration()->mem_config;
+	msl = &mcfg->memsegs[ms_list_idx];
+	if (msl->memseg_arr.count == 0) {
+		rte_mcfg_mem_read_unlock();
+		return -1;
+	}
+
+	arr = &msl->memseg_arr;
+	msl_len = arr->len;
+
+	ms = rte_fbarray_get(arr, ms_idx);
+	if (ms == NULL) {
+		rte_mcfg_mem_read_unlock();
+		RTE_LOG(DEBUG, EAL, "Error fetching requested memseg.\n");
+		return -1;
+	}
+
+	ms_start_addr = ms->addr_64;
+	ms_end_addr = (uint64_t)RTE_PTR_ADD(ms_start_addr, ms->len);
+	ms_size = ms->hugepage_sz;
+
+	rte_mcfg_mem_read_unlock();
+
+	rte_tel_data_start_dict(d);
+	rte_tel_data_add_dict_int(d, "Memseg_list_index", ms_list_idx);
+	rte_tel_data_add_dict_int(d, "Memseg_index", ms_idx);
+	rte_tel_data_add_dict_int(d, "Memseg_list_len", msl_len);
+	snprintf(addr, ADDR_STR, "0x%"PRIx64, ms_start_addr);
+	rte_tel_data_add_dict_string(d, "Start_addr", addr);
+	snprintf(addr, ADDR_STR, "0x%"PRIx64, ms_end_addr);
+	rte_tel_data_add_dict_string(d, "End_addr", addr);
+	rte_tel_data_add_dict_int(d, "Size", ms_size);
+
+	return 0;
+}
+
+static int
+handle_eal_element_list_request(const char *cmd __rte_unused,
+				const char *params, struct rte_tel_data *d)
+{
+	struct rte_mem_config *mcfg;
+	struct rte_memseg_list *msl;
+	const struct rte_memseg *ms;
+	struct malloc_elem *elem;
+	struct malloc_heap *heap;
+	uint64_t ms_start_addr, ms_end_addr;
+	uint64_t elem_start_addr, elem_end_addr;
+	uint32_t ms_list_idx = 0;
+	uint32_t heap_id = 0;
+	uint32_t ms_idx = 0;
+	char dlim[2] = ":";
+	int elem_count = 0;
+	char *token;
+	char *params_args;
+
+	if (params == NULL || strlen(params) == 0)
+		return -1;
+
+	if (strncasecmp(params, "help", strlen(params)) == 0) {
+		char buff[RTE_TEL_MAX_SINGLE_STRING_LEN];
+		snprintf(buff, RTE_TEL_MAX_SINGLE_STRING_LEN,
+			 "%s,<heap-id>:<memseg-list-id>:<memseg-id>",
+			 EAL_ELEMENT_LIST_REQ);
+		rte_tel_data_string(d, buff);
+		return 0;
+	}
+
+	/* strtok expects char * and param is const char *. Hence on using
+	 * params as "const char *" compiler throws warning.
+	 */
+	params_args = strdup(params);
+	token = strtok(params_args, dlim);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+
+	heap_id = strtoul(token, NULL, 10);
+	if (heap_id >= RTE_MAX_HEAPS) {
+		free(params_args);
+		return -1;
+	}
+
+	token = strtok(NULL, dlim);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+
+	ms_list_idx = strtoul(token, NULL, 10);
+	if (ms_list_idx >= RTE_MAX_MEMSEG_LISTS) {
+		free(params_args);
+		return -1;
+	}
+
+	token = strtok(NULL, dlim);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+
+	ms_idx = strtoul(token, NULL, 10);
+
+	free(params_args);
+
+	rte_mcfg_mem_read_lock();
+
+	mcfg = rte_eal_get_configuration()->mem_config;
+	msl = &mcfg->memsegs[ms_list_idx];
+	ms = rte_fbarray_get(&msl->memseg_arr, ms_idx);
+	if (ms == NULL) {
+		rte_mcfg_mem_read_unlock();
+		RTE_LOG(DEBUG, EAL, "Error fetching requested memseg.\n");
+		return -1;
+	}
+
+	ms_start_addr = ms->addr_64;
+	ms_end_addr = (uint64_t)RTE_PTR_ADD(ms_start_addr, ms->len);
+	rte_mcfg_mem_read_unlock();
+
+	rte_tel_data_start_dict(d);
+
+	heap = &mcfg->malloc_heaps[heap_id];
+	rte_spinlock_lock(&heap->lock);
+
+	elem = heap->first;
+	while (elem) {
+		elem_start_addr = (uint64_t)elem;
+		elem_end_addr =
+			(uint64_t)RTE_PTR_ADD(elem_start_addr, elem->size);
+
+		if ((uint64_t)elem_start_addr >= ms_start_addr &&
+		    (uint64_t)elem_end_addr <= ms_end_addr)
+			elem_count++;
+		elem = elem->next;
+	}
+
+	rte_spinlock_unlock(&heap->lock);
+
+	rte_tel_data_add_dict_int(d, "Element_count", elem_count);
+
+	return 0;
+}
+
+static int
+handle_eal_element_info_request(const char *cmd __rte_unused,
+				const char *params, struct rte_tel_data *d)
+{
+	struct rte_mem_config *mcfg;
+	struct rte_memseg_list *msl;
+	const struct rte_memseg *ms;
+	struct malloc_elem *elem;
+	struct malloc_heap *heap;
+	struct rte_tel_data *c;
+	uint64_t ms_start_addr, ms_end_addr;
+	uint64_t elem_start_addr, elem_end_addr;
+	uint32_t ms_list_idx = 0;
+	uint32_t heap_id = 0;
+	uint32_t ms_idx = 0;
+	uint32_t start_elem = 0, end_elem = 0;
+	uint32_t count = 0, elem_count = 0;
+	char dlim[2] = ":";
+	char dlim2[2] = "-";
+	char str[ADDR_STR];
+	char *params_args;
+	char *token;
+
+	if (params == NULL || strlen(params) == 0)
+		return -1;
+
+	if (strncasecmp(params, "help", strlen(params)) == 0) {
+		char buff[RTE_TEL_MAX_SINGLE_STRING_LEN];
+		snprintf(buff, RTE_TEL_MAX_SINGLE_STRING_LEN,
+			 "%s,<heap-id>:<memseg-list-id>:<memseg-id>:"
+			 "<elem-start-id>-<elem-end-id>",
+			 EAL_ELEMENT_INFO_REQ);
+		rte_tel_data_string(d, buff);
+		return 0;
+	}
+
+	/* strtok expects char * and param is const char *. Hence on using
+	 * params as "const char *" compiler throws warning.
+	 */
+	params_args = strdup(params);
+	token = strtok(params_args, dlim);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+
+	heap_id = strtoul(token, NULL, 10);
+	if (heap_id >= RTE_MAX_HEAPS) {
+		free(params_args);
+		return -1;
+	}
+
+	token = strtok(NULL, dlim);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+
+	ms_list_idx = strtoul(token, NULL, 10);
+	if (ms_list_idx >= RTE_MAX_MEMSEG_LISTS) {
+		free(params_args);
+		return -1;
+	}
+
+	token = strtok(NULL, dlim);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+
+	ms_idx = strtoul(token, NULL, 10);
+
+	token = strtok(NULL, dlim2);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+
+	start_elem = strtoul(token, NULL, 10);
+
+	token = strtok(NULL, dlim2);
+	if (token == NULL || !isdigit(*token)) {
+		free(params_args);
+		return -1;
+	}
+
+	end_elem = strtoul(token, NULL, 10);
+
+	free(params_args);
+
+	if (end_elem < start_elem)
+		return -1;
+
+	rte_mcfg_mem_read_lock();
+
+	mcfg = rte_eal_get_configuration()->mem_config;
+	msl = &mcfg->memsegs[ms_list_idx];
+	ms = rte_fbarray_get(&msl->memseg_arr, ms_idx);
+	if (ms == NULL) {
+		rte_mcfg_mem_read_unlock();
+		RTE_LOG(DEBUG, EAL, "Error fetching requested memseg.\n");
+		return -1;
+	}
+
+	ms_start_addr = ms->addr_64;
+	ms_end_addr = (uint64_t)RTE_PTR_ADD(ms_start_addr, ms->len);
+
+	rte_mcfg_mem_read_unlock();
+
+	rte_tel_data_start_dict(d);
+
+	heap = &mcfg->malloc_heaps[heap_id];
+	rte_spinlock_lock(&heap->lock);
+
+	elem = heap->first;
+	while (elem) {
+		elem_start_addr = (uint64_t)elem;
+		elem_end_addr =
+			(uint64_t)RTE_PTR_ADD(elem_start_addr, elem->size);
+
+		if (elem_start_addr < ms_start_addr ||
+				elem_end_addr > ms_end_addr) {
+			elem = elem->next;
+			continue;
+		}
+
+		if (count < start_elem) {
+			elem = elem->next;
+			count++;
+			continue;
+		}
+
+		c = rte_tel_data_alloc();
+		if (c == NULL)
+			break;
+
+		rte_tel_data_start_dict(c);
+		rte_tel_data_add_dict_int(c, "msl_id", ms_list_idx);
+		rte_tel_data_add_dict_int(c, "ms_id", ms_idx);
+		snprintf(str, ADDR_STR, "0x%"PRIx64, ms_start_addr);
+		rte_tel_data_add_dict_string(c, "memseg_start_addr", str);
+		snprintf(str, ADDR_STR, "0x%"PRIx64, ms_end_addr);
+		rte_tel_data_add_dict_string(c, "memseg_end_addr", str);
+		snprintf(str, ADDR_STR, "0x%"PRIx64, elem_start_addr);
+		rte_tel_data_add_dict_string(c, "element_start_addr", str);
+		snprintf(str, ADDR_STR, "0x%"PRIx64, elem_end_addr);
+		rte_tel_data_add_dict_string(c, "element_end_addr", str);
+		rte_tel_data_add_dict_int(c, "element_size", elem->size);
+		snprintf(str, ADDR_STR, "%s", elem->state == 0 ? "Free" :
+			 elem->state == 1 ? "Busy" : elem->state == 2 ?
+			 "Pad" : "Error");
+		rte_tel_data_add_dict_string(c, "element_state", str);
+
+		snprintf(str, ADDR_STR, "%s.%u", "elem_info", count);
+		if (rte_tel_data_add_dict_container(d, str, c, 0) != 0) {
+			rte_tel_data_free(c);
+			break;
+		}
+
+		elem_count++;
+		count++;
+		if (count > end_elem)
+			break;
+
+		elem = elem->next;
+	}
+
+	rte_spinlock_unlock(&heap->lock);
+
+	rte_tel_data_add_dict_int(d, "Element_count", elem_count);
+
+	return 0;
+}
+
 RTE_INIT(memory_telemetry)
 {
 	rte_telemetry_register_cmd(
@@ -1279,5 +1735,20 @@  RTE_INIT(memory_telemetry)
 	rte_telemetry_register_cmd(
 			EAL_HEAP_INFO_REQ, handle_eal_heap_info_request,
 			"Returns malloc heap stats. Parameters: int heap_id");
+	rte_telemetry_register_cmd(
+			EAL_MEMSEG_REQ, handle_eal_memseg_request,
+			"Returns hugepage list. Parameters: int hp_list_id");
+	rte_telemetry_register_cmd(
+			EAL_ACTIVE_MEMSEG_LIST_REQ, handle_eal_active_memseg_request,
+			"Returns hugepage list. Takes no parameters");
+	rte_telemetry_register_cmd(
+			EAL_MEMSEG_INFO_REQ, handle_eal_memseg_info_request,
+			"Returns hugepage information. Parameters: int hp_id");
+	rte_telemetry_register_cmd(EAL_ELEMENT_LIST_REQ,
+			handle_eal_element_list_request,
+			"Returns element information. Takes no parameters");
+	rte_telemetry_register_cmd(EAL_ELEMENT_INFO_REQ,
+			handle_eal_element_info_request,
+			"Returns element information. Parameters: int elem_id");
 }
 #endif
diff --git a/lib/telemetry/telemetry.c b/lib/telemetry/telemetry.c
index c6fd03a5ab..a044e6ea5f 100644
--- a/lib/telemetry/telemetry.c
+++ b/lib/telemetry/telemetry.c
@@ -23,7 +23,7 @@ 
 #include "telemetry_internal.h"
 
 #define MAX_CMD_LEN 56
-#define MAX_OUTPUT_LEN (1024 * 16)
+#define MAX_OUTPUT_LEN (1024 * 64)
 #define MAX_CONNECTIONS 10
 
 #ifndef RTE_EXEC_ENV_WINDOWS