Contribute/BiteSizedTasks: Difference between revisions

From QEMU
(Added another small task to remove unused functions and variables)
(The watchdog_perform_action() cleanup has been done (apart from spapr, which is too complicated to be bite-sized))
 
(153 intermediate revisions by 19 users not shown)
Line 1: Line 1:
This list is in the process of being re-evaluated and migrated to the [https://gitlab.com/qemu-project/qemu/-/issues QEMU issue tracker] using the [https://gitlab.com/qemu-project/qemu/-/issues?label_name%5B%5D=Bite+Sized Bite Sized] issue label.
'''For QEMU maintainers''': Please add your new suggestions to the [https://gitlab.com/qemu-project/qemu/-/issues issue tracker] instead, and add the [https://gitlab.com/qemu-project/qemu/-/issues?label_name%5B%5D=Bite+Sized Bite Sized label]. Please migrate any existing still relevant ideas to the issue tracker and remove them from this page afterward.
'''For new contributors''': Before starting on one of the tasks on this page, you should check the [https://lists.gnu.org/archive/html/qemu-devel/ mailing list archives] to ensure no one else has recently submitted similar cleanups for the same task. If nobody has, and the task appears valid, please reach out on the [[Contribute/MailingLists|QEMU development mailing list]] and let us know you'd like to start working on the issue. Please CC: John Snow <jsnow AT redhat.com> when doing so, they'll help get you assigned a GitLab issue and find the right points of contact.
For tasks on the issue tracker or on this page, patches are still handled by submitting patches to the mailing list and not via Gitlab merge requests. Before submitting a patch to the mailing list, please make sure that you've read and understood the [https://www.qemu.org/docs/master/devel/submitting-a-patch.html patch submission] page.
__TOC__
__TOC__
'''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.


'''Note''': 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.
== General Notes ==
 
In many cases, items on this page describe tasks that might apply to many files in QEMU's sources. In this case, you shouldn't try to solve the problem for the whole of QEMU all at once. Instead, pick a small part of it, ideally related to what you're interested in, and look only at the file or files relevant to that. (For instance, if you're interested in Arm emulation, look at whether one of the tasks affects an Arm device model source file.) It's likely to be more useful to you if you take a particular part of the codebase, and make various different cleanups to it, thus gradually becoming more familiar with it, better able to test it, and so on, rather than trying to make one cleanup to many different parts of QEMU.
 
Where there is a gitlab issue for a task, that will usually have more detail than the entry on this page; gitlab issues generally are probably more likely to have been defined in a way that will make them tractable for a first-time contributor.
 
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).
 
== Gitlab "Bite Sized" Issues ==
 
Issues tagged "[https://gitlab.com/qemu-project/qemu/-/issues?label_name%5B%5D=Bite+Sized Bite Sized]" on the issue tracker may be good candidates for first contributions. If you're interested in solving one of these problems, please register for a Gitlab account and participate in the discussion on the issue so it will be evident to others that you are engaged in researching and fixing the issue.
 
The issues may sometimes appear to be cryptic or vague. Don't hesitate to ask for more information if the task is not clear. If there is no obvious point of contact from the issue page itself, please reach out for help on the [[Contribute/MailingLists|qemu development mailing list]].


== API conversion ==
== API conversion ==
* Look for uses of malloc, and convert them to either g_malloc, g_new (more rarely g_try_malloc or g_try_new if a lot of memory is being allocated). Likewise, convert calloc to either g_new0 or g_try_new0. Drop return value checks unless using g_try_new/g_try_new0.
* 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.
* [[CodeTransitions#Makefile|Associate external libraries with the object files that actually use them]]
* Look for uses of malloc, and convert them to g_new or similar. See the fuller writeup in [https://gitlab.com/qemu-project/qemu/-/issues/1798 the issue on the bug tracker] for more information and a list of the remaining places that need conversion (and the places that don't need it).
* <del>For all "QEMUTimer*" variables that are initialized with timer_new, change them to "QEMUTimer" and initialize them with timer_init.  Drop any timer_free calls (there aren't many, so this patch would fix small memory leaks too).</del> (not quite bite-sized).
* Replace calls to functions named cpu_physical_memory_* with address_space_*.
* Replace calls to functions named cpu_physical_memory_* with address_space_*.
* Change net/socket.c to use the functions in include/qemu/sockets.h instead of parse_host_port/bind/connect/listen.
* 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.
* Change QemuMutex and QemuCond to CompatGMutex and CompatGCond (these are the same as GMutex and GCond, just with a different type).  With this change, qemu_mutex_init/qemu_cond_init becomes optional for global variables.
* 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.
* Change get_ticks_per_sec() calls to just use the NANOSECONDS_PER_SECOND constant.
* QSIMPLEQ_REMOVE and QSLIST_REMOVE are inefficient. Check if they could be replaced by QSIMPLEQ_REMOVE_HEAD and QSLIST_REMOVE_HEAD; if not, use a QTAILQ or QLIST respectively.
* <del>Remove macros IO_READ_PROTO and IO_WRITE_PROTO.</del>
* Replace calls to object_child_foreach() with object_child_foreach_recursive() when applicable.
* Change basename and dirname to g_path_get_basename() and g_path_get_dirname() respectively.
* Devices which create MemoryRegions with the old_mmio accessors should be converted to new style mmio accessors.
* The [[CodeTransitions]] page tracks ongoing internal QEMU API transitions. Most are not trivial but it's a good source of ideas.
 
== Header cleanups ==
* <del>avoid including include/exec/exec-all.h from other headers.</del> (now owned by Paolo Bonzini)
* avoid including files from include/exec/cpu-common.h.
* move declarations out of qemu-common.h for functions declared in utils/ files: e.g. include/qemu/path.h for utils/path.c, include/qemu/id.h for utils/id.c, etc.
* move inline functions out of qemu-common.h and into new files (e.g. include/qemu/bcd.h).


== Device models ==
== Code Modernization ==
* Include SDState by value instead of allocating it in sd_init (hw/sd/).
* Convert routines with multiple goto exit-paths to use g_autoptr/g_autofree to handle clean-up and allow direct returns
* 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().
* Replace common idioms like '''if (s->len > 0) { g_string_append(s, ", "); } g_string_append(s, "foo")''' with common helper function
* Replace hand-coded uri_string_escape/uri_string_unescape with glib equivalents, for bonus points unify open-coded to/from hex routines with the gdbstub equivilents


== Error checking ==
== Error checking ==
* Add checks for NULL return value to uses of qemu_find_file.
* Use qemu_strtol/qemu_strtoul/qemu_strtoll/qemu_strtoull more. (contact: eblake)
* 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.
 
== Device lifecycle ==
* IDE uses qemu_add_vm_change_state_handler() without a corresponding qemu_del_vm_change_state_handler().  This means hot unplugging an AHCI PCI adapter results in a dangling change state handler and could lead to a crash.


== Large frames ==
== Compiler-driven cleanups ==
* Use of -Wframe-larger-than=4096 can prevent the use of potential security flaws caused by stack overflows made possible with 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:
* 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:


Line 42: Line 46:
  hw/net/virtio-net.c                  virtio_net_receive              16544 bytes
  hw/net/virtio-net.c                  virtio_net_receive              16544 bytes
  net/tap.c                            net_init_tap                    16752 bytes
  net/tap.c                            net_init_tap                    16752 bytes
block/vmdk.c                        vmdk_write_cid.isra.8            20544 bytes
  hw/display/vmware_vga.c              vmsvga_fifo_run                  20688 bytes
  hw/display/vmware_vga.c              vmsvga_fifo_run                  20688 bytes
  hw/virtio/virtio.c                  virtqueue_pop                    24768 bytes
  hw/virtio/virtio.c                  virtqueue_pop                    24768 bytes
Line 49: Line 52:
  hw/virtio/virtio.c                  qemu_put_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/net/opencores_eth.c              open_eth_start_xmit              65664 bytes
hw/net/spapr_llan.c                  h_send_logical_lan              ~64Kbytes (uses alloca)
  hw/arm/nseries.c                    n8x0_init                        65728 bytes
  hw/arm/nseries.c                    n8x0_init                        65728 bytes
  net/net.c                            nc_sendv_compat                  69680 bytes
  net/net.c                            nc_sendv_compat                  69680 bytes
  net/socket.c                        net_socket_send                  69712 bytes
  net/socket.c                        net_socket_send                  69712 bytes


:For a larger list of functions with stack sizes of 1K or bigger, see http://article.gmane.org/gmane.comp.emulators.qemu/314061
Note that this list is likely out of date. If you want to work on this you should start by identifying some functions worth looking at by building QEMU yourself with --extra-cflags=-Wstack-usage=16383 --disable-werror . Then you can capture the output of the compile process (e.g. with make -C build -j8 2>&1 | tee stack-usage.log) and look for the warnings in the log file. Come and talk to us on the qemu-devel list about this before putting much work into it -- there are quite a lot of functions with large or even theoretically unbounded stack usage, but not all of them are in places in the code where it's important.
 
== Dead code removal ==
* hw/display contains files named *_template.h.  These are included many times with different values of the DEPTH macro. However, only the DEPTH == 32 case is used. Remove support for DEPTH != 32 in the template headers and in the file that include them.
* Look for functions that are named *_exit or *_exitfn in hw/ and that return int.  They should all return zero.  Make them return void, and remove the checks for the callers.
* Once the above change is done, remove the "Error **" argument from functions named *_unrealize in hw/
* Remove bdrv_aio_multiwrite() since virtio-blk no longer uses it and the only remaining caller, qemu-io, is for testing only
* 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.


== Tracing ==
== Tracing ==
* Add tracepoints.  All functions that are named ''something''_helper, and all functions mentioned in MemoryRegionOps are good candidates.
* Add tracepoints.  All functions that are named ''something''_helper, and all functions mentioned in MemoryRegionOps are good candidates.
* Convert DPRINTF() calls to tracepoints (see https://gitlab.com/qemu-project/qemu/-/issues/1827 in the bug tracker for more details)


== Bitrot prevention ==
== Bitrot prevention ==
* Files with conditional debug statements should ensure that the printf is always compiled, and merely hidden behind <code>if (0)</code> when not debugging, rather than <code>#ifdef</code>'d out.  This prevents bitrot of the format string of the debug statement.  See commit c691320faa6 for an example.  Or, go one step further and convert the debug statements to tracepoints.
* Files with conditional debug statements should ensure that the printf is always compiled, and merely hidden behind <code>if (0)</code> when not debugging, rather than <code>#ifdef</code>'d out.  This prevents bitrot of the format string of the debug statement.  See this {{git|c691320faa6}} for an example.  Or, go one step further and convert the debug statements to tracepoints. For more detail on tracepoint conversion, see the issue in the bug tracker: https://gitlab.com/qemu-project/qemu/-/issues/1827 (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.
 
== Contact persons ==
 
For tasks above marked with a "(contact: foo)" point of contact, these are those peoples' names, IRC nicks, and email addresses to get in contact with them.


== Misc ==
* eblake: Eric Blake (mail: eblake AT redhat.com -- IRC: eblake)
* <del>Improve the qemu_hexdump() function in util/hexdump.c to also print out an ASCII dump of the buffer (just like the hex_dump() function in net/net.c is doing it).</del>
* jsnow: John Snow (mail: jsnow AT redhat.com -- IRC: jsnow)
* <del>Remove the duplicated hex_dump() function in net/net.c, and use qemu_hexdump() (from util/hexdump.c) instead.</del>

Latest revision as of 12:59, 9 April 2024

This list is in the process of being re-evaluated and migrated to the QEMU issue tracker using the Bite Sized issue label.

For QEMU maintainers: Please add your new suggestions to the issue tracker instead, and add the Bite Sized label. Please migrate any existing still relevant ideas to the issue tracker and remove them from this page afterward.

For new contributors: Before starting on one of the tasks on this page, you should check the mailing list archives to ensure no one else has recently submitted similar cleanups for the same task. If nobody has, and the task appears valid, please reach out on the QEMU development mailing list and let us know you'd like to start working on the issue. Please CC: John Snow <jsnow AT redhat.com> when doing so, they'll help get you assigned a GitLab issue and find the right points of contact.

For tasks on the issue tracker or on this page, patches are still handled by submitting patches to the mailing list and not via Gitlab merge requests. Before submitting a patch to the mailing list, please make sure that you've read and understood the patch submission page.

General Notes

In many cases, items on this page describe tasks that might apply to many files in QEMU's sources. In this case, you shouldn't try to solve the problem for the whole of QEMU all at once. Instead, pick a small part of it, ideally related to what you're interested in, and look only at the file or files relevant to that. (For instance, if you're interested in Arm emulation, look at whether one of the tasks affects an Arm device model source file.) It's likely to be more useful to you if you take a particular part of the codebase, and make various different cleanups to it, thus gradually becoming more familiar with it, better able to test it, and so on, rather than trying to make one cleanup to many different parts of QEMU.

Where there is a gitlab issue for a task, that will usually have more detail than the entry on this page; gitlab issues generally are probably more likely to have been defined in a way that will make them tractable for a first-time contributor.

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).

Gitlab "Bite Sized" Issues

Issues tagged "Bite Sized" on the issue tracker may be good candidates for first contributions. If you're interested in solving one of these problems, please register for a Gitlab account and participate in the discussion on the issue so it will be evident to others that you are engaged in researching and fixing the issue.

The issues may sometimes appear to be cryptic or vague. Don't hesitate to ask for more information if the task is not clear. If there is no obvious point of contact from the issue page itself, please reach out for help on the qemu development mailing list.

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.
  • Look for uses of malloc, and convert them to g_new or similar. See the fuller writeup in the issue on the bug tracker for more information and a list of the remaining places that need conversion (and the places that don't need it).
  • 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.
  • QSIMPLEQ_REMOVE and QSLIST_REMOVE are inefficient. Check if they could be replaced by QSIMPLEQ_REMOVE_HEAD and QSLIST_REMOVE_HEAD; if not, use a QTAILQ or QLIST respectively.

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
  • Replace hand-coded uri_string_escape/uri_string_unescape with glib equivalents, for bonus points unify open-coded to/from hex routines with the gdbstub equivilents

Error checking

  • Use qemu_strtol/qemu_strtoul/qemu_strtoll/qemu_strtoull more. (contact: eblake)

Compiler-driven cleanups

  • Use of -Wframe-larger-than=4096 can prevent the use of potential security flaws caused by stack overflows made possible with 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

Note that this list is likely out of date. If you want to work on this you should start by identifying some functions worth looking at by building QEMU yourself with --extra-cflags=-Wstack-usage=16383 --disable-werror . Then you can capture the output of the compile process (e.g. with make -C build -j8 2>&1 | tee stack-usage.log) and look for the warnings in the log file. Come and talk to us on the qemu-devel list about this before putting much work into it -- there are quite a lot of functions with large or even theoretically unbounded stack usage, but not all of them are in places in the code where it's important.

Tracing

  • Add tracepoints. All functions that are named something_helper, and all functions mentioned in MemoryRegionOps are good candidates.
  • Convert DPRINTF() calls to tracepoints (see https://gitlab.com/qemu-project/qemu/-/issues/1827 in the bug tracker for more details)

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 (commit c691320faa6) for an example. Or, go one step further and convert the debug statements to tracepoints. For more detail on tracepoint conversion, see the issue in the bug tracker: https://gitlab.com/qemu-project/qemu/-/issues/1827 (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.

Contact persons

For tasks above marked with a "(contact: foo)" point of contact, these are those peoples' names, IRC nicks, and email addresses to get in contact with them.

  • eblake: Eric Blake (mail: eblake AT redhat.com -- IRC: eblake)
  • jsnow: John Snow (mail: jsnow AT redhat.com -- IRC: jsnow)