changeset 105:ecacb6b4c9fd

Grouping patches in the series file.
author Bryan O'Sullivan <bos@serpentine.com>
date Sat, 21 Oct 2006 11:05:51 -0700
parents 32bf9a5f22c0
children 9cbc5d0db542
files en/mq-collab.tex
diffstat 1 files changed, 106 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/en/mq-collab.tex	Fri Oct 20 16:56:20 2006 -0700
+++ b/en/mq-collab.tex	Sat Oct 21 11:05:51 2006 -0700
@@ -5,11 +5,11 @@
 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
@@ -33,7 +33,10 @@
   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
@@ -79,7 +82,8 @@
 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
@@ -150,14 +154,106 @@
 \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"