[Intel-gfx] [RFC v2] GuC firmware versioning change

Jeff McGee jeff.mcgee at intel.com
Mon Oct 22 22:54:45 UTC 2018


See https://lists.freedesktop.org/archives/intel-gfx/2018-October/178452.html
for RFC v1 and the helpful feedback incorporated into this v2.

The GuC firmware team is proposing a change to the firmware versioning scheme.
The goal is to more accurately track the firmware interface to help users
manage dependencies on that interface. The proposed scheme is based on
semver.org.

The proposed version number would consist of these 3 mandatory fields in order
of significance: MAJOR.MINOR.PATCH. Contrast this with the 2 fields in the
current version number: MAJOR.MINOR. The version block in the firmware header
will be refactored to contain these 3 fields so that i915 can continue to
verify the version before loading. The firmware file would adopt a change of
naming format to match:

Current:  <platform>_guc_ver<major>_<minor>.bin         (skl_guc_ver9_33.bin)
Proposed: <platform>_guc_ver<major>_<minor>_<patch>.bin (skl_guc_ver5_4_7.bin)

The MAJOR number conforms to the major in semver.org. It increments on a
backwards incompatible change of the interface. The MAJOR number basically
works the same between the current and proposed versioning schemes.

The MINOR number conforms to the minor in semver.org. It increments on a
backwards compatible change of the interface (new interfaces that are optional
to use). It will also increment on substantial new internal functionality that
doesn't affect the interface but should be called out to the user. It resets to
0 on a change of MAJOR. The MINOR number in the current versioning scheme
increments on any backwards compatible change. The proposed versioning scheme
breaks this into the MINOR number just described and the PATCH number below.

The PATCH number conforms to the patch in semver.org. It increments on a
backwards compatible internal change, usually a bug fix. It resets to 0 on a
change of MINOR.

The MAJOR.MINOR collectively define the interface version. Because the MINOR
may also increment on a substantial internal change, it doesn't always mark an
interface change, e.g. 4.5 and 4.6 may have identical interfaces. But the
determination of interface compatibility is unchanged, e.g. 4.6 is always
backwards compatible with 4.5.

Each MAJOR.MINOR may continue to receive internal fixes along a branch even
after the main branch has moved on to another MAJOR.MINOR. Releases from these
fix-only branches increment only the PATCH number on that MAJOR.MINOR, and
therefore remain semantically consistent with the main branch. Consider an
example:

 v1.0.0     v1.0.1     v1.0.2     v1.1.0     v1.1.1
----O----------O----------O----------O----------O    <-- main adopts v1.1.x
                           \
                            \
                             \
                              O----------O     <-- fixes for interface v1.0.x
                           v1.0.3     v1.0.4

The key here is that the branching happened from the last fix (v1.0.2) on the
main branch prior to the change of interface (v1.1.0). As long as only fixes
are applied to v1.0.x, there is no risk of version number clash. All of these
release versions remain semantically connected with one small caveat. If this
set of release versions came sequentially along a single branch, one could infer
that the exact fixes in v1.0.4 were inherited by v1.1.0. With this "hidden"
branching, this may not be true as this example shows. One should always review
the release notes to confirm release ancestry and content.

The above scenario of continued fixes on a given interface version represents
the most common form of release branching expected, and can be handled quite
smoothly within the proposed scheme as shown. But it may also be necessary to
branch from an arbitrary point and with an arbitrary scope of changes. Such a
scenario could not be handled with the basic 3 fields without violating
semver.org semantics. One or more additional version fields will need to be
defined. The GuC firmware team intends to avoid this scenario as long as
possible, though some day a customer or other situation might force it upon us.

For now we will just defer the design for handling the aforementioned scenario,
though I am summarizing some options below to be considered if and when. None
of these are being put into effect immediately as part of the proposed change.

At minimum we will need a 4th field to contain a branch ID. This will be a
numeric ID in the firmware image header, but can be mapped to a descriptive
branch string via a table that is part of the official firmware interface
documentation. If and when the branch ID field is added, it will start with a
value of 1 for that first branch, the mainline being implicitly branch ID 0.
There seems to be two logical choices for how to version the releases coming
from a branch. The best choice depends on the intent of the branch as described
below.

For branches that are short-lived, primarily for fixes, and make only minor or
no changes to the interface, the ability to track their relationship to the
mainline is of utmost importance. Releases along this type of branch always
carry the same major.minor.patch version of the mainline branch-off point. The
branch ID field maps to a string that describes the customer or usage of the
branch. A 5th field is then needed to increment successive releases from the
branch. We accept that by using a single release number we cannot distiguish
the types of changes from release to release. Below is an example for a branch
ID that maps to "projfoo".

 v2.0.0     v2.0.1     v2.0.2     v2.1.0     v2.1.1
----O----------O----------O----------O----------O
                \
                 \
                  \
                   O------------------O
            v2.0.1-projfoo-0   v2.0.1-projfoo-1

For branches that are long-lived and diverge significantly from the mainline,
one might consider them separate forked firmware projects entirely. We don't
care to track them with respect to mainline. We want to restart
major.minor.patch to track significant evolution within the branch/fork. The
branch ID field maps to a string with which we might consider renaming the
firmware project, instead of using the hypen post-fix designation. This kind of
branching should happen extremely rarely if ever. Below is an example for a
branch/fork ID that maps to "newguc".

 v2.0.0     v2.0.1     v2.0.2     v2.1.0     v2.1.1
----O----------O----------O----------O----------O
                \
                 \
                  \
                   O--------------O--------------O--------------O
             newguc v1.0.0  newguc v1.0.1  newguc v1.1.0  newguc v2.0.0

Both of the above approaches could be supported simultaneously by the firmware
where each branch ID would document the model that it follows.

Thanks,
Jeff


More information about the Intel-gfx mailing list