u-boot/common
Stephen Warren 4f144a4164 malloc: work around some memalign fragmentation issues
Use of memalign can trigger fragmentation issues such as:

// Internally, this needs to find a free block quite bit larger than s.
// Once the free region is found, any unaligned "padding" immediately
// before and after the block is marked free, so that the allocation
// takes only s bytes (plus malloc header overhead).
p = memalign(a, s);
// If there's little fragmentation so far, this allocation is likely
// located immediately after p.
p2 = malloc(x);
free(p);
// In theory, this should return the same value for p. However, the hole
// left by the free() call is only s in size (plus malloc header overhead)
// whereas memalign searches for a larger block in order to guarantee it
// can adjust the returned pointer to the alignment requirements. Hence,
// the pointer returned, if any, won't be p. If there's little or no space
// left after p2, this allocation will fail.
p = memalign(a, s);

In practice, this issue occurs when running the "dfu" command repeatedly
on NVIDIA Tegra boards, since DFU allocates a large 32M data buffer, and
then initializes the USB controller. If this is the first time USB has
been used in the U-Boot session, this causes a probe of the USB driver,
which causes various allocations, including a strdup() of a GPIO name
when requesting the VBUS GPIO. When DFU is torn down, the USB driver
is left probed, and hence its memory is left allocated. If "dfu" is
executed again, allocation of the 32M data buffer fails as described
above.

In practice, there is a memory hole exactly large enough to hold the 32M
data buffer than DFU needs. However, memalign() can't know that in a
general way. Given that, it's particularly annoying that the allocation
fails!

The issue is that memalign() tries to allocate something larger to
guarantee the ability to align the returned pointer. This patch modifies
memalign() so that if the "general case" over-sized allocation fails,
another allocation is attempted, of the exact size the user desired. If
that allocation just happens to be aligned in the way the user wants,
(and in the case described above, it will be, since the free memory
region is located where a previous identical allocation was located),
the pointer can be returned.

This patch is somewhat related to 806bd245b1 "dfu: don't keep
freeing/reallocating". That patch worked around the issue by removing
repeated free/memalign within a single execution of "dfu". However,
the same technique can't be applied across multiple invocations, since
there's no reason to keep the DFU buffer allocated while DFU isn't
running. This patch addresses the root-cause a bit more directly.

This problem highlights some of the disadvantages of dynamic allocation
and deferred probing of devices.

This patch isn't checkpatch-clean, since it conforms to the existing
coding style in dlmalloc.c, which is different to the rest of U-Boot.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Acked-by: Lukasz Majewski <l.majewski@samsung.com>
2016-02-01 17:08:43 -05:00
..
init x86: Fix board init breakage 2016-01-15 08:09:46 -05:00
spl block: pass block dev not num to read/write/erase() 2016-01-13 21:05:18 -05:00
autoboot.c Move console definitions into a new console.h file 2015-11-19 20:27:50 -07:00
bedbug.c Consolidate bool type 2013-04-01 16:33:52 -04:00
board_f.c dm: common: Add memory reservation for the video uclass 2016-01-20 19:10:15 -07:00
board_info.c generic-board: allow showing custom board info 2015-08-13 07:19:36 -04:00
board_r.c CONFIG_NEEDS_MANUAL_RELOC: Fix warnings when not set 2015-12-07 08:35:23 -05:00
bootm_os.c VxWorks: fixup MAC address for VxWorks 2015-12-12 15:56:08 -05:00
bootm.c bootm: fix size arg of flush_cache() in bootm_load_os(). 2016-01-25 10:39:45 -05:00
bootretry.c Rename bootretry functions and remove #ifdefs 2014-05-29 17:49:00 -04:00
bootstage.c Add GPL-2.0+ SPDX-License-Identifier to source files 2013-07-24 09:44:38 -04:00
bouncebuf.c Fix a few printf argument verification warnings 2014-09-15 13:32:55 -04:00
cli_hush.c common: cli_hush: Fix up simple typo 2015-12-12 15:56:10 -05:00
cli_readline.c spl, common, serial: build SPL without serial support 2015-08-12 20:47:13 -04:00
cli_simple.c common: cli_simple: use strlcpy instead of strcpy 2016-01-13 21:05:26 -05:00
cli.c common: cli: avoid memory leak 2016-01-04 12:25:35 -05:00
command.c Move console definitions into a new console.h file 2015-11-19 20:27:50 -07:00
console.c common/console.c: Remove unused inline functions 2016-01-25 10:39:47 -05:00
cros_ec.c cros_ec: Remove unused cros_ec_board_init() function 2015-04-18 11:11:16 -06:00
ddr_spd.c Add more SPDX-License-Identifier tags 2016-01-19 08:31:21 -05:00
dlmalloc.c malloc: work around some memalign fragmentation issues 2016-02-01 17:08:43 -05:00
dlmalloc.src Consolidate bool type 2013-04-01 16:33:52 -04:00
edid.c edid: Add a function to read detailed monitor timings 2015-05-13 09:24:10 -07:00
env_attr.c env: Add regex support to env_attrs 2015-05-21 09:13:19 -04:00
env_callback.c common: env: initialize scalar variable 2016-01-04 12:25:35 -05:00
env_common.c Add option -r to env import to allow import of text files with CRLF as line endings 2014-07-22 07:44:26 -04:00
env_dataflash.c env: Add env_export() wrapper 2014-03-21 16:43:59 -04:00
env_eeprom.c eeprom: Add bus argument to eeprom_init() 2015-11-21 21:50:26 -05:00
env_embedded.c nand_spl: remove nand_spl infrastructure 2014-06-05 17:01:59 -04:00
env_fat.c Move ALLOC_CACHE_ALIGN_BUFFER() to the new memalign.h header 2015-09-11 17:15:20 -04:00
env_flags.c common: env_flags: fix loop condition when using env_flags_varaccess_mask 2016-01-13 21:05:26 -05:00
env_flash.c env_flash.c: Drop unused variables 2014-04-17 17:44:36 -04:00
env_mmc.c env_mmc: support overriding mmc dev from board code 2016-01-25 10:39:46 -05:00
env_nand.c Move ALLOC_CACHE_ALIGN_BUFFER() to the new memalign.h header 2015-09-11 17:15:20 -04:00
env_nowhere.c Coding Style cleanup: remove trailing white space 2013-10-14 16:06:53 -04:00
env_nvram.c env: Add env_export() wrapper 2014-03-21 16:43:59 -04:00
env_onenand.c env: Add env_export() wrapper 2014-03-21 16:43:59 -04:00
env_remote.c Coding Style cleanup: remove trailing white space 2013-10-14 16:06:53 -04:00
env_sf.c dm: env_sf: fix saveenv() to use driver model 2016-01-27 08:28:40 -08:00
env_ubi.c env_ubi.c: Correct pointer error in env load 2015-11-19 07:32:49 +01:00
exports.c board/ls2085rdb: Export functions for standalone AQ FW load apps 2015-07-20 11:44:37 -07:00
fb_mmc.c block: pass block dev not num to read/write/erase() 2016-01-13 21:05:18 -05:00
fb_nand.c sparse: Rename the file and header 2015-11-12 13:18:59 -05:00
fdt_support.c Revert "fdt_support: Add multi-serial support for stdout fixup" 2016-01-20 19:10:12 -07:00
flash.c mpc8xx: remove SPD823TS board support 2015-01-05 12:08:51 -05:00
hash.c hash.c: Conditionally compile hash_command, static hash_show 2016-01-13 21:05:08 -05:00
hwconfig.c Add GPL-2.0+ SPDX-License-Identifier to source files 2013-07-24 09:44:38 -04:00
image-android.c image: fix support for Android boot images with no ramdisk 2015-10-11 17:12:10 -04:00
image-fdt.c common: image-fdt: correct fdt_blob for IMAGE_FORMAT_LEGACY 2015-12-05 18:22:15 -05:00
image-fit.c image-fit: Fix signature checking 2015-10-19 17:06:16 -04:00
image-sig.c image: Convert to use fdt_for_each_subnode macro 2015-02-16 12:41:41 -05:00
image-sparse.c sparse: Rename the file and header 2015-11-12 13:18:59 -05:00
image.c image: fix getenv_bootm_size() function 2016-01-19 08:31:11 -05:00
iomux.c Move console definitions into a new console.h file 2015-11-19 20:27:50 -07:00
iotrace.c common: Make sure arch-specific map_sysmem() is defined 2015-04-18 11:11:09 -06:00
kallsyms.c
Kconfig Move all command code into its own directory 2016-01-25 10:39:43 -05:00
kgdb_stubs.c
kgdb.c kgdb: Remove first_entry for kgdb 2014-09-16 12:23:56 -04:00
lcd_console_rotation.c common/lcd_console: introduce display/framebuffer rotation 2015-04-18 17:40:37 +02:00
lcd_console.c common/lcd_console: introduce display/framebuffer rotation 2015-04-18 17:40:37 +02:00
lcd_simplefb.c common/lcd_simplefb: Add support for 32bit organized framebuffers 2015-07-23 18:10:58 +02:00
lcd.c lcd: fix the color testpattern in 16bit mode 2016-01-24 00:38:40 +01:00
lynxkdi.c checkpatch whitespace cleanups 2011-10-22 01:13:35 +02:00
main.c Move console definitions into a new console.h file 2015-11-19 20:27:50 -07:00
Makefile Move all command code into its own directory 2016-01-25 10:39:43 -05:00
malloc_simple.c Merge git://git.denx.de/u-boot-x86 2015-10-21 20:47:40 -04:00
memsize.c common/memsize.c: Coding style cleanup 2015-01-14 11:35:43 -05:00
menu.c menu: Return an error code if Ctrl-C is pressed 2015-05-27 13:35:54 -04:00
miiphyutil.c common: miiphyutil: avoid memory leak 2015-12-05 18:22:24 -05:00
modem.c modem.c: Switch to debug() from dbg found in common/console.c 2014-10-25 07:27:37 -04:00
s_record.c Add GPL-2.0+ SPDX-License-Identifier to source files 2013-07-24 09:44:38 -04:00
splash_source.c splash_source: add support for filesystem formatted sata 2015-11-16 12:01:35 +01:00
splash.c lcd: split splash code into its own function 2015-02-10 13:31:58 +01:00
stdio.c stdio: Correct a build error with driver model 2016-01-21 20:42:36 -07:00
system_map.c
update.c update: tftp: dfu: Extend update_tftp() function to support DFU 2015-09-07 13:41:05 +02:00
usb_hub.c dm: usb: Avoid time delays in sandbox tests 2015-11-19 20:27:50 -07:00
usb_kbd.c usb: kbd: Prevent out of bound access 2016-01-25 22:00:46 +01:00
usb_storage.c usb: Define USB_MAX_STOR_DEV in only one place 2016-01-20 19:06:23 -07:00
usb.c common: usb: fix checking condition 2016-01-16 07:06:55 +01:00
xyzModem.c common/xyzModem.c: move empty statements to newline 2014-06-11 16:27:06 -04:00