On Mittwoch, 13. Februar 2019 13:48:21 CET Bohdan Tymkiv wrote:
> Hi all,
> 
> I've found an interesting issue while working with 64 MiB external QSPI
> flash bank. Bank is memory mapped, so 'default_flash_read()' is used in the
> flash driver. OpenOCD consumes as much as 6.8 GiB (!!!) of RAM when I am
> trying to read (flash read_bank) or verify (flash verify_bank) the contents
> of this bank. This is reproducible with JTAG transport only.
> 
> That was surprising so I've made small investigation and found that most of
> the memory is allocated in:
> cmd_queue_alloc (commands.c) - 4.2 GiB
> dap_cmd_new (adi_v5_jtag.c) - 2.25GiB
> 
> This happens because JTAG queue size is not limited in any way. OpenOCD
> queues 16 million of AP reads allocating all corresponding data structures.
> Full valgrind log is available on pastebin:
> https://pastebin.com/raw/0vjHXxk6
> 
> Some of the possible solutions to the problem are:
> [1] Check the number of queued commands in adi_v5_jtag.c within
> jtag_(dp|ap)_q_(read|write) functions and forcibly execute the queue by
> calling dap_run() when number of queued commands exceeds some limit. I am
> currently testing this approach and it seems to work correctly, but this
> change affects all targets so I am not sure if it will not make things
> broken.
> 
> [2] Read data in small chunks (e.g. 64 KiB) in
> handle_flash_read_bank_command etc. This is more safe but it does not cover
> all possible cases.
> 
> Any suggestion on this? I am ready to submit the patch [1] to gerrit but I
> would like to hear the opinion of the community.

I like the idea [1]. I remember I had a patch around myself to counter the 
excessive 
memory usage. But I wasn't sure about the performance impact and so I never 
submitted 
it. I'm trying to recall where and in which context I did that patch and if 
it's still around in 
some branch.

If you craft such a patch, I suggest you do the following:
- make a pool of "struct dap_cmd". limit the pool size to a sane number
- dap_cmd_new() checks the pool for available objects first
  * allocates a new one if none available and limit not reached
  * call dap_run() if limit reached. Mind you, error handling is tricky!
- create a dap_cmd_free() that returns dap_cmd objects to the pool instead of 
freeing 
them (modified version of flush_journal()).
- maybe add some garbage collection to flush the pool after a while

BR,
Matthias

> 
> Thanks,
> Bohdan Tymkiv


-- 
Mit freundlichen Grüßen/Best regards,

Matthias Welwarsky
Project Engineer

SYSGO AG
Office Mainz
Am Pfaffenstein 14 / D-55270 Klein-Winternheim / Germany
Phone: +49-6136-9948-0 / Fax: +49-6136-9948-10
VoIP: SIP:[email protected]
E-mail: [email protected] / Web: http://www.sysgo.com
_________________________________________________________________________________
 Web: 
https://www.sysgo.com
Blog: https://www.sysgo.com/blog
Events: https://www.sysgo.com/events
Newsletter: https://www.sysgo.com/newsletter 
_________________________________________________________________________________
 
Handelsregister/Commercial Registry: HRB Mainz 90 HRB 8066
Vorstand/Executive Board: Etienne Butery (CEO), Kai Sablotny (COO)
Aufsichtsratsvorsitzender/Supervisory Board Chairman: Marc Darmon
USt-Id-Nr./VAT-Id-No.: DE 149062328
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to