aboutsummaryrefslogtreecommitdiff
path: root/src/target/arm_dap.c
diff options
context:
space:
mode:
authorBohdan Tymkiv <bhdt@cypress.com>2019-02-26 11:45:40 +0200
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>2019-10-18 09:20:49 +0100
commit5f42124a40e8ccbc1b5db3a8898d24408be22c62 (patch)
tree8d87a2bb7739a93ea42ef7790de1dda9a7458e77 /src/target/arm_dap.c
parent03beb01239a8ca02787cb99d19401b1974fe41c4 (diff)
downloadriscv-openocd-5f42124a40e8ccbc1b5db3a8898d24408be22c62.zip
riscv-openocd-5f42124a40e8ccbc1b5db3a8898d24408be22c62.tar.gz
riscv-openocd-5f42124a40e8ccbc1b5db3a8898d24408be22c62.tar.bz2
adi_v5_jtag: avoid RAM exhaustion by limiting jtag queue size
Issue has been found when I tried to read 64 MiB QSPI flash bank. Bank is memory mapped, default_flash_read() is used for 'flash read_bank' command. OpenOCD consumed as much as 6.8 GiB of RAM during this process. Investigation showed that this happens because JTAG queue is not limited in any way. OpenOCD queues 16 millions of AP reads allocating all corresponding data structures. Most of this memory is allocated in: cmd_queue_alloc (commands.c) - 4.2 GiB dap_cmd_new (adi_v5_jtag.c) - 2.25GiB This patch implements a pool of "struct dap_cmd" objects using linked list. Objects are taken from a pool in "dap_cmd_new()" and returned to the pool when they are not needed. Size of the pool is limited to 64K of objects, JTAG queue is forcibly executed when this limit is reached. Checked with Valgrind and Clang analyzer - no new warnings. Change-Id: I5aaaecce5ed71414f7965a2598f49742f6a6b2b5 Signed-off-by: Bohdan Tymkiv <bhdt@cypress.com> Reviewed-on: http://openocd.zylin.com/4948 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
Diffstat (limited to 'src/target/arm_dap.c')
-rw-r--r--src/target/arm_dap.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c
index fbcfe0d..0f29578 100644
--- a/src/target/arm_dap.c
+++ b/src/target/arm_dap.c
@@ -59,6 +59,7 @@ static void dap_instance_init(struct adiv5_dap *dap)
dap->ap[i].csw_default = CSW_AHB_DEFAULT;
}
INIT_LIST_HEAD(&dap->cmd_journal);
+ INIT_LIST_HEAD(&dap->cmd_pool);
}
const char *adiv5_dap_name(struct adiv5_dap *self)