SUSE Linux Enterprise Patch Policy
==================================


Summary
-------

The SUSE Linux Enterprise (SLE) patch policy mirrors the mainline Linux
community's policy for accepting changes. Each commit must contain a small and
"obvious" change that can be reviewed individually and, once applied, be able to
be used as a bisection point. The kernel should be able to build and boot
between each applied patch. Since the SLE kernel is based on an official
upstream kernel release and is followed by a hardening process, we expect that
nearly all of the patches applied to the base release will be from subsequent
official upstream releases intended to address specific issues or to allow for
hardware/feature enablement.


Background
----------

Before covering the policy itself, we'll discuss a bit of background on how the
source code tree is organized. If you've used the SLE kernel source tree
at <https://github.com/SUSE/kernel-source> before, you've probably noticed that,
unlike the mainline Linux kernel, we don't use a source-level Git repository as
our "base". Instead, we use an official kernel.org Linux tar archive as the base
and add a series of patches on top of it. This carries with it several benefits.
The biggest is that we add metadata "tags" to our patches that allow us to
easily associate patches with particular feature requests, bug reports, and/or
the pedigree of the patch. Due to the nature of some of our feature requests, we
must also occasionally carry patches that, for one reason or another, haven't
been accepted into the mainline kernel repository yet. With a full Git
repository, it would be difficult to associate the initial commit for a
particular feature with any subsequent changes to it. Another benefit is more
superficial: with the use of separate patches, we and our users are able to
tell, at a glance, which patches are in any given kernel release simply by
looking at the source package.

This approach works well but has limited options for typical debugging
techniques such as bisection. The application of the patch series results in our
fully operational SLE kernel but stopping the patch series midway can result in
an unbuildable source tree. To help this and similar scenarios, we publish also
a fully expanded Git repository at <https://github.com/SUSE/kernel> which
exactly represents the code as if it were originally used as a standard source
code tree repository. This allows us to work with the individual patches *and*
have the ability to bisect the tree as the changes are applied. It also makes it
easier for partners unfamiliar with how our source tree works to make the
transition.


Format
------

The SLE patch format follows very closely what you would see on any mailing list
associated with Linux kernel development. A SLE patch is formatted like an
RFC822 mbox-style mail message, with a few extensions. If the patch is coming
from the mainline Linux repository or a subsystem maintainer repository, SUSE
has tools that can make adding these tags nearly painless.

Each patch should contain the "From" and "Subject" headers found in any email
message. The From should contain the name and email address of the patch author.
The Subject should contain a short description of the patch, prefixed with the
subsystem affected.

For instance:

    From: Jeff Mahoney <jeffm@suse.com>
    Subject: init: print hello world at boot time

Beyond that, we require several more headers, the full description of the patch,
the certification tags used in the mainline kernel, and the patch contents.

The required headers are as follows:

* Git-commit: [a-f0-9]{40}

  Contains the SHA-1 Git commit ID of the patch in either the mainline kernel
  repository or an official maintainer repository.

* Git-repo: URL-to-git-repo (starting with `git://`)

  The URL to the Git repository containing the commit. This tag can be omitted
  if the commit is from the mainline kernel repository.

* Patch-mainline: vMajor.Minor.Patch{-optional-rc}

  The official kernel release that contains this patch. In the case of a patch
  accepted into a maintainer branch, "Queued in subsystem maintainer repo" can
  be used. If the patch has been submitted to a subsystem mailing list for
  review and is nearly certain to be accepted,
  "Submitted <date> <list@site.org>" can be used. Otherwise, if the patch will
  never be in the upstream kernel, e.g. in the case of vendor-specific version
  numbers, etc., then "No" followed by the reason why it will not be accepted
  (or submitted). Please note that the reason must be compelling for it to be
  allowed into our kernel repository.

* References: list of references

  A specific reason must exist for each patch to be included into the kernel
  repository. It can be a fix in response to a bug report or a patch submitted
  as part of the feature development cycle for a release. We use a shorthand to
  indicate why a particular patch will be included and it's possible to use more
  than one.

  For feature requests, the feature will have to have gone through our feature
  tracking tool, a Jira instance at <https://jira.suse.com/>. Each feature
  request will have an ID associated with it and it can be added to the
  References tag using jsc#id, e.g. jsc#PED-12345.

  For fixes to bug reports or patches for feature requests submitted via
  Bugzilla at <https://bugzilla.suse.com/>, the shorthand is bsc#number. Other
  shorthands referring to different Bugzilla instances are possible too, such as
  bko, for <https://bugzilla.kernel.org/>.

Next is the full description of the patch, which should explain why the patch is
needed and an overview of what it does.

The last "header" portion of the patch contains the certification tags, which
consist of "Signed-off-by" and "Acked-by". We and the upstream Linux community
depend on patch submitters to "own" their submission and certify they have the
right to submit code to the kernel repository. For patches coming from the
mainline Linux kernel repository, the certification tags are already in place
and only the submitter's tag needs to be added, unless one is also already part
of the original patch. Likewise, the SUSE engineer who includes the submission
in our kernel tree will add their own "Acked-by" tag.

The remaining part of the patch is the actual diff with changes. The patch
content should be in the "-ab" format where the patch header itself only
contains the filename without any timestamps. An optional `diffstat -p1` output
may also be included.

Here's an example of a complete patch:

```
From: Upstream Committer <coder@somesite.com>
Subject: init: print hello world on boot
Patch-mainline: v3.8-rc1
Git-commit: deadbeefc0ffeeb1a4b1a4b1a4b1a4b1a4b1a4b1a4
References: jsc#PED-12134 bsc#23123

The kernel started off like every other project. Let's add the hello
world message in honor of its roots.

Signed-off-by: Upstream Committer <coder@somesite.com>
Tested-by: Bill User <bill.user@example.com>
Acked-by: Jeff Mahoney <jeffm@suse.com>
---
 init/main.c |    1 +
 1 file changed, 1 insertion(+)

--- a/init/main.c
+++ b/init/main.c
@@ -807,6 +807,7 @@ static noinline int init_post(void)
        system_state = SYSTEM_RUNNING;
        numa_default_policy();
 
+       printk("Hello world!\n");
 
        current->signal->flags |= SIGNAL_UNKILLABLE;
 
```


Patch inclusion rules
---------------------

As mentioned in the summary, we expect that most patches to the SLE kernel will
come from subsequent official upstream kernel releases, or from subsystem
maintainer repositories where the patch is on its way to become a part of an
official upstream Linux release. The SLE kernel contains hardware enablement
driver enhancement/backports for a wide range of devices offered by many
vendors. In many cases, the drivers are self-contained but many others have
shared dependencies on common infrastructure.

The shared dependencies on common infrastructure combined with the need to be
able to bisect the resulting kernel means that we must require all partners to
submit patch series consisting of individual patches that match upstream
commits. In the case where a commit affects multiple drivers, it is acceptable
to only include the portions that affect a particular driver as long as it is
annotated by appending "(partial)" to the Git-commit line and documenting what
is included or dropped. An example using the patch tools is included below.


Tools
-----

We understand that there are a bunch of rules to follow and that implementing
them all can be tedious. SUSE has a set of tools to make working with the
patches a lot easier. They are called patchtools and published at
<https://download.opensuse.org/repositories/Kernel:/tools/>.

Two important tools are included: fixpatch and exportpatch. Fixpatch adds
missing headers and formatting to existing patches, assuming there's at least a
Git-commit tag present. Exportpatch, given a list of commit IDs on the command
line, searches for each commit in the configured repositories and exports the
patches.

Exportpatch has a number of options, the following list shows the most useful
ones:

* `-w` | `--write`

  Write out each commit into a separate file. The filenames are based on the
  subject of the header and they get output on stdout for use directly in a
  series file.

* `-d DIR` | `--dir=DIR`

  Write out each commit into a designated directory. The default is to write
  into the current directory.

* `-F REF` | `--reference=REFERENCE`

  Add a References tag to the patch output using the specified reference, can be
  repeated multiple times.

* `-x EXTRACT` | `--extract=EXTRACT`

  It it sometimes desirable to split out chunks of patches that affect only a
  particular section of the code. This option accepts pathnames to extract.
  Anything not specified will be skipped. Paths ending with `/` designate
  everything under that hierarchy. This also adds the "(partial)" notation to
  the Git-commit tag and adds a Patch-filtered tag indicating which paths were
  used to extract.

Refer to the exportpatch(1) manual page for more details and a complete list of
all options.

One useful feature of exportpatch is that 3-way merge diffs are handled
automatically such that a new, exact 2-way diff is generated. Note that both the
`-x` option and the automatic handling of merge commits can generate empty
patches. Such patches are skipped entirely and no files are generated.

As a quick example, the following invocation would generate patches necessary
for a backport of the ixgbe driver from v3.2 against the v3.0 kernel:

    $ exportpatch -w -d ixgbe \
        -x drivers/net/ixgbe/ -x drivers/net/ethernet/intel/ixgbe/ \
        -F "jsc#PED-12345" -F "bsc#12354" \
        $(git log v3.0..v3.2 --pretty=oneline -- \
            drivers/net/ixgbe drivers/net/ethernet/intel/ixgbe | \
          cut -b 1-40) \
        > ixgbe/series

The tool automatically adds an Acked-by tag to the created patches unless you
were involved in the original upstream commit process. Be aware that the
produced result (obviously) doesn't include any infrastructure changes that
might be needed for the patches to build.

The first patch in the series looks like this:

```
From 6403eab143205a45a5493166ff8bf7e3646f4a77 Mon Sep 17 00:00:00 2001
From: Joe Perches <joe@perches.com>
Date: Fri, 3 Jun 2011 11:51:20 +0000
Subject: drivers/net: Remove unnecessary semicolons
Git-commit: 6403eab143205a45a5493166ff8bf7e3646f4a77 (partial)
Patch-mainline: v3.1-rc1
References: jsc#PED-12345 bsc#12354
Patch-filtered: drivers/net/ixgbe/ drivers/net/ethernet/intel/ixgbe/

Semicolons are not necessary after switch/while/for/if braces
so remove them.

Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Jeff Mahoney <jeffm@suse.com>
---

 drivers/net/ixgbe/ixgbe_82599.c  |    4 ++--
 drivers/net/ixgbe/ixgbe_common.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -1157,7 +1157,7 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc)
 	default:
 		/* bad value */
 		return IXGBE_ERR_CONFIG;
-	};
+	}
 
 	/* Move the flexible bytes to use the ethertype - shift 6 words */
 	fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT);
@@ -1245,7 +1245,7 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc)
 	default:
 		/* bad value */
 		return IXGBE_ERR_CONFIG;
-	};
+	}
 
 	/* Turn perfect match filtering on */
 	fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH;

--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1292,7 +1292,7 @@ static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
 
 		udelay(5);
 		ixgbe_standby_eeprom(hw);
-	};
+	}
 
 	/*
 	 * On some parts, SPI write time could vary from 0-20mSec on 3.3V
@@ -1374,7 +1374,7 @@ static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
 		 * EEPROM
 		 */
 		mask = mask >> 1;
-	};
+	}
 
 	/* We leave the "DI" bit set to "0" when we leave this routine. */
 	eec &= ~IXGBE_EEC_DI;

```
