\documentclass[aspectratio=169,obeyspaces,spaces,hyphens,dvipsnames]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}% http://ctan.org/pkg/lm
\usepackage{minted}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage[normalem]{ulem}
\usepackage{textcomp}
\usepackage{media9}

\mode<presentation>
\usetheme{Bootlin}

\def\signed #1{{\leavevmode\unskip\nobreak\hfil\penalty50\hskip2em
  \hbox{}\nobreak\hfil(#1)
  \parfillskip=0pt \finalhyphendemerits=0 \endgraf}}

\newsavebox\mybox
\newenvironment{aquote}[1]
  {\savebox\mybox{#1}\begin{quotation}}
  {\signed{\usebox\mybox}\end{quotation}}

\title{MTD: What's new?}
\conference{Embedded Linux Conference Europe, October 2019}
\authors{Miquèl Raynal \hfill Richard Weinberger}
\email{miquel@bootlin.com \hfill richard@sigma-star.at}
\institute{Bootlin \hfill sigma star gmbh}
\slidesurl{https://bootlin.com/pub/conferences/2019/elce/raynal-weinberger-mtd-what-s-new}

\begin{document}

\addtocontents{toc}{\protect\setcounter{tocdepth}{-1}}
\section{Memory Technology Devices: what's new?}
\addtocontents{toc}{\protect\setcounter{tocdepth}{2}}

\newcommand\added{\item[$+$]}
\newcommand\removed{\item[$-$]}
\newcommand\surviving{\item[$\bullet$]}

\begin{frame}{What exactly are we talking about?}
  \begin{center}
    \includegraphics[scale=0.13]{mtd-stack.pdf}
  \end{center}
\end{frame}

\begin{frame}{Administration}
  \begin{itemize}
  \item Lot's of changes in the maintainers team
    \begin{columns}
      \column{0.5\textwidth}
      \begin{itemize}
        \removed Adrian (UBIFS)
        \removed Artem (UBI/UBIFS)
        \removed Boris (MTD/NAND)
        \removed Brian (MTD)
        \removed Cyrille (SPI-NOR)
        \removed David (MTD)
        \removed Marek (MTD)
      \end{itemize}
      \column{0.5\textwidth}
      \begin{itemize}
        \surviving Richard (MTD/NAND/UBI/UBIFS/JFFS2), aka the pillar
        \added Frieder (MTD)
        \added Miquèl (MTD/NAND)
        \added Tudor (SPI-NOR)
        \added Vignesh (MTD/HyperBus)
      \end{itemize}
    \end{columns}
  \end{itemize}
\end{frame}

\begin{frame}{Where is the latest code?}
  \begin{itemize}
  \item Migration to a kernel.org repository:\\
    \sout{\code{https://git.infradead.org/linux-mtd.git}}\\
    \code{https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git}\\
    \begin{itemize}
    \item mtd/fixes (all fixes)
    \item mtd/next (MTD + parallel NORs + HyperBus)
    \item nand/next (all NAND flavors)
    \item spi-nor/next (SPI-NORs only)
    \end{itemize}
    \vfill
  \item UBI/UBIFS development is now also on kernel.org:\\
    \code{https://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs.git}\\
  \end{itemize}
\end{frame}

\subsection{MTD layer}

\begin{frame}{Panic write flag}
  \begin{itemize}
  \item MTD supports panic write since ever
  \item Useful to dump kernel crashes to flash
  \item During panic we must not do complex stuff
  \item Before v5.3 drivers had no way to detect panic write
  \item Now drivers can check the new \code{oops_panic_write} flag
  \end{itemize}
\end{frame}

\subsection{Flash type layers}

\begin{frame}{NAND: Keep it tidy!}
  \begin{columns}
    \column{0.6\textwidth}
    \begin{itemize}
    \item \code{mv items/ where-they-belong/}
      \begin{itemize}
      \item Creation of a \code{raw/} subdirectory
      \item Onenand drivers moved into the \code{nand/} subdirectory
      \item Code reorganization:
        \begin{itemize}
        \item Timings
        \item ONFI
        \item JEDEC
        \item ...
        \end{itemize}
      \end{itemize}
    \end{itemize}
    \column{0.4\textwidth}
    \begin{center}
      \includegraphics[scale=0.35]{dishes-in-sink-meme.jpg}
    \end{center}
  \end{columns}
\end{frame}

\begin{frame}{NAND: Generic NAND layer}
  \begin{itemize}
  \item Common to all flavors of NAND chips
  \item Abstracts the type of bus (ops)
  \item Describes the memory organization
    \begin{itemize}
      \begin{columns}
        \column{0.1\textwidth}
        \column{0.25\textwidth}
      \item targets
      \item luns
        \column{0.25\textwidth}
      \item planes
      \item eraseblocks
        \column{0.25\textwidth}
      \item pages
      \item ...
      \end{columns}
    \end{itemize}
    \vfill
  \item Shape the I/O requests
    \begin{itemize}
      \begin{columns}
        \column{0.1\textwidth}
        \column{0.25\textwidth}
      \item in-band data offset
      \item in-band data length
        \column{0.25\textwidth}
      \item out-of-band data offset
      \item out-of-band data length
        \column{0.25\textwidth}
      \item buffers
      \item ...
      \end{columns}
      \end{itemize}
    \vfill
  \item Share Bad Block Table handling and Bad Blocks logic
    \begin{itemize}
      \begin{columns}
        \column{0.1\textwidth}
        \column{0.25\textwidth}
      \item init
      \item cleanup
        \column{0.25\textwidth}
      \item read
      \item update
        \column{0.25\textwidth}
      \end{columns}
      \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Raw NAND: Jumbo cleanup 1/2}
  \begin{itemize}
  \item Make a distinction between the controller and the flash chip
  \end{itemize}
  \vfill
  \begin{columns}
    \column{0.7\textwidth}
    \begin{center}
      \includegraphics[scale=0.35]{rawnand-interface.pdf}
    \end{center}
    \column{0.3\textwidth}
  \end{columns}
\end{frame}

\begin{frame}[fragile]{Raw NAND: Jumbo cleanup 2/2}
  \begin{itemize}
  \item Deprecation of several hooks, creation of a legacy structure
    \begin{block}{}
\begin{verbatim}
drivers/mtd/nand/raw/nand_base.c   | 618 +-------------------------
drivers/mtd/nand/raw/nand_legacy.c | 642 ++++++++++++++++++++++++++++
\end{verbatim}
    \end{block}
  \item No more MTD objects in the NAND world
    \begin{block}{}
\begin{verbatim}
- * @mtd: MTD device structure
+ * @chip: NAND chip object
[...]
-static int nand_block_markbad_lowlevel(struct mtd_info *mtd, ...)
+static int nand_block_markbad_lowlevel(struct nand_chip *chip, ...)
 {
-       struct nand_chip *chip = mtd_to_nand(mtd);
+       struct mtd_info *mtd = nand_to_mtd(chip);
\end{verbatim}
    \end{block}
  \end{itemize}
\end{frame}

\begin{frame}{Raw NAND: {\bf\code{->exec_op()}}: origins}
  \begin{center}
    \includegraphics[scale=0.4]{rawnand-protocol-before.pdf}
  \end{center}
  \vfill
  \begin{columns}
    \column{0.5\textwidth}
    \begin{itemize}
    \item Controllers can usually handle more complex/higher-level
      operations (sometimes they cannot even send a single cycle)
    \item The API is incomplete
    \end{itemize}
    \column{0.5\textwidth}
    \begin{itemize}
    \item Workaround for driver developers: overload
      \code{->cmdfunc()}\\ $\rightarrow$ re-implementing everything?
      \begin{itemize}
      \item Hard to maintain
      \item Incomplete implementations
      \end{itemize}
    \end{itemize}
  \end{columns}
\end{frame}

\begin{frame}{Raw NAND: {\bf\code{->exec_op()}}: one hook to rule
      them all}
  \begin{columns}
    \column{0.5\textwidth}
    \begin{itemize}
    \item Asks to execute the whole operation
    \item Just a translation in NAND operations of the MTD layer orders
    \item An array of instructions is passed
    \end{itemize}
    \column{0.5\textwidth}
    \begin{itemize}
    \item The controller's implementation will parse the sequence, split
      it in as many sub-operations as needed/supported and execute
    \end{itemize}
  \end{columns}
  \vfill
  \begin{center}
    \includegraphics[scale=0.4]{rawnand-protocol-execop.pdf}
  \end{center}
\end{frame}

\begin{frame}{Raw NAND: A journey supporting Micron's hardware}
  \begin{itemize}
  \item a.k.a: why we tend not to believe hardware manufacturers?
  \end{itemize}
  \vfill
  \begin{center}
    \includegraphics[scale=0.2]{satirical-content.jpg}
  \end{center}
\end{frame}

\begin{frame}{Raw NAND: A journey supporting Micron's hardware 1/3}
  \begin{itemize}
  \item [Plot] What is the on-die ECC engine capability of a Micron
    NAND chip, between: unsupported, supported and mandatory?
    \onslide<2->
  \item [Solution] Discover these information statically: build an
    ID $\leftrightarrow$ capabilities table.
    \onslide<3->
  \item [Issue 1] It seems that Micron produces many chips with the
    same ID and blow internal fuses to prevent the advertisement and the
    use of on-die ECC on outgoing products depending if their on-die ECC
    tests passed or not. So only the ID, as-is, is unusable.
    \onslide<4->
  \item [Fix 1] Discover these information dynamically: enable the
    engine with \code{->set_features()} then read back the ECC engine
    status with \code{->get_features()}. With this information we know
    if the engine is supported. Disable it with
    \code{->set_features()}. If \code{->get_features()} report the
    engine is still on, on-die ECC is mandatory.
  \end{itemize}
\end{frame}

\begin{frame}{Raw NAND: A journey supporting Micron's hardware 2/3}
  \begin{itemize}
  \item [Issue 2] On certain chips where on-die ECC is supposedly
    mandatory, \code{->get_features()} returns that it is disabled.
    \onslide<2->
  \item [Fix 2] Use the \code{ECC_STATUS} bit of the 5th ID byte
    as discriminant, our observations shows that it is dynamically
    changed and it reflects what \code{->get_features()} fails to
    retrieve.
    \onslide<3->
  \item [Issue 3] Has explained above, a chip without on-die ECC does
    not mean there is no ECC engine on it, it means it is at least
    unavailable. But, there are buggy chips where enabling the engine
    with a \code{->set_feature()} will work despite the fact that the
    engine is not supposed to be available and will probably not work
    reliably!
    \onslide<4->
  \item [Fix 3] Let's check {\bf first} the \code{ECC_STATUS} bit, and
    activate the engine only if the default state reflects an available
    engine. The engine will still be activated and deactivated if it
    appears to be present and usable, in order to know if it is
    mandatory.
  \end{itemize}
\end{frame}

\begin{frame}{Raw NAND: A journey supporting Micron's hardware 3/3}
  \begin{itemize}
  \item [Issue 4] We found chips that do not update the
    \code{ECC_STATUS} bit when the engine is enabled.
    \onslide<2->
  \item [Fix 4] Micron advises to rely on \code{->get_features()}. Oh,
    wait...
    \begin{center}
      \includegraphics[scale=0.25]{baby-confused.jpg}
    \end{center}
  \item Back to endless part number tables. Maybe they did mess that
    too?
  \end{itemize}
\end{frame}

\begin{frame}{Raw NAND: Supporting more and more hardware}
  \begin{itemize}
  \item Raw NANDs should have died by now
  \item New controllers (or IP flavors):
    \begin{itemize}
    \item MTK, Tegra, STM32 FMC2, Amlogic, Brcmnand, Macronix
    \end{itemize}
  \item Cleaned, updated, migrated to use the new hooks:
    \begin{itemize}
    \item Marvell, OMAP2, Sunxi, GPMI, Qualcomm, Denali, VF610, FSMC, Ams-Delta
    \end{itemize}
  \end{itemize}
  \vfill
  \begin{columns}
    \column{0.3\textwidth}
    \begin{center}
      \includegraphics[scale=0.5]{crystal-ball.jpg}
    \end{center}
    \column{0.7\textwidth}
    \begin{itemize}
    \item Not dead enough from my perspective :)
    \item What does my crystal ball says? % SPI memories \o/
    \end{itemize}
  \end{columns}
\end{frame}

\begin{frame}{SPI memories}
  \begin{itemize}
  \item SPI controllers are memory agnostic
  \item Introduction of the \code{spi-mem} layer
  \item Standardizes how to communicate with a device
  \end{itemize}
  \vfill
  \includegraphics[scale=0.3]{spi-mem-protocol.pdf}
  \vfill
  \begin{itemize}
  \item Command set is device specific (2 known at this time)
  \item Supports direct-mapping!
  \item Generic SPI controller drivers can implement the
    \code{spi_mem_ops} interface
  \end{itemize}
\end{frame}

\begin{frame}{SPI-NAND}
  \begin{itemize}
  \item Introduction of a real SPI-NAND framework, built on top of
    \code{spi-mem}
  \item Similarly to \code{->exec_op()}, translates the upper layer
    I/O requests into SPI cycles thanks to the \code{spi-mem} abstraction
    layer
    \vfill
  \item Very active field, could replace raw memories in the near future
    due to the parallelization of data sampling (dual-spi, quad-spi,
    octo-spi) abstracted by the \code{spi-mem} layer.
  \item Plenty of new chips already supported, keeps increasing!
    \begin{itemize}
    \item Winbond, Gigadevices, Toshiba, Micron, Macronix, Paragon
    \end{itemize}
    \vfill
  \item Staging \code{mt29f_spinand} driver removed
  \end{itemize}
\end{frame}

\begin{frame}{SPI-NOR: Fit the {\bf\code{spi-mem}} layer}
  \begin{itemize}
  \item Much older than the SPI-NAND framework
    \vfill
  \begin{columns}
    \column{0.11\textwidth}
    \column{0.5\textwidth}
    \item Re-worked to fit the \code{spi-mem} approach
      \begin{itemize}
      \item Temporary use of the m28p80 driver as intermediate layer
        between SPI-NOR and \code{spi-mem}
      \item Structural changes to move generic code to the SPI-NOR
        (\code{spi-nor.c}) layer
      \item Get rid of manufacturer specific code in the generic bits
      \end{itemize}
      \column{0.5\textwidth}
      \begin{center}
    \includegraphics[scale=0.12]{spi-mem-stack.pdf}
      \end{center}
  \end{columns}
  \vfill
  \item Goal is to get rid of the SPI-NOR controller drivers entirely
  \end{itemize}
\end{frame}

\begin{frame}{SPI-NOR: Improvements}
  \begin{itemize}
  \item DMA'able buffers mandatory now (assumed by the \code{spi-mem}
    layer)
    \vfill
  \item Lock/unlock logic reworked
    \vfill
  \item Notable new features:
    \begin{itemize}
    \item System power management support
    \item Non-uniform erase size
    \item JEDEC SFDP 4-byte Address Instruction Table parser
    \item \code{->default_init()} and \code{->post_sfdp()} hooks to
      tweak the flash parameters
    \item Octal mode
    \item ...
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{HyperBus framework}
  \begin{itemize}
  \item 29/10/2019 @ Lyon: Vignesh talk about HyperBus support in Linux
    \vfill
  \item Physically similar to Octo-SPI
  \item Double data rate
  \item Part of xSPI standard JEDEC 251 (standardizes all SPI-NOR
    flashes)
  \item Different protocol than what traditional SPI NOR chips use
    \vfill
  \item HyperFlash
    \begin{itemize}
    \item NOR based memory with HyberBus interface
    \item Follows CFI Parallel NOR command set\\
      \code{drivers/mtd/chips/cfi_cmdset_0002.c}
    \item Command set encapsulated by the HyperBus protocol
    \end{itemize}
  \end{itemize}
\end{frame}

\subsection{Wear leveling and file-system layers}

\begin{frame}{UBI: Dealing with read disturb}
  \begin{itemize}
     \item Reading the same page over and over can corrupt nearby pages
     \item Big issue on MLC NAND but also possible on SLC NAND
     \item Problem: Seldom read pages might corrupt faster than you can fix them
   \end{itemize}
\end{frame}

\begin{frame}{UBI: Dealing with read disturb}
  \begin{itemize}
     \item Old solution: Read whole NAND once in a while
     \item \ldots reading on what layer?
     \item UBI does wear leveling for us, so we need to read at UBI level
     \item Once a week: \code{dd if=/dev/ubiX_Y of=/dev/null}
     \item Done?
   \end{itemize}
\end{frame}

\begin{frame}{UBI: Dealing with read disturb}
  \begin{itemize}
    \item Problem 1: Hurts performance
    \item Problem 2: Will only catch pages with UBI user data, no meta data
    \item Solution for problem 2: Reboot also once in a while
    \item Upon UBI attach UBI reads all meta data and can detect errors
  \end{itemize}
\end{frame}

\begin{frame}{UBI: Dealing with read disturb}
  \begin{itemize}
    \item Fastmap makes things interesting, as always
    \item At attach time most meta data is not read
    \item UBI meta data can bitrot and corrupt badly
  \end{itemize}
\end{frame}

\begin{frame}{UBI: Bitrot interface}
  \begin{itemize}
   \item Simple UBI ioctl interface to userspace
   \item Allows userspace to initiate checks
   \item PEBs can be in many different state, userspace has to restart checks
   \item Simple but handy userspace daemon: ubihealthd
  \end{itemize}
\end{frame}

\begin{frame}{UBI: ubihealthd}
  \begin{itemize}
   \item Part of mtd-utils package
   \item Stateless, no config file, no state file needed
   \item Shuffles list of PEBs and checks every block one by one
   \item One PEB per 120 seconds, default value
  \end{itemize}
\end{frame}

\begin{frame}{UBIFS: fstests}
  \begin{itemize}
   \item fstests (former xfstests) can now test UBIFS
   \item Useful for regression testing
   \item Some tests can fail, e.g. atime tests
  \end{itemize}
\end{frame}

\begin{frame}{UBIFS: Authentication}
  \begin{itemize}
   \item Beside of encryption you also want your data authenticated
   \item UBIFS authentication can be combined with encryption
   \item UBIFS encryption via fscrypt covers only user data
   \item UBIFS authentication covers user and meta data
   \item e.g. switching inodes of \code{/bin/login} and \code{/bin/true} will be detected
  \end{itemize}
\end{frame}

\begin{frame}{UBIFS: Bug fixes}
  \begin{itemize}
   \item xattrs saw major rework
   \item \code{O_TMPFILE} needed multiple fixes, sadly
  \end{itemize}
\end{frame}

\begin{frame}{What next?}
  \begin{columns}
    \column{0.6\textwidth}
    \begin{itemize}
    \item Definitely coming
      \begin{itemize}
      \item NAND
        \begin{itemize}
        \item External ECC engines
        \item MLC support (in pseudo SLC mode)
        \end{itemize}
      \item HyperBus
        \begin{itemize}
        \item HyperRAM support
        \item Use of spi-mem layer
        \end{itemize}
      \end{itemize}
      \vfill
    \item Keep on dreaming
      \begin{itemize}
      \item ONFI for SPI-NANDs? Maybe, maybe not
      \item DMA-able buffers everywhere in MTD\\ (implies new I/O requests
        structures)
      \item An MTD I/O scheduler, parallelized access
        \begin{itemize}
        \item Running upstream Linux in SSDs?
        \end{itemize}
      \end{itemize}
    \end{itemize}
    \column{0.5\textwidth}
    \begin{center}
      \includegraphics[scale=0.30]{plan.jpg}
      % Screenshot of a scene of the Joker movie
    \end{center}
  \end{columns}
\end{frame}

\begin{frame}
  \centering
  \Huge
  Questions? Suggestions? Comments?\\
  \vspace{0.5cm}
  \huge
  Miquèl Raynal \& Richard Weinberger\\
  \large
  \vspace{0.5cm}
  \hspace{2.6cm}\code{miquel@bootlin.com} and \code{richard@sigma-star.at}
  \vspace{0.5cm}
  \newline Slides under CC-BY-SA 3.0\\
  \scriptsize
  \url{https://bootlin.com/pub/conferences/2019/elce/raynal-weinberger-what-s-new}
\end{frame}

\end{document}
