Commits

Bryan O'Sullivan committed ecacb6b

Grouping patches in the series file.

Comments (0)

Files changed (1)

 capabilities makes it possible to work in complicated development
 environments.
 
-In this chapter, I will discuss a technique I have developed to manage
-the development of an Infiniband device driver for the Linux kernel.
-The driver in question is large (at least as drivers go), with 25,000
-lines of code spread across 35 source files.  It is maintained by a
-small team of developers.
+In this chapter, I will use as an example a technique I have used to
+manage the development of an Infiniband device driver for the Linux
+kernel.  The driver in question is large (at least as drivers go),
+with 25,000 lines of code spread across 35 source files.  It is
+maintained by a small team of developers.
 
 While much of the material in this chapter is specific to Linux, the
 same principles apply to any code base for which you're not the
   subsystems.
 \item We also maintain a number of ``backports'' to older versions of
   the Linux kernel, to support the needs of customers who are running
-  older Linux distributions that do not incorporate our drivers.
+  older Linux distributions that do not incorporate our drivers.  (To
+  \emph{backport} a piece of code is to modify it to work in an older
+  version of its target environment than the version it was developed
+  for.)
 \item Finally, we make software releases on a schedule that is
   necessarily not aligned with those used by Linux distributors and
   kernel developers, so that we can deliver new features to customers
 case, MQ contains a few added features that make the job more
 pleasant.
 
-\section{Conditionally applying patches with guards}
+\section{Conditionally applying patches with 
+  guards}
 
 Perhaps the best way to maintain sanity with so many targets is to be
 able to choose specific patches to apply for a given situation.  MQ
 \interaction{mq.guards.qselect.qpush}
 
 A guard cannot start with a ``\texttt{+}'' or ``\texttt{-}''
-character.
+character.  The name of a guard must start with an alphabetic
+character (upper or lower case) or an underscore.  The rest of the
+guard's name can contain any of these characters, or a digit.  These
+rules are similar to those used for variable naming in most popular
+programming languages.  If you try to use a guard with an invalid
+name, MQ will complain:
 \interaction{mq.guards.qselect.error}
 Changing the selected guards changes the patches that are applied.
 \interaction{mq.guards.qselect.quux}
-You can see here that negative guards take precedence over positive
-guards.
+You can see in the example below that negative guards take precedence
+over positive guards.
 \interaction{mq.guards.qselect.foobar}
 
+\section{MQ's rules for applying patches}
+
+The rules that MQ uses when deciding whether to apply a patch
+are as follows.
+\begin{itemize}
+\item A patch that has no guards is always applied.
+\item If the patch has any negative guard that matches any currently
+  selected guard, the patch is skipped.
+\item If the patch has any positive guard that matches any currently
+  selected guard, the patch is applied.
+\item If the patch has positive or negative guards, but none matches
+  any currently selected guard, the patch is skipped.
+\end{itemize}
+
+\section{Trimming the work environment}
+
+In working on the device driver I mentioned earlier, I don't apply the
+patches to a normal Linux kernel tree.  Instead, I use a repository
+that contains only a snapshot of the source files and headers that are
+relevant to Infiniband development.  This repository is~1\% the size
+of a kernel repository, so it's easier to work with.
+
+I then choose a ``base'' version on top of which the patches are
+applied.  This is a snapshot of the Linux kernel tree as of a revision
+of my choosing.  When I take the snapshot, I record the changeset ID
+from the kernel repository in the commit message.  Since the snapshot
+preserves the ``shape'' and content of the relevant parts of the
+kernel tree, I can apply my patches on top of either my tiny
+repository or a normal kernel tree.
+
+Normally, the base tree atop which the patches apply should be a
+snapshot of a very recent upstream tree.  This best facilitates the
+development of patches that can easily be submitted upstream with few
+or no modifications.
+
+\section{Dividing up the \sfilename{series} file}
+
+I categorise the patches in the \sfilename{series} file into a number
+of logical groups.  Each section of like patches begins with a block
+of comments that describes the purpose of the patches that follow.
+
+The sequence of patch groups that I maintain follows.  The ordering of
+these groups is important; I'll describe why after I introduce the
+groups.
+\begin{itemize}
+\item The ``accepted'' group.  Patches that the development team has
+  submitted to the maintainer of the Infiniband subsystem, and which
+  he has accepted, but which are not present in the snapshot that the
+  tiny repository is based on.  These are ``read only'' patches,
+  present only to transform the tree into a similar state as it is in
+  the upstream maintainer's repository.
+\item The ``rework'' group.  Patches that I have submitted, but that
+  the upstream maintainer has requested modifications to before he
+  will accept them.
+\item The ``pending'' group.  Patches that I have not yet submitted to
+  the upstream maintainer, but which we have finished working on.
+  These will be ``read only'' for a while.  If the upstream maintainer
+  accepts them upon submission, I'll move them to the end of the
+  ``accepted'' group.  If he requests that I modify any, I'll move
+  them to the beginning of the ``rework'' group.
+\item The ``in progress'' group.  Patches that are actively being
+  developed, and should not be submitted anywhere yet.
+\item The ``backport'' group.  Patches that adapt the source tree to
+  older versions of the kernel tree.
+\item The ``do not ship'' group.  Patches that for some reason should
+  never be submitted upstream.  For example, one such patch might
+  change embedded driver identification strings to make it easier to
+  distinguish, in the field, between an out-of-tree version of the
+  driver and a version shipped by a distribution vendor.
+\end{itemize}
+
+Now to return to the reasons for ordering groups of patches in this
+way.  We would like the lowest patches in the stack to be as stable as
+possible, so that we will not need to rework higher patches due to
+changes in context.  Putting patches that will never be changed first
+in the \sfilename{series} file serves this purpose.
+
+We would also like the patches that we know we'll need to modify to be
+applied on top of a source tree that resembles the upstream tree as
+closely as possible.  This is why we keep accepted patches around for
+a while.
+
+The ``backport'' and ``do not ship'' patches float at the end of the
+\sfilename{series} file in part because they'll never be shipped
+upstream.  Additionally, the backport patches must be applied on top
+of all other patches.
+
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "00book"