Contribute/BiteSizedTasks: Difference between revisions
No edit summary |
|||
Line 78: | Line 78: | ||
== Consistent option usage in documentation == | == Consistent option usage in documentation == | ||
qemu uses getopt_long_only(), which means that '-help' and '--help' are parsed identically; however, the short form is considered a crutch. Meanwhile, other binaries in the qemu package use getopt_long(), which requires the double-dash form. For consistency, all documentation examples should mention the long spelling with two dashes, especially since some options (like --object) have the same syntax between multiple binaries. Note: This task needs to be discussed first on the mailing list (contact: eblake) | |||
* https://gitlab.com/qemu-project/qemu/-/issues/186 | |||
* qemu uses getopt_long_only(), which means that '-help' and '--help' are parsed identically; however, the short form is considered a crutch. Meanwhile, other binaries in the qemu package use getopt_long(), which requires the double-dash form. For consistency, all documentation examples should mention the long spelling with two dashes, especially since some options (like --object) have the same syntax between multiple binaries. Note: This task needs to be discussed first on the mailing list (contact: eblake) | |||
== CLI cleanups == | == CLI cleanups == |
Revision as of 02:37, 6 May 2021
Note: Before starting on one of these tasks, it would be wise to double-check the list archives to ensure no one else has recently submitted similar cleanups for the same task. And before submitting a patch to the mailing list, please make sure that you've read and understood the Contribute/SubmitAPatch page.
Potentially easy bugs
These are bugs that are really easy to reproduce, don't require any complicated setup and are probably some simple missing check - but there again we've not looked at them yet!
See the QEMU issue tracker for an up to date list of bugs that have been tagged "Bite Sized".
API conversion
- Replace manual qemu_mutex_lock() and qemu_mutex_unlock() calls with QEMU_LOCK_GUARD() where it makes the code easier to read. See ToDo/LockGuards for details.
- Remove leading underscores from #defines: Identifiers with leading underscores followed by another underscore or a capital letter are reserved by the C standard. Use something like
grep 'define[ \t]*_[A-Z_]' $(find -name \*.h | grep -v roms | grep -v linux)
to find files that might violate this rule, double-check whether the file should be cleaned up or not (some files that are derived from other sources like the Linux headers should not be changed), and then send patches to remove the leading underscores if it is OK there. (contact: THH) - Look for uses of malloc, and convert them to g_new or similar (see the coding style guide for more details on allocation interface usage). Likewise, convert calloc to g_new0 and friends. Drop return value checks unless using g_try_new/g_try_new0. (This needs to be done for one data structure at a time, because an allocation with malloc must be freed with free but an allocation with g_malloc must be freed with g_free. So you need to do a bit of analysis of the code to see where an allocation may be later freed.) Please ignore the mallocs in libdecnumber and tests/tcg/.
- Replace calls to functions named cpu_physical_memory_* with address_space_*.
- Replace calls to object_child_foreach() with object_child_foreach_recursive() when applicable: nvdimm_device_list, nmi_monitor_handle, find_sysbus_device, pc_dimm_slot2bitmap, build_dimm_list.
- The ToDo/CodeTransitions page tracks ongoing internal QEMU API transitions. Most are not trivial but it's a good source of ideas, and some items should be doable for newcomers, too, e.g.:
- Coding whitespace style: Some files in the util/ and other folders use TABs for indentation instead of spaces, so sending patches that affect these files usually trigger a warning by the checkpatch.pl script. Identify the files with the wrong indentations and send a patch to adapt the files to the QEMU coding style conventions (i.e. indent with 4 spaces instead of TABs). (contact: THH)
- Introduce a better alternative to strncpy. QEMU uses strncpy whenever the destination needs to be zeroed entirely, for example to avoid data leaks. Add a new function qemu_strncpy that asserts that the destination buffer is big enough to fit strlen(source)+1 bytes. Also add a new function qemu_strncpy_nonul that asserts that the destination buffer is big enough to fit strlen(source) bytes (thus not guaranteeing NUL termination). Replace uses of strncpy throughout the QEMU sources.
Code Modernization
- Convert routines with multiple goto exit-paths to use g_autoptr/g_autofree to handle clean-up and allow direct returns
- Replace common idioms like if (s->len > 0) { g_string_append(s, ", "); } g_string_append(s, "foo") with common helper function
Header cleanups
- Clean up includes to reduce compile time. There are many "touch it, recompile the world" headers in the QEMU project. See http://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg07189.html for a list of headers (not all of them can be cleaned up, though) and http://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg06941.html for examples how to get rid of them. (contact: THH)
- Run '
grep -rl "Temple Place" *
' to find some files that still have the old address of the FSF (they moved to a different location since a couple of years already). Replace the address with the URL to the GPL license text instead
Device models
- Categorize devices: Run "
qemu-system-x86_64 -device help
" or "qemu-system-arm -M none -device help
" and look for devices that are in the "uncategorized devices" section. Ideally, each device should have a category, even if it's just the "misc devices" category. Identify the source file of such an uncategorized devices and set an appropriate DEVICE_CATEGORY bit in its device class categories field (use "grep -r DEVICE_CATEGORY hw/
" to see some examples). (contact: THH) - Look for invocations of qemu_system_reset_request() in hw/. Whenever they correspond to some kind of watchdog that has triggered, change to watchdog_perform_action().
- "QOMify" devices: Some devices are still not adapted to the recent QEMU Object Model (QOM) yet. Try to identify such devices and convert them to the recent QOM device model. Details can be found in Andreas Färber's talk during KVM Forum 2013: https://www.youtube.com/watch?v=9LXvZOrHwjw . Note that this is a rather advanced task already. (contact: THH)
- Add support for attribute((bitwise)), tag structure fields and use that for static checking of structure endian-ness accesses
- Implement the "Backend program conventions" from vhost-user.rst, including the standard command-line options and vhost-user.json for
contrib/vhost-user-blk/
andcontrib/vhost-user-scsi/
. Seecontrib/vhost-user-input/
for an example.
Error checking
- Add checks for negative return value to uses of load_image_targphys, get_image_size, event_notifier_init, msix_init.
- Use qemu_strtol/qemu_strtoul/qemu_strtoll/qemu_strtoull more. (contact: eblake)
- Make qemu_thread_create return a flag to indicate if it succeeded rather than failing with an error; make all callers check it. Previous largely complete work https://lists.gnu.org/archive/html/qemu-devel/2019-07/msg03964.html
- Using "NULL" for errp in case "it cannot fail" should be avoided. If there is an unexpected error generated, it will simply be ignored. Making use of "&error_abort" instead allows us to catch unexpected errors.
- Dereferencing errp to check for errors is wrong "because errp may be NULL!". Making use of a local Error * and call error_propagate() instead, as explained in "qapi/error.h".
- Look for code that checks for errno == EINTR. If the code is simply doing something like '
do { x = expr(); } while (x == -1 && errno == EINTR);
', you can replace the surrounding loop with the TFR() macro from include/qemu-common.h instead. - strerror() is not thread safe (completely unsafe in FreeBSD, while on glibc it threadsafe for defined errno values but non-safe for out-of-range values); the code base needs to be audited for a conversion to g_strerror() (which is an easy-to-use wrapper around the thread-safe strerror_r() function)
Dead code removal
- Use the technique described at https://blog.flameeyes.eu/2008/01/today-how-to-identify-unused-exported-functions-and-variables to identify unused global functions and variables, try to decide whether it's a good idea to remove the detected code fragments and send (single) patches to remove them if applicable. (contact: THH)
Compiler-driven cleanups
- Use of -Wshadow while compiling can prevent legitimate bugs, but can't be enabled until we first clean up the code base to avoid shadowed declarations.
- Use of -Wvla and -Wframe-larger-than=4096 can prevent the use of potential security flaws caused by stack overflows made possible with variable-length arrays or other over-large stack allocations.
- The following functions have very large stack frames (as obtained with -Wstack-usage=16383), mostly due to huge arrays. Make the stack array smaller and allocate on the heap in the rare case that the data does not fit in the small array:
hw/dma/xilinx_axidma.c stream_process_mem2s 16480 bytes hw/net/virtio-net.c virtio_net_receive 16544 bytes net/tap.c net_init_tap 16752 bytes hw/display/vmware_vga.c vmsvga_fifo_run 20688 bytes hw/virtio/virtio.c virtqueue_pop 24768 bytes hw/net/virtio-net.c virtio_net_flush_tx 32928 bytes hw/virtio/virtio.c qemu_get_virtqueue_element 49216 bytes hw/virtio/virtio.c qemu_put_virtqueue_element 49216 bytes hw/net/opencores_eth.c open_eth_start_xmit 65664 bytes hw/arm/nseries.c n8x0_init 65728 bytes net/net.c nc_sendv_compat 69680 bytes net/socket.c net_socket_send 69712 bytes
Tracing
- Add tracepoints. All functions that are named something_helper, and all functions mentioned in MemoryRegionOps are good candidates.
- Convert DPRINTF() calls to tracepoints.
Bitrot prevention
- Files with conditional debug statements should ensure that the printf is always compiled, and merely hidden behind
if (0)
when not debugging, rather than#ifdef
'd out. This prevents bitrot of the format string of the debug statement. See this (commitc691320faa6
) for an example. Or, go one step further and convert the debug statements to tracepoints. (contact: eblake)
Functions that should be static
- For example: vga_sync_dirty_bitmap, WC_CONFIG_STRING, WC_FULL_CONFIG_STRING, WC_MODEL_STRING, timer_put, vfio_region_ops, vfio_reset_handler, cpu_gen_init, monitor_read_bdrv_key_start, pdu_marshal, pdu_unmarshal, qcrypto_hmac_alg_map (crypto/hmap-nettle.c), spapr_tce_set_need_vfio, virtqueue_map, vnc_disconnect_finish, vnc_display_init, gicv3_full_update_noirqset, cpu_disable_ticks, cpu_enable_ticks, qemu_thread_exit (actually unused in thread-posix.c), qemu_egl_init_dpy_mesa, monitor_defs (3 occurrences), apic_deliver_irq, pcie_host_mmcfg_map, pcie_host_mmcfg_unmap
- tracetool-generated arrays (e.g. hw_mem_trace_events in the generated file hw/mem/trace.c) should be static.
- The property types defined in hw/core/qdev-properties-system.c should be moved to other directories (e.g. hw/net for network-related property types). After doing this, some functions probably could become static, too.
Consistent option usage in documentation
- https://gitlab.com/qemu-project/qemu/-/issues/186
- qemu uses getopt_long_only(), which means that '-help' and '--help' are parsed identically; however, the short form is considered a crutch. Meanwhile, other binaries in the qemu package use getopt_long(), which requires the double-dash form. For consistency, all documentation examples should mention the long spelling with two dashes, especially since some options (like --object) have the same syntax between multiple binaries. Note: This task needs to be discussed first on the mailing list (contact: eblake)
CLI cleanups
- A collection of command-lines that can crash QEMU can be generated with the scripts/device-crash-test tool from the QEMU sources (but currently, we seem to be in a good shape, so if you don't see any useful output, pick another task instead)
Coroutines
QEMU uses coroutines for asynchronous operations, especially in the block layer (disk I/O, disk image formats, network storage protocols, etc). The basics of coroutines are explained here.
- https://gitlab.com/qemu-project/qemu/-/issues/185 - All functions that may yield (either directly or indirectly through a function they call) must be marked coroutine_fn in their function signature. There is no build-time check for coroutine_fn, so it is accidentally missing in some places. Search the code for function names that contain _co_ or end with _co() or functions that call qemu_coroutine_yield(), qemu_co_queue_wait(), or any other coroutine_fn. Add coroutine_fn to the function signature if it is missing.
Contact persons
Some of these tasks are described very briefly and somewhat cryptically. If you're not sure what a task involves, then feel free to ask for clarification on the qemu-devel mailing list, or the contact person for the task (if the task has been marked with a contact):
- THH: Thomas Huth (mail: thuth AT redhat.com -- IRC: th_huth)
- eblake: Eric Blake (mail: eblake AT redhat.com -- IRC: eblake)