Skip to content

For Developers: Backports

Jason Gerecke edited this page Sep 21, 2021 · 11 revisions

Backporting commits into input-wacom

The "input-wacom" driver is a backported version of the upstream Wacom kernel drivers which allows users who are running older kernels to benefit from the latest updates. As patches are accepted upstream, it is necessary to ensure they are also added to input-wacom so the codebases stay in sync. This page outlines the steps so that the process can be followed without having to commit it to memory.

Prerequisites

Before beginning, you'll need to be sure your development machine has a copy of git installed and that you have clones of both the Linux kernel repository and our own input-wacom repository. Because development will not typically take place on Linus' upstream repository, additional "remotes" will need to be added that point to active development trees. The two remotes we deal most often with are for the HID subsystem (maintained by Jiri Kosina and Benjamin Tissoires) and the input subsystem (maintained by Dmitry Torokhov).

(kernel.git)~ git remote add hid https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git
(kernel.git)~ git remote add input https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git
(kernel.git)~ git remote update

In addition, to get the full benefit of our automated test suite, it is recommended to create a personal fork of the input-wacom Github repository and add it as a remote. Pushing to your fork gives the automated tests a chance to run and report any problems back.

(input-wacom.git)~ git remote add fork https://github.com/${USERNAME}/input-wacom.git
(input-wacom.git)~ git remote update

The remainder of this document assumes that the remotes "hid", "input", "origin", and "fork" exist as described above. If you choose different names, please substitute them where necessary.

Importing Upstream Commits

Step 1: Navigate to your upstream kernel directory and fetch all upstream updates for the remotes. As git downloads the new commits, it will print out information about new branches and branches which have updates. New code which affects our driver could potentially be contained in any updated branch, but typically updates will only occur in the following branches:

  • hid/for-<release>/wacom (updates to the Wacom driver scheduled for the merge window)
  • hid/for-<release>/upstream-fixes (bugfixes found after the merge window)
  • input/next (updates to input drivers scheduled for the next merge window)
  • input/master (updates to input drivers scheduled for this release)

Additionally, it is a good idea to periodically also check Linus' RC tags to ensure they don't contain any unexpected code.

In the sample below, we fetch updates for all upstream repositories by running git remote update. The output lists a number of branches of interest: "hid/for-4.5/upstream-fixes", "hid/for-4.6/upstream-fixes", and "hid/for-4.6/wacom". Additionally, there are new RCs tagged by Linus that could also be investigated.

(kernel.git)~ git remote update
Fetching origin
remote: Counting objects: 319561, done.
remote: Compressing objects: 100% (76364/76364), done.
remote: Total 319561 (delta 251640), reused 296046 (delta 242417)
Receiving objects: 100% (319561/319561), 144.47 MiB | 2.51 MiB/s, done.
Resolving deltas: 100% (251640/251640), done.
From git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
   b562e44..d3436a1  master     -> origin/master
 * [new tag]         v4.5       -> v4.5
 * [new tag]         v4.5-rc1   -> v4.5-rc1
 * [new tag]         v4.5-rc2   -> v4.5-rc2
 * [new tag]         v4.5-rc3   -> v4.5-rc3
 * [new tag]         v4.5-rc4   -> v4.5-rc4
 * [new tag]         v4.5-rc5   -> v4.5-rc5
 * [new tag]         v4.5-rc6   -> v4.5-rc6
 * [new tag]         v4.5-rc7   -> v4.5-rc7
 * [new tag]         v4.6-rc1   -> v4.6-rc1
 * [new tag]         v4.6-rc2   -> v4.6-rc2
Fetching hid
remote: Counting objects: 149, done.
remote: Compressing objects: 100% (149/149), done.
remote: Total 149 (delta 98), reused 0 (delta 0)
Receiving objects: 100% (149/149), 147.53 KiB | 0 bytes/s, done.
Resolving deltas: 100% (98/98), done.
From git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
 * [new branch]      for-4.5/upstream -> hid/for-4.5/upstream
 * [new branch]      for-4.5/upstream-fixes -> hid/for-4.5/upstream-fixes
 * [new branch]      for-4.6/cmedia -> hid/for-4.6/cmedia
 * [new branch]      for-4.6/i2c-hid -> hid/for-4.6/i2c-hid
 * [new branch]      for-4.6/logitech -> hid/for-4.6/logitech
 * [new branch]      for-4.6/multitouch -> hid/for-4.6/multitouch
 * [new branch]      for-4.6/penmount -> hid/for-4.6/penmount
 * [new branch]      for-4.6/sony -> hid/for-4.6/sony
 * [new branch]      for-4.6/thingm -> hid/for-4.6/thingm
 * [new branch]      for-4.6/upstream -> hid/for-4.6/upstream
 * [new branch]      for-4.6/upstream-fixes -> hid/for-4.6/upstream-fixes
 * [new branch]      for-4.6/wacom -> hid/for-4.6/wacom
   f212bd9..e1c9b9f  for-linus  -> hid/for-linus
   369032a..ab99ccb  for-next   -> hid/for-next
   851328f..d66435c  master     -> hid/master

Step 2: For each branch or tag of interest from step 1, you will need to see if they contain any new commits that have not already been added to the input-wacom repository. The easiest way of doing this is to look at the last commit in each of input-wacom's upstream mirror branches. For example, we might find that the commit message of the last commit to our "hid/for-4.5" branch contains the message [jason.gerecke@wacom.com: Imported into input-wacom repository (0bbfe28)]. This indicates that the branch should contain all commits prior to 0bbfe28 and that anything newer may need to be added.

For each branch that may have new upstream commits (e.g., "hid/for-4.5" and "hid/for-4.6") take note of the commit ID mentioned in the last commit message.

Step 3: With the information gathered in step 2, we can have git export all commits newer than than that commit which affect our driver. To do this, we can run a command similar to the following example. The command should be run for each branch that may have new commits on it, replacing the commit SHA with the SHA from step 2 and the branch name with the branch of interest. The final path argument will depend on the remote -- for the HID subsystem you will want to use "drivers/hid/wacom*", while for the input subsystem use "drivers/input/touchscreen/wacom*".

(kernel.git)~ git format-patch 0bbfe28..hid/for-4.5/upstream -- drivers/hid/wacom*
# No output.

If nothing is printed out, that means that none of the new upstream commits to "hid/for-4.5/upstream" directly affect our driver. In such a case you can run the command again for the next branch of interest. If something is printed out, however, proceed to step 4 to integrate the patches into input-wacom.

(kernel.git)~ git format-patch 0bbfe28..hid/for-4.5/upstream-fixes -- drivers/hid/wacom*
# No output.
(kernel.git)~ git format-patch f620516..hid/for-4.6/wacom -- drivers/hid/wacom*
# No output.
(kernel.git)~ git format-patch f620516..hid/for-4.6/upstream -- drivers/hid/wacom*
# No output.
(kernel.git)~ git format-patch f620516..hid/for-4.6/upstream-fixes -- drivers/hid/wacom*
0001-HID-wacom-fix-Bamboo-ONE-oops.patch
0002-HID-wacom-Initialize-hid_data.inputmode-to-1.patch
0003-HID-wacom-Support-switching-from-vendor-defined-devi.patch

After checking several branches, each with no commits of interest, we see that 3 patches were generated for the "hid/for-4.6/upstream-fixes" branch. We should now proceed to step 4 to integrate these patches into input-wacom.

Step 4: The patch files generated in step 3 will need to be slightly modified before importing them into the input-wacom repository. Firstly, we need to change the path to coincide with the path used by input-wacom:

(kernel.git)~ sed -i 's!drivers/hid/!4.5/!' *.patch

or

(kernel.git)~ sed -i 's!drivers/input/touchscreen!4.5!' *.patch

Secondly, we need to edit the files to add additional metadata that allows us to track who was responsible for the input process. After the last "Signed-off-by" line in the commit comments, add the following. The commit ID should be the first 12 characters of the commit ID upstream -- this can be found on the first line of the patch file.

[<email-address>: Imported into input-wacom repository (<commit-id>)]
Signed-off-by: <name> <email-address>

Step 5: At this point the files are ready and you can attempt to import them into the input-wacom repository. Switch to the appropriate mirror branch (e.g. "for-4.6" for patches destined for the Linux 4.6 release) and then use "git am" to apply them. If an appropriate mirror branch does not yet exist, see "Creating New input-wacom Branches" below.

(input-wacom.git)~ git checkout for-<release>
(input-wacom.git)~ git am ${KERNELDIR}/*.patch

If a merge error occurs during the import process, git will suggest trying to apply the patch manually (e.g. with patch -p1 < .git/rebase-apply/patch). Go ahead and try this, and then resolve any patch errors by looking at the generated ".rej" files. Commit the fixed version, and then continue applying patches by running git am --continue.

Step 6: With all the patches successfully imported, it is now time to test them. Run ./configure && make to verify everything compiles, sudo rmmod wacom && sudo insmod 4.5/wacom.ko to test things out. If any errors are encountered, you'll need to edit the buggy commit with the necessary changes.

Step 7: Once you've completed importing the patches from one upstream branch, you can remove the patch files from the kernel directory and return to step 3 with the next branch of interest. In this particular example, "hid/for-4.6/upstream-fixes" was the last branch of interest so there was no need to return to step 3.

Step 8: Push your changes to your fork:

(input-wacom.git)~ git push fork for-<release>

Next, visit the Actions tab of your fork on Github (https://github.com/${USERNAME}/input-wacom/actions) and watch to make sure the automated tests pass. If they do, you can either create a pull request or (if you have access and are supremely confident) directly push your changes to the "origin" remote.

Step 9: After all the upstream changes have been imported, the next step is to go see if any of them need to be backported to earlier kernel versions (e.g. 3.17, 3.7, etc.). Determining if a particular change needs to be backported will require an understanding of whether the change fixes a bug or adds a feature that is applicable to older kernel versions. Any backported changes should be added to the input-wacom "master" branch rather than one of the upstream mirror branches like "for-4.6".

Creating New input-wacom Branches

A new kernel releases are made you will periodically need to make new mirror branches to house the upstream commits. The general plan is to ensure the previous mirror branch is fully merged into master and then create a new branch off of master with the appropriate name.

(input-wacom.git)~ git checkout master
(input-wacom.git)~ git merge --no-ff for-<lastrelease> -m "Merge for-<lastrelease> into master"
(input-wacom.git)~ git checkout -b for-<release>
(input-wacom.git)~ git push origin for-<release>

Backporting Patches to Earlier Kernels

Backporting requires an understanding of the history of the driver, so it is not as step-by-step as the importing to 4.5 done above.

As of September 2021, input-wacom ships three driver trees: "4.5", "3.17", and "3.7". The most recent tree is kept up-to-date with all upstream patches and is almost line-for-line identical to upstream. The older trees often cannot accept the upstream patches without significant work or require additional device-support patches that aren't necessary for upstream. The multiple trees exist due to a desire to support current Wacom products even on older kernels that are not able to compile the more modern code.

Whereas imports to the newest tree (4.5) are done on the "for-" branches, backports to the older kernels are done on master. To begin, find all of the existing patches on the "for-" branches (see above) which have not been merged into master. Our job will be to determine how, and if, to 'backport' (or replicate these changes) for the older kernels.

The following types of changes will be encountered: new features, new devices, bug fixes, upstream code refactoring, and upstream code cleanup. In general, we only backport new features, new devices and bug fixes which are relevant to the older kernels. Upstream code refactoring and cleanup are considered on a case-by-case basis.

When backporting patches, I generally recommend attempting to follow a process similar to importing if possible. Export the "for-" version of patch, edit its commit summary to include backport: at the beginning, change the file paths (e.g. from 4.5/ to 3.17/), and add backport metadata just below the import metadata (though this time use "Backported from" instead of "Imported into" and use the commit ID of the input-wacom import commit). With some luck, the patch will apply cleanly. You can then repeat the process for the 3.7 branch (though this is unlikely to apply cleanly).

A single upstream commit should result in a single "import" commit to the newest tree, and then a single "backport" commit to all other trees. You may need to squash a 3.17 and 3.7 version of the backport into a single commit after following the advice in the paragraph above.

Some bits of knowledge about backporting

  • Kernel 3.7 does not support Bluetooth devices without modifications to hid-core. We avoid backporting Bluetooth support to this kernel.
  • Kernel 3.7 does not support HID and so must have additional patches that manually add device support.
Clone this wiki locally