Skip to content

pv-runtime: Consolidate capsule-capture-libs calls into fewer, larger batches

Simon McVittie requested to merge wip/smcv/batch-collection into master

Repeatedly launching capsule-capture-libs can be slow, particularly when running pressure-vessel under an emulator like FEX-Emu that needs to instrument each executable launch and therefore has a significant per-process overhead. We can reduce this impact by minimizing the number of separate calls.

This speeds up pressure-vessel container launch by a few percent (approximately 3.2 to 3.0 seconds) when running on x86 with a warm cache; the impact is probably larger under FEX-Emu.

Other things we could do in this direction:

  • if two DRI/VA-API drivers are hard links or symlinks to the same file (Mesa "megadrivers"), only pass one of them to capsule-capture-libs, and make the other one a symlink to the first one

Helps: #81 (closed), #86 (closed)


  • pv-runtime: Refactor bind_icds to take an array of IcdDetails

    Repeatedly launching capsule-capture-libs can be slow, particularly when running pressure-vessel under an emulator like FEX-Emu that needs to instrument each executable launch and therefore has a significant per-process overhead. Taking an array of ICDs will eventually let us amortize the startup cost over several similar ICDs.

    For now, we just pass a trivial array of length 1, exactly equivalent to the previous implementation.

  • pv-runtime: Pass ICDs to bind_icds() an array at a time

    This requires making bind_icds() accept and ignore array entries in which the resolved path is null, for example those that had an error.

  • pv-runtime: Detect successful capture by inspecting target path

    Inspecting the target path instead of counting directory entries will still work after we aggregate the capture-capture-libs operations for multiple libraries into one call to the external program. It might also be a bit quicker.

  • pv-runtime: Put all capsule-capture-libs calls through one code path

    This improves code sharing, and is an enabler for running it fewer times with longer command-lines.

  • pv-runtime: Consolidate all driver SONAMEs into one capture-libs call

    For drivers that are located by their absolute or relative path (which we normalize into an absolute path), bind_icds() has significant complexity to deal with putting the driver in an appropriate subdirectory and the possibility of filename collisions, but for drivers that are located by their SONAME, we don't need that complexity: only one instance of the library per architecture can be the first in search-path order, and we will put that instance first in our search path.

    We can reduce the number of capsule-capture-libs calls by including all such drivers in the "main" capsule-capture-libs invocation, which we were already using to deal with dependencies.

    We can also reduce the number of individual patterns in that "main" invocation by combining drivers with their dependencies: in this case they are both going to end up in the ${libdir} anyway.

  • pv-runtime: Start to split up bind_icds() loop

    We can do a first pass through the drivers to classify them into SONAME, ABSOLUTE or missing, and process the SONAMEs. If there are no ABSOLUTE paths, we can stop here. Otherwise, we only need to create the subdirectory to contain symlinks to ABSOLUTE drivers once, then we can enter a loop that does the rest of the more complicated processing of ABSOLUTE drivers.

  • pv-runtime: Don't redundantly compute basename

  • pv-runtime: Use a separate loop to detect collisions

    This is another step towards batching together all drivers that share a destination directory.

  • pv-runtime: Delay computation of final_path

    We want to split this loop into the parts that happen before and after pv_runtime_capture_libraries(), which makes it harder to carry state across that boundary.

    Previously, we checked whether final_path already existed, but this is in fact unnecessary: we already checked for collisions, and if a collision was found, we'll be using individual destination directories for each driver, which are newly-created and therefore ought to be empty.

  • pv-runtime: Don't compute dependency_pattern until we need it

    We want to split this loop into the parts before and after the pv_runtime_capture_libraries() call, which will make it harder to carry state across that boundary.

  • pv-runtime: Batch together most DRI drivers, etc.

    It's faster to do one large capsule-capture-libs invocation than multiple smaller ones, especially if we're using emulation like FEX-Emu that gives process startup additional overhead.

  • runtime: Treat DRI and VA-API drivers as basically equivalent

    These are normally in the same directory, we handle them equivalently, and there are usually no name collisions, so we can treat them as one big batch rather than two smaller batches.

  • runtime: Remove over-allocation of arrays keyed by multiarch index

    Previously these were the same length as pv_multiarch_tuples, but they don't actually need to be. The only reason pv_multiarch_tuples has an extra element is so we can use it as a NULL-terminated array (like a GStrv), but we don't do that with these arrays, which can be sparse (because an ICD might exist on one architecture but not on another).

Edited by Simon McVittie

Merge request reports