Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1668294 > unrolled thread
| Started by | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| First post | 2017-06-17 17:40 +0200 |
| Last post | 2017-06-17 17:50 +0200 |
| Articles | 20 on this page of 21 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v2 01/29] IPMI.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 15/29] lzo.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 20/29] men-chameleon-bus.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 05/29] IRQ.txt: add a markup for its title Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 09/29] kobject.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 25/29] padata.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 22/29] nommu-mmap.txt: don't use all upper case on titles Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 18/29] memory-barriers.txt: use literals for variables Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 29/29] pi-futex.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 11/29] kref.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 02/29] IRQ-affinity.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 19/29] memory-hotplug.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 21/29] nommu-mmap.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 27/29] percpu-rw-semaphore.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 28/29] phy.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 23/29] ntb.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 24/29] numastat.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 03/29] IRQ-domain.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 12/29] kselftest.rst: do some adjustments after ReST conversion Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:40 +0200
[PATCH v2 14/29] lockup-watchdogs.txt: standardize document format Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2017-06-17 17:50 +0200
Re: [PATCH v2 01/29] IPMI.txt: standardize document format Corey Minyard <minyard@acm.org> - 2017-06-17 17:50 +0200
Page 1 of 2 [1] 2 Next page →
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 01/29] IPMI.txt: standardize document format |
| Message-ID | <tTnPH-y3-13@gated-at.bofh.it> |
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- fix document type;
- add missing markups for subitems;
- mark literal blocks;
- add whitespaces and blank lines where needed;
- use bulleted list markups where neded.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/IPMI.txt | 76 +++++++++++++++++++++++++++++---------------------
1 file changed, 44 insertions(+), 32 deletions(-)
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index 6962cab997ef..aa77a25a0940 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -1,9 +1,8 @@
+=====================
+The Linux IPMI Driver
+=====================
- The Linux IPMI Driver
- ---------------------
- Corey Minyard
- <minyard@mvista.com>
- <minyard@acm.org>
+:Author: Corey Minyard <minyard@mvista.com> / <minyard@acm.org>
The Intelligent Platform Management Interface, or IPMI, is a
standard for controlling intelligent devices that monitor a system.
@@ -141,7 +140,7 @@ Addressing
----------
The IPMI addressing works much like IP addresses, you have an overlay
-to handle the different address types. The overlay is:
+to handle the different address types. The overlay is::
struct ipmi_addr
{
@@ -153,7 +152,7 @@ to handle the different address types. The overlay is:
The addr_type determines what the address really is. The driver
currently understands two different types of addresses.
-"System Interface" addresses are defined as:
+"System Interface" addresses are defined as::
struct ipmi_system_interface_addr
{
@@ -166,7 +165,7 @@ straight to the BMC on the current card. The channel must be
IPMI_BMC_CHANNEL.
Messages that are destined to go out on the IPMB bus use the
-IPMI_IPMB_ADDR_TYPE address type. The format is
+IPMI_IPMB_ADDR_TYPE address type. The format is::
struct ipmi_ipmb_addr
{
@@ -184,16 +183,16 @@ spec.
Messages
--------
-Messages are defined as:
+Messages are defined as::
-struct ipmi_msg
-{
+ struct ipmi_msg
+ {
unsigned char netfn;
unsigned char lun;
unsigned char cmd;
unsigned char *data;
int data_len;
-};
+ };
The driver takes care of adding/stripping the header information. The
data portion is just the data to be send (do NOT put addressing info
@@ -208,7 +207,7 @@ block of data, even when receiving messages. Otherwise the driver
will have no place to put the message.
Messages coming up from the message handler in kernelland will come in
-as:
+as::
struct ipmi_recv_msg
{
@@ -246,6 +245,7 @@ and the user should not have to care what type of SMI is below them.
Watching For Interfaces
+^^^^^^^^^^^^^^^^^^^^^^^
When your code comes up, the IPMI driver may or may not have detected
if IPMI devices exist. So you might have to defer your setup until
@@ -256,6 +256,7 @@ and tell you when they come and go.
Creating the User
+^^^^^^^^^^^^^^^^^
To use the message handler, you must first create a user using
ipmi_create_user. The interface number specifies which SMI you want
@@ -272,6 +273,7 @@ closing the device automatically destroys the user.
Messaging
+^^^^^^^^^
To send a message from kernel-land, the ipmi_request_settime() call does
pretty much all message handling. Most of the parameter are
@@ -321,6 +323,7 @@ though, since it is tricky to manage your own buffers.
Events and Incoming Commands
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The driver takes care of polling for IPMI events and receiving
commands (commands are messages that are not responses, they are
@@ -367,7 +370,7 @@ in the system. It discovers interfaces through a host of different
methods, depending on the system.
You can specify up to four interfaces on the module load line and
-control some module parameters:
+control some module parameters::
modprobe ipmi_si.o type=<type1>,<type2>....
ports=<port1>,<port2>... addrs=<addr1>,<addr2>...
@@ -437,7 +440,7 @@ default is one. Setting to 0 is useful with the hotmod, but is
obviously only useful for modules.
When compiled into the kernel, the parameters can be specified on the
-kernel command line as:
+kernel command line as::
ipmi_si.type=<type1>,<type2>...
ipmi_si.ports=<port1>,<port2>... ipmi_si.addrs=<addr1>,<addr2>...
@@ -474,16 +477,22 @@ The driver supports a hot add and remove of interfaces. This way,
interfaces can be added or removed after the kernel is up and running.
This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a
write-only parameter. You write a string to this interface. The string
-has the format:
+has the format::
+
<op1>[:op2[:op3...]]
-The "op"s are:
+
+The "op"s are::
+
add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
-You can specify more than one interface on the line. The "opt"s are:
+
+You can specify more than one interface on the line. The "opt"s are::
+
rsp=<regspacing>
rsi=<regsize>
rsh=<regshift>
irq=<irq>
ipmb=<ipmb slave addr>
+
and these have the same meanings as discussed above. Note that you
can also use this on the kernel command line for a more compact format
for specifying an interface. Note that when removing an interface,
@@ -496,7 +505,7 @@ The SMBus Driver (SSIF)
The SMBus driver allows up to 4 SMBus devices to be configured in the
system. By default, the driver will only register with something it
finds in DMI or ACPI tables. You can change this
-at module load time (for a module) with:
+at module load time (for a module) with::
modprobe ipmi_ssif.o
addr=<i2caddr1>[,<i2caddr2>[,...]]
@@ -535,7 +544,7 @@ the smb_addr parameter unless you have DMI or ACPI data to tell the
driver what to use.
When compiled into the kernel, the addresses can be specified on the
-kernel command line as:
+kernel command line as::
ipmb_ssif.addr=<i2caddr1>[,<i2caddr2>[...]]
ipmi_ssif.adapter=<adapter1>[,<adapter2>[...]]
@@ -565,9 +574,9 @@ Some users need more detailed information about a device, like where
the address came from or the raw base device for the IPMI interface.
You can use the IPMI smi_watcher to catch the IPMI interfaces as they
come or go, and to grab the information, you can use the function
-ipmi_get_smi_info(), which returns the following structure:
+ipmi_get_smi_info(), which returns the following structure::
-struct ipmi_smi_info {
+ struct ipmi_smi_info {
enum ipmi_addr_src addr_src;
struct device *dev;
union {
@@ -575,7 +584,7 @@ struct ipmi_smi_info {
void *acpi_handle;
} acpi_info;
} addr_info;
-};
+ };
Currently special info for only for SI_ACPI address sources is
returned. Others may be added as necessary.
@@ -590,7 +599,7 @@ Watchdog
A watchdog timer is provided that implements the Linux-standard
watchdog timer interface. It has three module parameters that can be
-used to control it:
+used to control it::
modprobe ipmi_watchdog timeout=<t> pretimeout=<t> action=<action type>
preaction=<preaction type> preop=<preop type> start_now=x
@@ -635,7 +644,7 @@ watchdog device is closed. The default value of nowayout is true
if the CONFIG_WATCHDOG_NOWAYOUT option is enabled, or false if not.
When compiled into the kernel, the kernel command line is available
-for configuring the watchdog:
+for configuring the watchdog::
ipmi_watchdog.timeout=<t> ipmi_watchdog.pretimeout=<t>
ipmi_watchdog.action=<action type>
@@ -675,6 +684,7 @@ also get a bunch of OEM events holding the panic string.
The field settings of the events are:
+
* Generator ID: 0x21 (kernel)
* EvM Rev: 0x03 (this event is formatting in IPMI 1.0 format)
* Sensor Type: 0x20 (OS critical stop sensor)
@@ -683,18 +693,20 @@ The field settings of the events are:
* Event Data 1: 0xa1 (Runtime stop in OEM bytes 2 and 3)
* Event data 2: second byte of panic string
* Event data 3: third byte of panic string
+
See the IPMI spec for the details of the event layout. This event is
always sent to the local management controller. It will handle routing
the message to the right place
Other OEM events have the following format:
-Record ID (bytes 0-1): Set by the SEL.
-Record type (byte 2): 0xf0 (OEM non-timestamped)
-byte 3: The slave address of the card saving the panic
-byte 4: A sequence number (starting at zero)
-The rest of the bytes (11 bytes) are the panic string. If the panic string
-is longer than 11 bytes, multiple messages will be sent with increasing
-sequence numbers.
+
+* Record ID (bytes 0-1): Set by the SEL.
+* Record type (byte 2): 0xf0 (OEM non-timestamped)
+* byte 3: The slave address of the card saving the panic
+* byte 4: A sequence number (starting at zero)
+ The rest of the bytes (11 bytes) are the panic string. If the panic string
+ is longer than 11 bytes, multiple messages will be sent with increasing
+ sequence numbers.
Because you cannot send OEM events using the standard interface, this
function will attempt to find an SEL and add the events there. It
--
2.9.4
[toc] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 15/29] lzo.txt: standardize document format |
| Message-ID | <tTnZo-Cs-19@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- Add markups for section titles;
- mark literal blocks;
- use ".. important::" for an important note.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/lzo.txt | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/Documentation/lzo.txt b/Documentation/lzo.txt
index 285c54f66779..6fa6a93d0949 100644
--- a/Documentation/lzo.txt
+++ b/Documentation/lzo.txt
@@ -1,8 +1,9 @@
-
+===========================================================
LZO stream format as understood by Linux's LZO decompressor
===========================================================
Introduction
+============
This is not a specification. No specification seems to be publicly available
for the LZO stream format. This document describes what input format the LZO
@@ -14,12 +15,13 @@ Introduction
for future bug reports.
Description
+===========
The stream is composed of a series of instructions, operands, and data. The
instructions consist in a few bits representing an opcode, and bits forming
the operands for the instruction, whose size and position depend on the
opcode and on the number of literals copied by previous instruction. The
- operands are used to indicate :
+ operands are used to indicate:
- a distance when copying data from the dictionary (past output buffer)
- a length (number of bytes to copy from dictionary)
@@ -38,7 +40,7 @@ Description
of bits in the operand. If the number of bits isn't enough to represent the
length, up to 255 may be added in increments by consuming more bytes with a
rate of at most 255 per extra byte (thus the compression ratio cannot exceed
- around 255:1). The variable length encoding using #bits is always the same :
+ around 255:1). The variable length encoding using #bits is always the same::
length = byte & ((1 << #bits) - 1)
if (!length) {
@@ -67,15 +69,19 @@ Description
instruction may encode this distance (0001HLLL), it takes one LE16 operand
for the distance, thus requiring 3 bytes.
- IMPORTANT NOTE : in the code some length checks are missing because certain
- instructions are called under the assumption that a certain number of bytes
- follow because it has already been guaranteed before parsing the instructions.
- They just have to "refill" this credit if they consume extra bytes. This is
- an implementation design choice independent on the algorithm or encoding.
+ .. important::
+
+ In the code some length checks are missing because certain instructions
+ are called under the assumption that a certain number of bytes follow
+ because it has already been guaranteed before parsing the instructions.
+ They just have to "refill" this credit if they consume extra bytes. This
+ is an implementation design choice independent on the algorithm or
+ encoding.
Byte sequences
+==============
- First byte encoding :
+ First byte encoding::
0..17 : follow regular instruction encoding, see below. It is worth
noting that codes 16 and 17 will represent a block copy from
@@ -91,7 +97,7 @@ Byte sequences
state = 4 [ don't copy extra literals ]
skip byte
- Instruction encoding :
+ Instruction encoding::
0 0 0 0 X X X X (0..15)
Depends on the number of literals copied by the last instruction.
@@ -156,6 +162,7 @@ Byte sequences
distance = (H << 3) + D + 1
Authors
+=======
This document was written by Willy Tarreau <w@1wt.eu> on 2014/07/19 during an
analysis of the decompression code available in Linux 3.16-rc5. The code is
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 20/29] men-chameleon-bus.txt: standardize document format |
| Message-ID | <tTnZo-Cs-23@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- Adjust identations;
- Remove title numbering;
- mark literal blocks;
- comment its TOC.
Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/men-chameleon-bus.txt | 298 +++++++++++++++++++-----------------
1 file changed, 155 insertions(+), 143 deletions(-)
diff --git a/Documentation/men-chameleon-bus.txt b/Documentation/men-chameleon-bus.txt
index 30ded732027e..1b1f048aa748 100644
--- a/Documentation/men-chameleon-bus.txt
+++ b/Documentation/men-chameleon-bus.txt
@@ -1,163 +1,175 @@
- MEN Chameleon Bus
- =================
-
-Table of Contents
=================
-1 Introduction
- 1.1 Scope of this Document
- 1.2 Limitations of the current implementation
-2 Architecture
- 2.1 MEN Chameleon Bus
- 2.2 Carrier Devices
- 2.3 Parser
-3 Resource handling
- 3.1 Memory Resources
- 3.2 IRQs
-4 Writing an MCB driver
- 4.1 The driver structure
- 4.2 Probing and attaching
- 4.3 Initializing the driver
-
+MEN Chameleon Bus
+=================
-1 Introduction
-===============
- This document describes the architecture and implementation of the MEN
- Chameleon Bus (called MCB throughout this document).
+.. Table of Contents
+ =================
+ 1 Introduction
+ 1.1 Scope of this Document
+ 1.2 Limitations of the current implementation
+ 2 Architecture
+ 2.1 MEN Chameleon Bus
+ 2.2 Carrier Devices
+ 2.3 Parser
+ 3 Resource handling
+ 3.1 Memory Resources
+ 3.2 IRQs
+ 4 Writing an MCB driver
+ 4.1 The driver structure
+ 4.2 Probing and attaching
+ 4.3 Initializing the driver
-1.1 Scope of this Document
----------------------------
- This document is intended to be a short overview of the current
- implementation and does by no means describe the complete possibilities of MCB
- based devices.
-1.2 Limitations of the current implementation
-----------------------------------------------
- The current implementation is limited to PCI and PCIe based carrier devices
- that only use a single memory resource and share the PCI legacy IRQ. Not
- implemented are:
- - Multi-resource MCB devices like the VME Controller or M-Module carrier.
- - MCB devices that need another MCB device, like SRAM for a DMA Controller's
- buffer descriptors or a video controller's video memory.
- - A per-carrier IRQ domain for carrier devices that have one (or more) IRQs
- per MCB device like PCIe based carriers with MSI or MSI-X support.
+Introduction
+============
-2 Architecture
-===============
- MCB is divided into 3 functional blocks:
- - The MEN Chameleon Bus itself,
- - drivers for MCB Carrier Devices and
- - the parser for the Chameleon table.
+This document describes the architecture and implementation of the MEN
+Chameleon Bus (called MCB throughout this document).
-2.1 MEN Chameleon Bus
+Scope of this Document
----------------------
- The MEN Chameleon Bus is an artificial bus system that attaches to a so
- called Chameleon FPGA device found on some hardware produced my MEN Mikro
- Elektronik GmbH. These devices are multi-function devices implemented in a
- single FPGA and usually attached via some sort of PCI or PCIe link. Each
- FPGA contains a header section describing the content of the FPGA. The
- header lists the device id, PCI BAR, offset from the beginning of the PCI
- BAR, size in the FPGA, interrupt number and some other properties currently
- not handled by the MCB implementation.
-
-2.2 Carrier Devices
+
+This document is intended to be a short overview of the current
+implementation and does by no means describe the complete possibilities of MCB
+based devices.
+
+Limitations of the current implementation
+-----------------------------------------
+
+The current implementation is limited to PCI and PCIe based carrier devices
+that only use a single memory resource and share the PCI legacy IRQ. Not
+implemented are:
+
+- Multi-resource MCB devices like the VME Controller or M-Module carrier.
+- MCB devices that need another MCB device, like SRAM for a DMA Controller's
+ buffer descriptors or a video controller's video memory.
+- A per-carrier IRQ domain for carrier devices that have one (or more) IRQs
+ per MCB device like PCIe based carriers with MSI or MSI-X support.
+
+Architecture
+============
+
+MCB is divided into 3 functional blocks:
+
+- The MEN Chameleon Bus itself,
+- drivers for MCB Carrier Devices and
+- the parser for the Chameleon table.
+
+MEN Chameleon Bus
+-----------------
+
+The MEN Chameleon Bus is an artificial bus system that attaches to a so
+called Chameleon FPGA device found on some hardware produced my MEN Mikro
+Elektronik GmbH. These devices are multi-function devices implemented in a
+single FPGA and usually attached via some sort of PCI or PCIe link. Each
+FPGA contains a header section describing the content of the FPGA. The
+header lists the device id, PCI BAR, offset from the beginning of the PCI
+BAR, size in the FPGA, interrupt number and some other properties currently
+not handled by the MCB implementation.
+
+Carrier Devices
+---------------
+
+A carrier device is just an abstraction for the real world physical bus the
+Chameleon FPGA is attached to. Some IP Core drivers may need to interact with
+properties of the carrier device (like querying the IRQ number of a PCI
+device). To provide abstraction from the real hardware bus, an MCB carrier
+device provides callback methods to translate the driver's MCB function calls
+to hardware related function calls. For example a carrier device may
+implement the get_irq() method which can be translated into a hardware bus
+query for the IRQ number the device should use.
+
+Parser
+------
+
+The parser reads the first 512 bytes of a Chameleon device and parses the
+Chameleon table. Currently the parser only supports the Chameleon v2 variant
+of the Chameleon table but can easily be adopted to support an older or
+possible future variant. While parsing the table's entries new MCB devices
+are allocated and their resources are assigned according to the resource
+assignment in the Chameleon table. After resource assignment is finished, the
+MCB devices are registered at the MCB and thus at the driver core of the
+Linux kernel.
+
+Resource handling
+=================
+
+The current implementation assigns exactly one memory and one IRQ resource
+per MCB device. But this is likely going to change in the future.
+
+Memory Resources
+----------------
+
+Each MCB device has exactly one memory resource, which can be requested from
+the MCB bus. This memory resource is the physical address of the MCB device
+inside the carrier and is intended to be passed to ioremap() and friends. It
+is already requested from the kernel by calling request_mem_region().
+
+IRQs
+----
+
+Each MCB device has exactly one IRQ resource, which can be requested from the
+MCB bus. If a carrier device driver implements the ->get_irq() callback
+method, the IRQ number assigned by the carrier device will be returned,
+otherwise the IRQ number inside the Chameleon table will be returned. This
+number is suitable to be passed to request_irq().
+
+Writing an MCB driver
+=====================
+
+The driver structure
--------------------
- A carrier device is just an abstraction for the real world physical bus the
- Chameleon FPGA is attached to. Some IP Core drivers may need to interact with
- properties of the carrier device (like querying the IRQ number of a PCI
- device). To provide abstraction from the real hardware bus, an MCB carrier
- device provides callback methods to translate the driver's MCB function calls
- to hardware related function calls. For example a carrier device may
- implement the get_irq() method which can be translated into a hardware bus
- query for the IRQ number the device should use.
-2.3 Parser
------------
- The parser reads the first 512 bytes of a Chameleon device and parses the
- Chameleon table. Currently the parser only supports the Chameleon v2 variant
- of the Chameleon table but can easily be adopted to support an older or
- possible future variant. While parsing the table's entries new MCB devices
- are allocated and their resources are assigned according to the resource
- assignment in the Chameleon table. After resource assignment is finished, the
- MCB devices are registered at the MCB and thus at the driver core of the
- Linux kernel.
+Each MCB driver has a structure to identify the device driver as well as
+device ids which identify the IP Core inside the FPGA. The driver structure
+also contains callback methods which get executed on driver probe and
+removal from the system::
-3 Resource handling
-====================
- The current implementation assigns exactly one memory and one IRQ resource
- per MCB device. But this is likely going to change in the future.
+ static const struct mcb_device_id foo_ids[] = {
+ { .device = 0x123 },
+ { }
+ };
+ MODULE_DEVICE_TABLE(mcb, foo_ids);
-3.1 Memory Resources
+ static struct mcb_driver foo_driver = {
+ driver = {
+ .name = "foo-bar",
+ .owner = THIS_MODULE,
+ },
+ .probe = foo_probe,
+ .remove = foo_remove,
+ .id_table = foo_ids,
+ };
+
+Probing and attaching
---------------------
- Each MCB device has exactly one memory resource, which can be requested from
- the MCB bus. This memory resource is the physical address of the MCB device
- inside the carrier and is intended to be passed to ioremap() and friends. It
- is already requested from the kernel by calling request_mem_region().
-3.2 IRQs
----------
- Each MCB device has exactly one IRQ resource, which can be requested from the
- MCB bus. If a carrier device driver implements the ->get_irq() callback
- method, the IRQ number assigned by the carrier device will be returned,
- otherwise the IRQ number inside the Chameleon table will be returned. This
- number is suitable to be passed to request_irq().
+When a driver is loaded and the MCB devices it services are found, the MCB
+core will call the driver's probe callback method. When the driver is removed
+from the system, the MCB core will call the driver's remove callback method::
-4 Writing an MCB driver
-=======================
+ static init foo_probe(struct mcb_device *mdev, const struct mcb_device_id *id);
+ static void foo_remove(struct mcb_device *mdev);
-4.1 The driver structure
--------------------------
- Each MCB driver has a structure to identify the device driver as well as
- device ids which identify the IP Core inside the FPGA. The driver structure
- also contains callback methods which get executed on driver probe and
- removal from the system.
+Initializing the driver
+-----------------------
+When the kernel is booted or your foo driver module is inserted, you have to
+perform driver initialization. Usually it is enough to register your driver
+module at the MCB core::
- static const struct mcb_device_id foo_ids[] = {
- { .device = 0x123 },
- { }
- };
- MODULE_DEVICE_TABLE(mcb, foo_ids);
+ static int __init foo_init(void)
+ {
+ return mcb_register_driver(&foo_driver);
+ }
+ module_init(foo_init);
- static struct mcb_driver foo_driver = {
- driver = {
- .name = "foo-bar",
- .owner = THIS_MODULE,
- },
- .probe = foo_probe,
- .remove = foo_remove,
- .id_table = foo_ids,
- };
+ static void __exit foo_exit(void)
+ {
+ mcb_unregister_driver(&foo_driver);
+ }
+ module_exit(foo_exit);
-4.2 Probing and attaching
---------------------------
- When a driver is loaded and the MCB devices it services are found, the MCB
- core will call the driver's probe callback method. When the driver is removed
- from the system, the MCB core will call the driver's remove callback method.
+The module_mcb_driver() macro can be used to reduce the above code::
-
- static init foo_probe(struct mcb_device *mdev, const struct mcb_device_id *id);
- static void foo_remove(struct mcb_device *mdev);
-
-4.3 Initializing the driver
-----------------------------
- When the kernel is booted or your foo driver module is inserted, you have to
- perform driver initialization. Usually it is enough to register your driver
- module at the MCB core.
-
-
- static int __init foo_init(void)
- {
- return mcb_register_driver(&foo_driver);
- }
- module_init(foo_init);
-
- static void __exit foo_exit(void)
- {
- mcb_unregister_driver(&foo_driver);
- }
- module_exit(foo_exit);
-
- The module_mcb_driver() macro can be used to reduce the above code.
-
-
- module_mcb_driver(foo_driver);
+ module_mcb_driver(foo_driver);
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 05/29] IRQ.txt: add a markup for its title |
| Message-ID | <tTnZo-Cs-27@gated-at.bofh.it> |
| In reply to | #1668294 |
This simple document only needs a markup for its title to be using the standard we're adopting for text documents. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> --- Documentation/IRQ.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/IRQ.txt b/Documentation/IRQ.txt index 1011e7175021..4273806a606b 100644 --- a/Documentation/IRQ.txt +++ b/Documentation/IRQ.txt @@ -1,4 +1,6 @@ +=============== What is an IRQ? +=============== An IRQ is an interrupt request from a device. Currently they can come in over a pin, or over a packet. -- 2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 09/29] kobject.txt: standardize document format |
| Message-ID | <tTnZo-Cs-39@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- Add markups for titles;
- mark literal blocks as such;
- add needed whitespace/blank lines;
- use :Author: and :Last updated: for authorship.
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/kobject.txt | 69 ++++++++++++++++++++++++++++-------------------
1 file changed, 42 insertions(+), 27 deletions(-)
diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt
index 1be59a3a521c..fc9485d79061 100644
--- a/Documentation/kobject.txt
+++ b/Documentation/kobject.txt
@@ -1,13 +1,13 @@
+=====================================================================
Everything you never wanted to know about kobjects, ksets, and ktypes
+=====================================================================
-Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+:Author: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+:Last updated: December 19, 2007
Based on an original article by Jon Corbet for lwn.net written October 1,
2003 and located at http://lwn.net/Articles/51437/
-Last updated December 19, 2007
-
-
Part of the difficulty in understanding the driver model - and the kobject
abstraction upon which it is built - is that there is no obvious starting
place. Dealing with kobjects requires understanding a few different types,
@@ -47,6 +47,7 @@ approach will be taken, so we'll go back to kobjects.
Embedding kobjects
+==================
It is rare for kernel code to create a standalone kobject, with one major
exception explained below. Instead, kobjects are used to control access to
@@ -65,7 +66,7 @@ their own, but are invariably found embedded in the larger objects of
interest.)
So, for example, the UIO code in drivers/uio/uio.c has a structure that
-defines the memory region associated with a uio device:
+defines the memory region associated with a uio device::
struct uio_map {
struct kobject kobj;
@@ -77,7 +78,7 @@ just a matter of using the kobj member. Code that works with kobjects will
often have the opposite problem, however: given a struct kobject pointer,
what is the pointer to the containing structure? You must avoid tricks
(such as assuming that the kobject is at the beginning of the structure)
-and, instead, use the container_of() macro, found in <linux/kernel.h>:
+and, instead, use the container_of() macro, found in <linux/kernel.h>::
container_of(pointer, type, member)
@@ -90,13 +91,13 @@ where:
The return value from container_of() is a pointer to the corresponding
container type. So, for example, a pointer "kp" to a struct kobject
embedded *within* a struct uio_map could be converted to a pointer to the
-*containing* uio_map structure with:
+*containing* uio_map structure with::
struct uio_map *u_map = container_of(kp, struct uio_map, kobj);
For convenience, programmers often define a simple macro for "back-casting"
kobject pointers to the containing type. Exactly this happens in the
-earlier drivers/uio/uio.c, as you can see here:
+earlier drivers/uio/uio.c, as you can see here::
struct uio_map {
struct kobject kobj;
@@ -106,23 +107,25 @@ earlier drivers/uio/uio.c, as you can see here:
#define to_map(map) container_of(map, struct uio_map, kobj)
where the macro argument "map" is a pointer to the struct kobject in
-question. That macro is subsequently invoked with:
+question. That macro is subsequently invoked with::
struct uio_map *map = to_map(kobj);
Initialization of kobjects
+==========================
Code which creates a kobject must, of course, initialize that object. Some
-of the internal fields are setup with a (mandatory) call to kobject_init():
+of the internal fields are setup with a (mandatory) call to kobject_init()::
void kobject_init(struct kobject *kobj, struct kobj_type *ktype);
The ktype is required for a kobject to be created properly, as every kobject
must have an associated kobj_type. After calling kobject_init(), to
-register the kobject with sysfs, the function kobject_add() must be called:
+register the kobject with sysfs, the function kobject_add() must be called::
- int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...);
+ int kobject_add(struct kobject *kobj, struct kobject *parent,
+ const char *fmt, ...);
This sets up the parent of the kobject and the name for the kobject
properly. If the kobject is to be associated with a specific kset,
@@ -133,7 +136,7 @@ kset itself.
As the name of the kobject is set when it is added to the kernel, the name
of the kobject should never be manipulated directly. If you must change
-the name of the kobject, call kobject_rename():
+the name of the kobject, call kobject_rename()::
int kobject_rename(struct kobject *kobj, const char *new_name);
@@ -146,12 +149,12 @@ is being removed. If your code needs to call this function, it is
incorrect and needs to be fixed.
To properly access the name of the kobject, use the function
-kobject_name():
+kobject_name()::
const char *kobject_name(const struct kobject * kobj);
There is a helper function to both initialize and add the kobject to the
-kernel at the same time, called surprisingly enough kobject_init_and_add():
+kernel at the same time, called surprisingly enough kobject_init_and_add()::
int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
struct kobject *parent, const char *fmt, ...);
@@ -161,10 +164,11 @@ kobject_add() functions described above.
Uevents
+=======
After a kobject has been registered with the kobject core, you need to
announce to the world that it has been created. This can be done with a
-call to kobject_uevent():
+call to kobject_uevent()::
int kobject_uevent(struct kobject *kobj, enum kobject_action action);
@@ -180,11 +184,12 @@ hand.
Reference counts
+================
One of the key functions of a kobject is to serve as a reference counter
for the object in which it is embedded. As long as references to the object
exist, the object (and the code which supports it) must continue to exist.
-The low-level functions for manipulating a kobject's reference counts are:
+The low-level functions for manipulating a kobject's reference counts are::
struct kobject *kobject_get(struct kobject *kobj);
void kobject_put(struct kobject *kobj);
@@ -209,21 +214,24 @@ file Documentation/kref.txt in the Linux kernel source tree.
Creating "simple" kobjects
+==========================
Sometimes all that a developer wants is a way to create a simple directory
in the sysfs hierarchy, and not have to mess with the whole complication of
ksets, show and store functions, and other details. This is the one
exception where a single kobject should be created. To create such an
-entry, use the function:
+entry, use the function::
struct kobject *kobject_create_and_add(char *name, struct kobject *parent);
This function will create a kobject and place it in sysfs in the location
underneath the specified parent kobject. To create simple attributes
-associated with this kobject, use:
+associated with this kobject, use::
int sysfs_create_file(struct kobject *kobj, struct attribute *attr);
-or
+
+or::
+
int sysfs_create_group(struct kobject *kobj, struct attribute_group *grp);
Both types of attributes used here, with a kobject that has been created
@@ -236,6 +244,7 @@ implementation of a simple kobject and attributes.
ktypes and release methods
+==========================
One important thing still missing from the discussion is what happens to a
kobject when its reference count reaches zero. The code which created the
@@ -257,7 +266,7 @@ is good practice to always use kobject_put() after kobject_init() to avoid
errors creeping in.
This notification is done through a kobject's release() method. Usually
-such a method has a form like:
+such a method has a form like::
void my_object_release(struct kobject *kobj)
{
@@ -281,7 +290,7 @@ leak in the kobject core, which makes people unhappy.
Interestingly, the release() method is not stored in the kobject itself;
instead, it is associated with the ktype. So let us introduce struct
-kobj_type:
+kobj_type::
struct kobj_type {
void (*release)(struct kobject *kobj);
@@ -306,6 +315,7 @@ automatically created for any kobject that is registered with this ktype.
ksets
+=====
A kset is merely a collection of kobjects that want to be associated with
each other. There is no restriction that they be of the same ktype, but be
@@ -335,13 +345,16 @@ kobject) in their parent.
As a kset contains a kobject within it, it should always be dynamically
created and never declared statically or on the stack. To create a new
-kset use:
+kset use::
+
struct kset *kset_create_and_add(const char *name,
struct kset_uevent_ops *u,
struct kobject *parent);
-When you are finished with the kset, call:
+When you are finished with the kset, call::
+
void kset_unregister(struct kset *kset);
+
to destroy it. This removes the kset from sysfs and decrements its reference
count. When the reference count goes to zero, the kset will be released.
Because other references to the kset may still exist, the release may happen
@@ -351,14 +364,14 @@ An example of using a kset can be seen in the
samples/kobject/kset-example.c file in the kernel tree.
If a kset wishes to control the uevent operations of the kobjects
-associated with it, it can use the struct kset_uevent_ops to handle it:
+associated with it, it can use the struct kset_uevent_ops to handle it::
-struct kset_uevent_ops {
+ struct kset_uevent_ops {
int (*filter)(struct kset *kset, struct kobject *kobj);
const char *(*name)(struct kset *kset, struct kobject *kobj);
int (*uevent)(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env);
-};
+ };
The filter function allows a kset to prevent a uevent from being emitted to
@@ -386,6 +399,7 @@ added below the parent kobject.
Kobject removal
+===============
After a kobject has been registered with the kobject core successfully, it
must be cleaned up when the code is finished with it. To do that, call
@@ -409,6 +423,7 @@ called, and the objects in the former circle release each other.
Example code to copy from
+=========================
For a more complete example of using ksets and kobjects properly, see the
example programs samples/kobject/{kobject-example.c,kset-example.c},
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 25/29] padata.txt: standardize document format |
| Message-ID | <tTnZo-Cs-35@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- mark document title;
- mark literal blocks.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/padata.txt | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/Documentation/padata.txt b/Documentation/padata.txt
index 7ddfe216a0aa..b103d0c82000 100644
--- a/Documentation/padata.txt
+++ b/Documentation/padata.txt
@@ -1,5 +1,8 @@
+=======================================
The padata parallel execution mechanism
-Last updated for 2.6.36
+=======================================
+
+:Last updated: for 2.6.36
Padata is a mechanism by which the kernel can farm work out to be done in
parallel on multiple CPUs while retaining the ordering of tasks. It was
@@ -9,7 +12,7 @@ those packets. The crypto developers made a point of writing padata in a
sufficiently general fashion that it could be put to other uses as well.
The first step in using padata is to set up a padata_instance structure for
-overall control of how tasks are to be run:
+overall control of how tasks are to be run::
#include <linux/padata.h>
@@ -24,7 +27,7 @@ The workqueue wq is where the work will actually be done; it should be
a multithreaded queue, naturally.
To allocate a padata instance with the cpu_possible_mask for both
-cpumasks this helper function can be used:
+cpumasks this helper function can be used::
struct padata_instance *padata_alloc_possible(struct workqueue_struct *wq);
@@ -36,7 +39,7 @@ it is legal to supply a cpumask to padata that contains offline CPUs.
Once an offline CPU in the user supplied cpumask comes online, padata
is going to use it.
-There are functions for enabling and disabling the instance:
+There are functions for enabling and disabling the instance::
int padata_start(struct padata_instance *pinst);
void padata_stop(struct padata_instance *pinst);
@@ -48,7 +51,7 @@ padata cpumask contains no active CPU (flag not set).
padata_stop clears the flag and blocks until the padata instance
is unused.
-The list of CPUs to be used can be adjusted with these functions:
+The list of CPUs to be used can be adjusted with these functions::
int padata_set_cpumasks(struct padata_instance *pinst,
cpumask_var_t pcpumask,
@@ -71,12 +74,12 @@ padata_add_cpu/padata_remove_cpu are used. cpu specifies the CPU to add or
remove and mask is one of PADATA_CPU_SERIAL, PADATA_CPU_PARALLEL.
If a user is interested in padata cpumask changes, he can register to
-the padata cpumask change notifier:
+the padata cpumask change notifier::
int padata_register_cpumask_notifier(struct padata_instance *pinst,
struct notifier_block *nblock);
-To unregister from that notifier:
+To unregister from that notifier::
int padata_unregister_cpumask_notifier(struct padata_instance *pinst,
struct notifier_block *nblock);
@@ -84,7 +87,7 @@ To unregister from that notifier:
The padata cpumask change notifier notifies about changes of the usable
cpumasks, i.e. the subset of active CPUs in the user supplied cpumask.
-Padata calls the notifier chain with:
+Padata calls the notifier chain with::
blocking_notifier_call_chain(&pinst->cpumask_change_notifier,
notification_mask,
@@ -95,7 +98,7 @@ is one of PADATA_CPU_SERIAL, PADATA_CPU_PARALLEL and cpumask is a pointer
to a struct padata_cpumask that contains the new cpumask information.
Actually submitting work to the padata instance requires the creation of a
-padata_priv structure:
+padata_priv structure::
struct padata_priv {
/* Other stuff here... */
@@ -110,7 +113,7 @@ parallel() and serial() functions should be provided. Those functions will
be called in the process of getting the work done as we will see
momentarily.
-The submission of work is done with:
+The submission of work is done with::
int padata_do_parallel(struct padata_instance *pinst,
struct padata_priv *padata, int cb_cpu);
@@ -138,7 +141,7 @@ need not be completed during this call, but, if parallel() leaves work
outstanding, it should be prepared to be called again with a new job before
the previous one completes. When a task does complete, parallel() (or
whatever function actually finishes the job) should inform padata of the
-fact with a call to:
+fact with a call to::
void padata_do_serial(struct padata_priv *padata);
@@ -151,7 +154,7 @@ pains to ensure that tasks are completed in the order in which they were
submitted.
The one remaining function in the padata API should be called to clean up
-when a padata instance is no longer needed:
+when a padata instance is no longer needed::
void padata_free(struct padata_instance *pinst);
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 22/29] nommu-mmap.txt: don't use all upper case on titles |
| Message-ID | <tTnZp-Cs-45@gated-at.bofh.it> |
| In reply to | #1668294 |
This file is almost in the standard format we're adopting for
other documentation text files. Yet, it use upper case on
titles.
So, in order to uniform how chapter names, adjust caps on
titles.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/nommu-mmap.txt | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/Documentation/nommu-mmap.txt b/Documentation/nommu-mmap.txt
index 39a62ab0f50a..69556f0d494b 100644
--- a/Documentation/nommu-mmap.txt
+++ b/Documentation/nommu-mmap.txt
@@ -1,5 +1,5 @@
=============================
-NO-MMU MEMORY MAPPING SUPPORT
+No-MMU memory mapping support
=============================
The kernel has limited support for memory mapping under no-MMU conditions, such
@@ -105,7 +105,7 @@ and it's also much more restricted in the latter case:
provide any such support, then the mapping request will be denied.
-FURTHER NOTES ON NO-MMU MMAP
+Further notes on no-MMU MMAP
============================
(#) A request for a private mapping of a file may return a buffer that is not
@@ -160,7 +160,7 @@ FURTHER NOTES ON NO-MMU MMAP
with character device files, pipes, fifos and sockets.
-INTERPROCESS SHARED MEMORY
+Interprocess shared memory
==========================
Both SYSV IPC SHM shared memory and POSIX shared memory is supported in NOMMU
@@ -168,7 +168,7 @@ mode. The former through the usual mechanism, the latter through files created
on ramfs or tmpfs mounts.
-FUTEXES
+Futexes
=======
Futexes are supported in NOMMU mode if the arch supports them. An error will
@@ -177,7 +177,7 @@ mappings made by a process or if the mapping in which the address lies does not
support futexes (such as an I/O chardev mapping).
-NO-MMU MREMAP
+No-MMU mremap
=============
The mremap() function is partially supported. It may change the size of a
@@ -199,7 +199,7 @@ act on a complete mapping.
.. [#] Not currently supported.
-PROVIDING SHAREABLE CHARACTER DEVICE SUPPORT
+Providing shareable character device support
============================================
To provide shareable character device support, a driver must provide a
@@ -244,7 +244,7 @@ copy mapped otherwise.
circumstances!
-PROVIDING SHAREABLE MEMORY-BACKED FILE SUPPORT
+Providing shareable memory-backed file support
==============================================
Provision of shared mappings on memory backed files is similar to the provision
@@ -261,7 +261,7 @@ Memory backed devices are indicated by the mapping's backing device info having
the memory_backed flag set.
-PROVIDING SHAREABLE BLOCK DEVICE SUPPORT
+Providing shareable block device support
========================================
Provision of shared mappings on block device files is exactly the same as for
@@ -269,7 +269,7 @@ character devices. If there isn't a real device underneath, then the driver
should allocate sufficient contiguous memory to honour any supported mapping.
-ADJUSTING PAGE TRIMMING BEHAVIOUR
+Adjusting page trimming behaviour
=================================
NOMMU mmap automatically rounds up to the nearest power-of-2 number of pages
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 18/29] memory-barriers.txt: use literals for variables |
| Message-ID | <tTnZo-Cs-41@gated-at.bofh.it> |
| In reply to | #1668294 |
From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
The minimal adjustments on this file were not enough
to make it build clean with Sphinx:
Documentation/memory-barriers.rst:192: WARNING: Inline emphasis start-string without end-string.
Documentation/memory-barriers.rst:603: WARNING: Inline emphasis start-string without end-string.
Documentation/memory-barriers.rst:1065: WARNING: Inline emphasis start-string without end-string.
Documentation/memory-barriers.rst:1068: WARNING: Inline emphasis start-string without end-string.
Documentation/memory-barriers.rst:2289: WARNING: Inline emphasis start-string without end-string.
Documentation/memory-barriers.rst:2289: WARNING: Inline emphasis start-string without end-string.
Documentation/memory-barriers.rst:3091: WARNING: Inline emphasis start-string without end-string.
What happens there is that, while some vars are inside
'var' or `var`, most of them aren't, and some start with
asterisk.
Standardize it by always use ``literal``. As a bonus,
the output will use the same monospaced fonts as the
literal blocks.
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/memory-barriers.txt | 154 +++++++++++++++++++-------------------
1 file changed, 77 insertions(+), 77 deletions(-)
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 69cc3e770e8d..f1642d927957 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -181,16 +181,16 @@ As a further example, consider this sequence of events::
B = 4; Q = P;
P = &B D = *Q;
-There is an obvious data dependency here, as the value loaded into D depends on
-the address retrieved from P by CPU 2. At the end of the sequence, any of the
+There is an obvious data dependency here, as the value loaded into ``D`` depends on
+the address retrieved from ``P`` by CPU 2. At the end of the sequence, any of the
following results are possible::
(Q == &A) and (D == 1)
(Q == &B) and (D == 2)
(Q == &B) and (D == 4)
-Note that CPU 2 will never try and load C into D because the CPU will load P
-into Q before issuing the load of *Q.
+Note that CPU 2 will never try and load ``C`` into ``D`` because the CPU will load ``P``
+into ``Q`` before issuing the load of ``*Q``.
Device operations
@@ -199,8 +199,8 @@ Device operations
Some devices present their control interfaces as collections of memory
locations, but the order in which the control registers are accessed is very
important. For instance, imagine an ethernet card with a set of internal
-registers that are accessed through an address port register (A) and a data
-port register (D). To read internal register 5, the following code might then
+registers that are accessed through an address port register (``A``) and a data
+port register (``D``). To read internal register 5, the following code might then
be used::
*A = 5;
@@ -558,12 +558,12 @@ following sequence of events::
D = *Q;
There's a clear data dependency here, and it would seem that by the end of the
-sequence, Q must be either &A or &B, and that::
+sequence, ``Q`` must be either ``&A`` or ``&B``, and that::
(Q == &A) implies (D == 1)
(Q == &B) implies (D == 4)
-But! CPU 2's perception of P may be updated _before_ its perception of B, thus
+But! CPU 2's perception of ``P`` may be updated _before_ its perception of ``B``, thus
leading to the following situation::
(Q == &B) and (D == 2) ????
@@ -600,8 +600,8 @@ A data-dependency barrier must also order against dependent writes::
<data dependency barrier>
*Q = 5;
-The data-dependency barrier must order the read into Q with the store
-into *Q. This prohibits this outcome::
+The data-dependency barrier must order the read into ``Q`` with the store
+into ``*Q``. This prohibits this outcome::
(Q == &B) && (B == 4)
@@ -615,11 +615,11 @@ prevents such records from being lost.
[!] Note that this extremely counterintuitive situation arises most easily on
machines with split caches, so that, for example, one cache bank processes
even-numbered cache lines and the other bank processes odd-numbered cache
-lines. The pointer P might be stored in an odd-numbered cache line, and the
-variable B might be stored in an even-numbered cache line. Then, if the
+lines. The pointer ``P`` might be stored in an odd-numbered cache line, and the
+variable ``B`` might be stored in an even-numbered cache line. Then, if the
even-numbered bank of the reading CPU's cache is extremely busy while the
-odd-numbered bank is idle, one can see the new value of the pointer P (&B),
-but the old value of the variable B (2).
+odd-numbered bank is idle, one can see the new value of the pointer ``P`` (``&B``),
+but the old value of the variable ``B`` (2).
The data dependency barrier is very important to the RCU system,
@@ -651,7 +651,7 @@ following bit of code::
This will not have the desired effect because there is no actual data
dependency, but rather a control dependency that the CPU may short-circuit
by attempting to predict the outcome in advance, so that other CPUs see
-the load from b as having happened before the load from a. In such a
+the load from ``b`` as having happened before the load from ``a``. In such a
case what's actually required is::
q = READ_ONCE(a);
@@ -671,12 +671,12 @@ for load-store control dependencies, as in the following example::
Control dependencies pair normally with other types of barriers.
That said, please note that neither READ_ONCE() nor WRITE_ONCE()
are optional! Without the READ_ONCE(), the compiler might combine the
-load from 'a' with other loads from 'a'. Without the WRITE_ONCE(),
-the compiler might combine the store to 'b' with other stores to 'b'.
+load from ``a`` with other loads from ``a``. Without the WRITE_ONCE(),
+the compiler might combine the store to ``b`` with other stores to ``b``.
Either can result in highly counterintuitive effects on ordering.
Worse yet, if the compiler is able to prove (say) that the value of
-variable 'a' is always non-zero, it would be well within its rights
+variable ``a`` is always non-zero, it would be well within its rights
to optimize the original example by eliminating the "if" statement
as follows::
@@ -713,8 +713,8 @@ optimization levels::
do_something_else();
}
-Now there is no conditional between the load from 'a' and the store to
-'b', which means that the CPU is within its rights to reorder them:
+Now there is no conditional between the load from ``a`` and the store to
+``b``, which means that the CPU is within its rights to reorder them:
The conditional is absolutely required, and must be present in the
assembly code even after all compiler optimizations have been applied.
Therefore, if you need ordering in this example, you need explicit
@@ -742,9 +742,9 @@ ordering is guaranteed only when the stores differ, for example::
}
The initial READ_ONCE() is still required to prevent the compiler from
-proving the value of 'a'.
+proving the value of ``a``.
-In addition, you need to be careful what you do with the local variable 'q',
+In addition, you need to be careful what you do with the local variable ``q``,
otherwise the compiler might be able to guess the value and again remove
the needed conditional. For example::
@@ -757,7 +757,7 @@ the needed conditional. For example::
do_something_else();
}
-If MAX is defined to be 1, then the compiler knows that (q % MAX) is
+If MAX is defined to be 1, then the compiler knows that ``(q % MAX)`` is
equal to zero, in which case the compiler is within its rights to
transform the above code into the following::
@@ -766,7 +766,7 @@ transform the above code into the following::
do_something_else();
Given this transformation, the CPU is not required to respect the ordering
-between the load from variable 'a' and the store to variable 'b'. It is
+between the load from variable ``a`` and the store to variable ``b``. It is
tempting to add a barrier(), but this does not help. The conditional
is gone, and the barrier won't bring it back. Therefore, if you are
relying on this ordering, you should make sure that MAX is greater than
@@ -782,7 +782,7 @@ one, perhaps as follows::
do_something_else();
}
-Please note once again that the stores to 'b' differ. If they were
+Please note once again that the stores to ``b`` differ. If they were
identical, as noted earlier, the compiler could pull this store outside
of the 'if' statement.
@@ -819,8 +819,8 @@ not necessarily apply to code following the if-statement::
It is tempting to argue that there in fact is ordering because the
compiler cannot reorder volatile accesses and also cannot reorder
-the writes to 'b' with the condition. Unfortunately for this line
-of reasoning, the compiler might compile the two writes to 'b' as
+the writes to ``b`` with the condition. Unfortunately for this line
+of reasoning, the compiler might compile the two writes to ``b`` as
conditional-move instructions, as in this fanciful pseudo-assembly
language::
@@ -832,7 +832,7 @@ language::
st $1,c
A weakly ordered CPU would have no dependency of any sort between the load
-from 'a' and the store to 'c'. The control dependencies would extend
+from ``a`` and the store to ``c``. The control dependencies would extend
only to the pair of cmov instructions and the store depending on them.
In short, control dependencies apply only to the stores in the then-clause
and else-clause of the if-statement in question (including functions
@@ -840,7 +840,7 @@ invoked by those two clauses), not to code following that if-statement.
Finally, control dependencies do -not- provide transitivity. This is
demonstrated by two related examples, with the initial values of
-'x' and 'y' both being zero::
+``x`` and ``y`` both being zero::
CPU 0 CPU 1
======================= =======================
@@ -994,9 +994,9 @@ Consider the following sequence of events::
STORE E = 5
This sequence of events is committed to the memory coherence system in an order
-that the rest of the system might perceive as the unordered set of { STORE A,
-STORE B, STORE C } all occurring before the unordered set of { STORE D, STORE E
-}::
+that the rest of the system might perceive as the unordered set of ``{ STORE A,
+STORE B, STORE C }`` all occurring before the unordered set of ``{ STORE D, STORE E
+}``::
+-------+ : :
| | +------+
@@ -1062,11 +1062,11 @@ effectively random order, despite the write barrier issued by CPU 1::
: :
-In the above example, CPU 2 perceives that B is 7, despite the load of *C
-(which would be B) coming after the LOAD of C.
+In the above example, CPU 2 perceives that ``B`` is 7, despite the load of ``*C``
+(which would be ``B``) coming after the LOAD of ``C``.
-If, however, a data dependency barrier were to be placed between the load of C
-and the load of *C (ie: B) on CPU 2::
+If, however, a data dependency barrier were to be placed between the load of ``C``
+and the load of ``*C`` (ie: ``B``) on CPU 2::
CPU 1 CPU 2
======================= =======================
@@ -1142,8 +1142,8 @@ some effectively random order, despite the write barrier issued by CPU 1::
: :
-If, however, a read barrier were to be placed between the load of B and the
-load of A on CPU 2::
+If, however, a read barrier were to be placed between the load of ``B`` and the
+load of ``A`` on CPU 2::
CPU 1 CPU 2
======================= =======================
@@ -1179,7 +1179,7 @@ then the partial ordering imposed by CPU 1 will be perceived correctly by CPU
To illustrate this more completely, consider what could happen if the code
-contained a load of A either side of the read barrier::
+contained a load of ``A`` either side of the read barrier::
CPU 1 CPU 2
======================= =======================
@@ -1192,7 +1192,7 @@ contained a load of A either side of the read barrier::
<read barrier>
LOAD A [second load of A]
-Even though the two loads of A both occur after the load of B, they may both
+Even though the two loads of ``A`` both occur after the load of ``B``, they may both
come up with different values::
+-------+ : : : :
@@ -1218,7 +1218,7 @@ come up with different values::
: : +-------+
-But it may be that the update to A from CPU 1 becomes perceptible to CPU 2
+But it may be that the update to ``A`` from CPU 1 becomes perceptible to CPU 2
before the read barrier completes anyway::
+-------+ : : : :
@@ -1244,9 +1244,9 @@ before the read barrier completes anyway::
: : +-------+
-The guarantee is that the second load will always come up with A == 1 if the
-load of B came up with B == 2. No such guarantee exists for the first load of
-A; that may come up with either A == 0 or A == 1.
+The guarantee is that the second load will always come up with ``A`` == 1 if the
+load of ``B`` came up with ``B`` == 2. No such guarantee exists for the first load of
+``A``; that may come up with either ``A`` == 0 or ``A`` == 1.
Read memory barriers vs load speculation
@@ -1360,21 +1360,21 @@ demonstrates transitivity::
<general barrier> <general barrier>
LOAD Y LOAD X
-Suppose that CPU 2's load from X returns 1 and its load from Y returns 0.
-This indicates that CPU 2's load from X in some sense follows CPU 1's
-store to X and that CPU 2's load from Y in some sense preceded CPU 3's
-store to Y. The question is then "Can CPU 3's load from X return 0?"
+Suppose that CPU 2's load from ``X`` returns 1 and its load from ``Y`` returns 0.
+This indicates that CPU 2's load from ``X`` in some sense follows CPU 1's
+store to ``X`` and that CPU 2's load from ``Y`` in some sense preceded CPU 3's
+store to ``Y``. The question is then "Can CPU 3's load from ``X`` return 0?"
-Because CPU 2's load from X in some sense came after CPU 1's store, it
-is natural to expect that CPU 3's load from X must therefore return 1.
+Because CPU 2's load from ``X`` in some sense came after CPU 1's store, it
+is natural to expect that CPU 3's load from ``X`` must therefore return 1.
This expectation is an example of transitivity: if a load executing on
CPU A follows a load from the same variable executing on CPU B, then
CPU A's load must either return the same value that CPU B's load did,
or must return some later value.
In the Linux kernel, use of general memory barriers guarantees
-transitivity. Therefore, in the above example, if CPU 2's load from X
-returns 1 and its load from Y returns 0, then CPU 3's load from X must
+transitivity. Therefore, in the above example, if CPU 2's load from ``X``
+returns 1 and its load from ``Y`` returns 0, then CPU 3's load from ``X`` must
also return 1.
However, transitivity is -not- guaranteed for read or write barriers.
@@ -1389,8 +1389,8 @@ is changed to a read barrier as shown below::
LOAD Y LOAD X
This substitution destroys transitivity: in this example, it is perfectly
-legal for CPU 2's load from X to return 1, its load from Y to return 0,
-and CPU 3's load from X to return 0.
+legal for CPU 2's load from ``X`` to return 1, its load from ``Y`` to return 0,
+and CPU 3's load from ``X`` to return 0.
The key point is that although CPU 2's read barrier orders its pair
of loads, it does not guarantee to order CPU 1's store. Therefore, if
@@ -1530,7 +1530,7 @@ of optimizations:
a[0] = x;
a[1] = x;
- Might result in an older value of x stored in a[1] than in a[0].
+ Might result in an older value of ``x`` stored in ``a[1]`` than in ``a[0]``.
Prevent both the compiler and the CPU from doing this as follows::
a[0] = READ_ONCE(x);
@@ -1562,7 +1562,7 @@ of optimizations:
(#) The compiler is within its rights to reload a variable, for example,
in cases where high register pressure prevents the compiler from
keeping all data of interest in registers. The compiler might
- therefore optimize the variable 'tmp' out of our previous example::
+ therefore optimize the variable ``tmp`` out of our previous example::
while (tmp = a)
do_something_with(tmp);
@@ -1591,7 +1591,7 @@ of optimizations:
(#) The compiler is within its rights to omit a load entirely if it knows
what the value will be. For example, if the compiler can prove that
- the value of variable 'a' is always zero, it can optimize this code::
+ the value of variable ``a`` is always zero, it can optimize this code::
while (tmp = a)
do_something_with(tmp);
@@ -1603,7 +1603,7 @@ of optimizations:
This transformation is a win for single-threaded code because it
gets rid of a load and a branch. The problem is that the compiler
will carry out its proof assuming that the current CPU is the only
- one updating variable 'a'. If variable 'a' is shared, then the
+ one updating variable ``a``. If variable ``a`` is shared, then the
compiler's proof will be erroneous. Use READ_ONCE() to tell the
compiler that it doesn't know as much as it thinks it does::
@@ -1620,7 +1620,7 @@ of optimizations:
Then the compiler knows that the result of the "%" operator applied
to MAX will always be zero, again allowing the compiler to optimize
the code into near-nonexistence. (It will still load from the
- variable 'a'.)
+ variable ``a``.)
(#) Similarly, the compiler is within its rights to omit a store entirely
if it knows that the variable already has the value being stored.
@@ -1633,9 +1633,9 @@ of optimizations:
... Code that does not store to variable a ...
a = 0;
- The compiler sees that the value of variable 'a' is already zero, so
+ The compiler sees that the value of variable ``a`` is already zero, so
it might well omit the second store. This would come as a fatal
- surprise if some other CPU might have stored to variable 'a' in the
+ surprise if some other CPU might have stored to variable ``a`` in the
meantime.
Use WRITE_ONCE() to prevent the compiler from making this sort of
@@ -1689,7 +1689,7 @@ of optimizations:
Note that the READ_ONCE() and WRITE_ONCE() wrappers in
interrupt_handler() are needed if this interrupt handler can itself
- be interrupted by something that also accesses 'flag' and 'msg',
+ be interrupted by something that also accesses ``flag`` and ``msg``,
for example, a nested interrupt or an NMI. Otherwise, READ_ONCE()
and WRITE_ONCE() are not needed in interrupt_handler() other than
for documentation purposes. (Note also that nested interrupts
@@ -1727,7 +1727,7 @@ of optimizations:
In single-threaded code, this is not only safe, but also saves
a branch. Unfortunately, in concurrent code, this optimization
could cause some other CPU to see a spurious value of 42 -- even
- if variable 'a' was never zero -- when loading variable 'b'.
+ if variable ``a`` was never zero -- when loading variable ``b``.
Use WRITE_ONCE() to prevent this as follows::
if (a)
@@ -1779,7 +1779,7 @@ of optimizations:
volatile markings, the compiler would be well within its rights to
implement these three assignment statements as a pair of 32-bit
loads followed by a pair of 32-bit stores. This would result in
- load tearing on 'foo1.b' and store tearing on 'foo2.b'. READ_ONCE()
+ load tearing on ``foo1.b`` and store tearing on ``foo2.b``. READ_ONCE()
and WRITE_ONCE() again prevent tearing in this example::
foo2.a = foo1.a;
@@ -1788,7 +1788,7 @@ of optimizations:
All that aside, it is never necessary to use READ_ONCE() and
WRITE_ONCE() on a variable that has been marked volatile. For example,
-because 'jiffies' is marked volatile, it is never necessary to
+because ``jiffies`` is marked volatile, it is never necessary to
say READ_ONCE(jiffies). The reason for this is that READ_ONCE() and
WRITE_ONCE() are implemented as volatile casts, which has no effect when
its argument is already marked volatile.
@@ -1816,12 +1816,12 @@ All memory barriers except the data dependency barriers imply a compiler
barrier. Data dependencies do not impose any additional compiler ordering.
Aside: In the case of data dependencies, the compiler would be expected
-to issue the loads in the correct order (eg. `a[b]` would have to load
-the value of b before loading a[b]), however there is no guarantee in
-the C specification that the compiler may not speculate the value of b
-(eg. is equal to 1) and load a before b (eg. tmp = a[1]; if (b != 1)
-tmp = a[b]; ). There is also the problem of a compiler reloading b after
-having loaded a[b], thus having a newer copy of b than a[b]. A consensus
+to issue the loads in the correct order (eg. ``a[b]`` would have to load
+the value of ``b`` before loading ``a[b]``), however there is no guarantee in
+the C specification that the compiler may not speculate the value of ``b``
+(eg. is equal to 1) and load ``a`` before ``b`` (eg. ``tmp`` = ``a[1]``; if (``b`` != 1)
+``tmp = ``a[b]``; ). There is also the problem of a compiler reloading b after
+having loaded ``a[b]``, thus having a newer copy of ``b`` than ``a[b]``. A consensus
has not yet been reached about these problems, however the READ_ONCE()
macro is a good place to start looking.
@@ -2197,7 +2197,7 @@ events, where X and Y are both initially zero::
wake_up(); load from Y sees 1, no memory barrier
load from X might see 0
-In contrast, if a wakeup does occur, CPU 2's load from X would be guaranteed
+In contrast, if a wakeup does occur, CPU 2's load from ``X`` would be guaranteed
to see 1.
The available waker functions include::
@@ -2274,7 +2274,7 @@ conflict on any particular lock.
Acquires vs memory accesses
---------------------------
-Consider the following: the system has a pair of spinlocks (M) and (Q), and
+Consider the following: the system has a pair of spinlocks (``M``) and (``Q``), and
three CPUs; then should the following sequence of events occur::
CPU 1 CPU 2
@@ -2286,8 +2286,8 @@ three CPUs; then should the following sequence of events occur::
RELEASE M RELEASE Q
WRITE_ONCE(*D, d); WRITE_ONCE(*H, h);
-Then there is no guarantee as to what order CPU 3 will see the accesses to *A
-through *H occur in, other than the constraints imposed by the separate locks
+Then there is no guarantee as to what order CPU 3 will see the accesses to ``*A``
+through ``*H`` occur in, other than the constraints imposed by the separate locks
on the separate CPUs. It might, for example, see::
*E, ACQUIRE M, ACQUIRE Q, *G, *C, *F, *A, *B, RELEASE Q, *D, *H, RELEASE M
@@ -2896,7 +2896,7 @@ now imagine that the second CPU wants to read those values::
The above pair of reads may then fail to happen in the expected order, as the
cacheline holding p may get updated in one of the second CPU's caches whilst
-the update to the cacheline holding v is delayed in the other of the second
+the update to the cacheline holding ``v`` is delayed in the other of the second
CPU's caches by some other cache event::
CPU 1 CPU 2 COMMENT
@@ -3089,7 +3089,7 @@ may be reduced to::
*A = W;
since, without either a write barrier or an WRITE_ONCE(), it can be
-assumed that the effect of the storage of V to *A is lost. Similarly::
+assumed that the effect of the storage of ``V`` to ``*A`` is lost. Similarly::
*A = Y;
Z = *A;
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 29/29] pi-futex.txt: standardize document format |
| Message-ID | <tTnZp-Cs-57@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different format. Some doesn't even have titles! Change its representation to follow the adopted standard, using ReST markups for it to be parseable by Sphinx. This document requires just minor adjustments to match the standard documentation style: - promote document name; - remove extra collons on some chapter titles; - use "-" for a bulleted list. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> --- Documentation/pi-futex.txt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Documentation/pi-futex.txt b/Documentation/pi-futex.txt index 9a5bc8651c29..aafddbee7377 100644 --- a/Documentation/pi-futex.txt +++ b/Documentation/pi-futex.txt @@ -1,5 +1,6 @@ +====================== Lightweight PI-futexes ----------------------- +====================== We are calling them lightweight for 3 reasons: @@ -25,8 +26,8 @@ determinism and well-bound latencies. Even in the worst-case, PI will improve the statistical distribution of locking related application delays. -The longer reply: ------------------ +The longer reply +---------------- Firstly, sharing locks between multiple tasks is a common programming technique that often cannot be replaced with lockless algorithms. As we @@ -71,8 +72,8 @@ deterministic execution of the high-prio task: any medium-priority task could preempt the low-prio task while it holds the shared lock and executes the critical section, and could delay it indefinitely. -Implementation: ---------------- +Implementation +-------------- As mentioned before, the userspace fastpath of PI-enabled pthread mutexes involves no kernel work at all - they behave quite similarly to @@ -83,8 +84,8 @@ entering the kernel. To handle the slowpath, we have added two new futex ops: - FUTEX_LOCK_PI - FUTEX_UNLOCK_PI + - FUTEX_LOCK_PI + - FUTEX_UNLOCK_PI If the lock-acquire fastpath fails, [i.e. an atomic transition from 0 to TID fails], then FUTEX_LOCK_PI is called. The kernel does all the -- 2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 11/29] kref.txt: standardize document format |
| Message-ID | <tTnZp-Cs-59@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- add a title for the document and section titles;
- move authorship information to the beginning and use
:Author:
- mark literal blocks as such and ident them if needed.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/kref.txt | 285 ++++++++++++++++++++++++++-----------------------
1 file changed, 150 insertions(+), 135 deletions(-)
diff --git a/Documentation/kref.txt b/Documentation/kref.txt
index d26a27ca964d..3af384156d7e 100644
--- a/Documentation/kref.txt
+++ b/Documentation/kref.txt
@@ -1,24 +1,42 @@
+===================================================
+Adding reference counters (krefs) to kernel objects
+===================================================
+
+:Author: Corey Minyard <minyard@acm.org>
+:Author: Thomas Hellstrom <thellstrom@vmware.com>
+
+A lot of this was lifted from Greg Kroah-Hartman's 2004 OLS paper and
+presentation on krefs, which can be found at:
+
+ - http://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf
+ - http://www.kroah.com/linux/talks/ols_2004_kref_talk/
+
+Introduction
+============
krefs allow you to add reference counters to your objects. If you
have objects that are used in multiple places and passed around, and
you don't have refcounts, your code is almost certainly broken. If
you want refcounts, krefs are the way to go.
-To use a kref, add one to your data structures like:
+To use a kref, add one to your data structures like::
-struct my_data
-{
+ struct my_data
+ {
.
.
struct kref refcount;
.
.
-};
+ };
The kref can occur anywhere within the data structure.
+Initialization
+==============
+
You must initialize the kref after you allocate it. To do this, call
-kref_init as so:
+kref_init as so::
struct my_data *data;
@@ -29,18 +47,25 @@ kref_init as so:
This sets the refcount in the kref to 1.
+Kref rules
+==========
+
Once you have an initialized kref, you must follow the following
rules:
1) If you make a non-temporary copy of a pointer, especially if
it can be passed to another thread of execution, you must
- increment the refcount with kref_get() before passing it off:
+ increment the refcount with kref_get() before passing it off::
+
kref_get(&data->refcount);
+
If you already have a valid pointer to a kref-ed structure (the
refcount cannot go to zero) you may do this without a lock.
-2) When you are done with a pointer, you must call kref_put():
+2) When you are done with a pointer, you must call kref_put()::
+
kref_put(&data->refcount, data_release);
+
If this is the last reference to the pointer, the release
routine will be called. If the code never tries to get
a valid pointer to a kref-ed structure without already
@@ -53,25 +78,25 @@ rules:
structure must remain valid during the kref_get().
For example, if you allocate some data and then pass it to another
-thread to process:
+thread to process::
-void data_release(struct kref *ref)
-{
+ void data_release(struct kref *ref)
+ {
struct my_data *data = container_of(ref, struct my_data, refcount);
kfree(data);
-}
+ }
-void more_data_handling(void *cb_data)
-{
+ void more_data_handling(void *cb_data)
+ {
struct my_data *data = cb_data;
.
. do stuff with data here
.
kref_put(&data->refcount, data_release);
-}
+ }
-int my_data_handler(void)
-{
+ int my_data_handler(void)
+ {
int rv = 0;
struct my_data *data;
struct task_struct *task;
@@ -91,10 +116,10 @@ int my_data_handler(void)
.
. do stuff with data here
.
- out:
+ out:
kref_put(&data->refcount, data_release);
return rv;
-}
+ }
This way, it doesn't matter what order the two threads handle the
data, the kref_put() handles knowing when the data is not referenced
@@ -104,7 +129,7 @@ put needs no lock because nothing tries to get the data without
already holding a pointer.
Note that the "before" in rule 1 is very important. You should never
-do something like:
+do something like::
task = kthread_run(more_data_handling, data, "more_data_handling");
if (task == ERR_PTR(-ENOMEM)) {
@@ -124,14 +149,14 @@ bad style. Don't do it.
There are some situations where you can optimize the gets and puts.
For instance, if you are done with an object and enqueuing it for
something else or passing it off to something else, there is no reason
-to do a get then a put:
+to do a get then a put::
/* Silly extra get and put */
kref_get(&obj->ref);
enqueue(obj);
kref_put(&obj->ref, obj_cleanup);
-Just do the enqueue. A comment about this is always welcome:
+Just do the enqueue. A comment about this is always welcome::
enqueue(obj);
/* We are done with obj, so we pass our refcount off
@@ -142,109 +167,99 @@ instance, you have a list of items that are each kref-ed, and you wish
to get the first one. You can't just pull the first item off the list
and kref_get() it. That violates rule 3 because you are not already
holding a valid pointer. You must add a mutex (or some other lock).
-For instance:
+For instance::
-static DEFINE_MUTEX(mutex);
-static LIST_HEAD(q);
-struct my_data
-{
- struct kref refcount;
- struct list_head link;
-};
+ static DEFINE_MUTEX(mutex);
+ static LIST_HEAD(q);
+ struct my_data
+ {
+ struct kref refcount;
+ struct list_head link;
+ };
-static struct my_data *get_entry()
-{
- struct my_data *entry = NULL;
- mutex_lock(&mutex);
- if (!list_empty(&q)) {
- entry = container_of(q.next, struct my_data, link);
- kref_get(&entry->refcount);
+ static struct my_data *get_entry()
+ {
+ struct my_data *entry = NULL;
+ mutex_lock(&mutex);
+ if (!list_empty(&q)) {
+ entry = container_of(q.next, struct my_data, link);
+ kref_get(&entry->refcount);
+ }
+ mutex_unlock(&mutex);
+ return entry;
}
- mutex_unlock(&mutex);
- return entry;
-}
-static void release_entry(struct kref *ref)
-{
- struct my_data *entry = container_of(ref, struct my_data, refcount);
+ static void release_entry(struct kref *ref)
+ {
+ struct my_data *entry = container_of(ref, struct my_data, refcount);
- list_del(&entry->link);
- kfree(entry);
-}
+ list_del(&entry->link);
+ kfree(entry);
+ }
-static void put_entry(struct my_data *entry)
-{
- mutex_lock(&mutex);
- kref_put(&entry->refcount, release_entry);
- mutex_unlock(&mutex);
-}
+ static void put_entry(struct my_data *entry)
+ {
+ mutex_lock(&mutex);
+ kref_put(&entry->refcount, release_entry);
+ mutex_unlock(&mutex);
+ }
The kref_put() return value is useful if you do not want to hold the
lock during the whole release operation. Say you didn't want to call
kfree() with the lock held in the example above (since it is kind of
-pointless to do so). You could use kref_put() as follows:
+pointless to do so). You could use kref_put() as follows::
-static void release_entry(struct kref *ref)
-{
- /* All work is done after the return from kref_put(). */
-}
+ static void release_entry(struct kref *ref)
+ {
+ /* All work is done after the return from kref_put(). */
+ }
-static void put_entry(struct my_data *entry)
-{
- mutex_lock(&mutex);
- if (kref_put(&entry->refcount, release_entry)) {
- list_del(&entry->link);
- mutex_unlock(&mutex);
- kfree(entry);
- } else
- mutex_unlock(&mutex);
-}
+ static void put_entry(struct my_data *entry)
+ {
+ mutex_lock(&mutex);
+ if (kref_put(&entry->refcount, release_entry)) {
+ list_del(&entry->link);
+ mutex_unlock(&mutex);
+ kfree(entry);
+ } else
+ mutex_unlock(&mutex);
+ }
This is really more useful if you have to call other routines as part
of the free operations that could take a long time or might claim the
same lock. Note that doing everything in the release routine is still
preferred as it is a little neater.
-
-Corey Minyard <minyard@acm.org>
-
-A lot of this was lifted from Greg Kroah-Hartman's 2004 OLS paper and
-presentation on krefs, which can be found at:
- http://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf
-and:
- http://www.kroah.com/linux/talks/ols_2004_kref_talk/
-
-
The above example could also be optimized using kref_get_unless_zero() in
-the following way:
+the following way::
-static struct my_data *get_entry()
-{
- struct my_data *entry = NULL;
- mutex_lock(&mutex);
- if (!list_empty(&q)) {
- entry = container_of(q.next, struct my_data, link);
- if (!kref_get_unless_zero(&entry->refcount))
- entry = NULL;
+ static struct my_data *get_entry()
+ {
+ struct my_data *entry = NULL;
+ mutex_lock(&mutex);
+ if (!list_empty(&q)) {
+ entry = container_of(q.next, struct my_data, link);
+ if (!kref_get_unless_zero(&entry->refcount))
+ entry = NULL;
+ }
+ mutex_unlock(&mutex);
+ return entry;
}
- mutex_unlock(&mutex);
- return entry;
-}
-static void release_entry(struct kref *ref)
-{
- struct my_data *entry = container_of(ref, struct my_data, refcount);
+ static void release_entry(struct kref *ref)
+ {
+ struct my_data *entry = container_of(ref, struct my_data, refcount);
- mutex_lock(&mutex);
- list_del(&entry->link);
- mutex_unlock(&mutex);
- kfree(entry);
-}
+ mutex_lock(&mutex);
+ list_del(&entry->link);
+ mutex_unlock(&mutex);
+ kfree(entry);
+ }
-static void put_entry(struct my_data *entry)
-{
- kref_put(&entry->refcount, release_entry);
-}
+ static void put_entry(struct my_data *entry)
+ {
+ kref_put(&entry->refcount, release_entry);
+ }
Which is useful to remove the mutex lock around kref_put() in put_entry(), but
it's important that kref_get_unless_zero is enclosed in the same critical
@@ -254,51 +269,51 @@ Note that it is illegal to use kref_get_unless_zero without checking its
return value. If you are sure (by already having a valid pointer) that
kref_get_unless_zero() will return true, then use kref_get() instead.
+Krefs and RCU
+=============
+
The function kref_get_unless_zero also makes it possible to use rcu
-locking for lookups in the above example:
+locking for lookups in the above example::
-struct my_data
-{
- struct rcu_head rhead;
- .
- struct kref refcount;
- .
- .
-};
+ struct my_data
+ {
+ struct rcu_head rhead;
+ .
+ struct kref refcount;
+ .
+ .
+ };
-static struct my_data *get_entry_rcu()
-{
- struct my_data *entry = NULL;
- rcu_read_lock();
- if (!list_empty(&q)) {
- entry = container_of(q.next, struct my_data, link);
- if (!kref_get_unless_zero(&entry->refcount))
- entry = NULL;
+ static struct my_data *get_entry_rcu()
+ {
+ struct my_data *entry = NULL;
+ rcu_read_lock();
+ if (!list_empty(&q)) {
+ entry = container_of(q.next, struct my_data, link);
+ if (!kref_get_unless_zero(&entry->refcount))
+ entry = NULL;
+ }
+ rcu_read_unlock();
+ return entry;
}
- rcu_read_unlock();
- return entry;
-}
-static void release_entry_rcu(struct kref *ref)
-{
- struct my_data *entry = container_of(ref, struct my_data, refcount);
+ static void release_entry_rcu(struct kref *ref)
+ {
+ struct my_data *entry = container_of(ref, struct my_data, refcount);
- mutex_lock(&mutex);
- list_del_rcu(&entry->link);
- mutex_unlock(&mutex);
- kfree_rcu(entry, rhead);
-}
+ mutex_lock(&mutex);
+ list_del_rcu(&entry->link);
+ mutex_unlock(&mutex);
+ kfree_rcu(entry, rhead);
+ }
-static void put_entry(struct my_data *entry)
-{
- kref_put(&entry->refcount, release_entry_rcu);
-}
+ static void put_entry(struct my_data *entry)
+ {
+ kref_put(&entry->refcount, release_entry_rcu);
+ }
But note that the struct kref member needs to remain in valid memory for a
rcu grace period after release_entry_rcu was called. That can be accomplished
by using kfree_rcu(entry, rhead) as done above, or by calling synchronize_rcu()
before using kfree, but note that synchronize_rcu() may sleep for a
substantial amount of time.
-
-
-Thomas Hellstrom <thellstrom@vmware.com>
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 02/29] IRQ-affinity.txt: standardize document format |
| Message-ID | <tTnZp-Cs-63@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different format. Some doesn't even have titles! Change its representation to follow the adopted standard, using ReST markups for it to be parseable by Sphinx: - Add a title for the document; - mark literal blocks as such; - use a bulleted list for changelog. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> --- Documentation/IRQ-affinity.txt | 77 ++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/Documentation/IRQ-affinity.txt b/Documentation/IRQ-affinity.txt index 01a675175a36..29da5000836a 100644 --- a/Documentation/IRQ-affinity.txt +++ b/Documentation/IRQ-affinity.txt @@ -1,8 +1,11 @@ -ChangeLog: - Started by Ingo Molnar <mingo@redhat.com> - Update by Max Krasnyansky <maxk@qualcomm.com> - +================ SMP IRQ affinity +================ + +ChangeLog: + - Started by Ingo Molnar <mingo@redhat.com> + - Update by Max Krasnyansky <maxk@qualcomm.com> + /proc/irq/IRQ#/smp_affinity and /proc/irq/IRQ#/smp_affinity_list specify which target CPUs are permitted for a given IRQ source. It's a bitmask @@ -16,50 +19,52 @@ will be set to the default mask. It can then be changed as described above. Default mask is 0xffffffff. Here is an example of restricting IRQ44 (eth1) to CPU0-3 then restricting -it to CPU4-7 (this is an 8-CPU SMP box): +it to CPU4-7 (this is an 8-CPU SMP box):: -[root@moon 44]# cd /proc/irq/44 -[root@moon 44]# cat smp_affinity -ffffffff + [root@moon 44]# cd /proc/irq/44 + [root@moon 44]# cat smp_affinity + ffffffff -[root@moon 44]# echo 0f > smp_affinity -[root@moon 44]# cat smp_affinity -0000000f -[root@moon 44]# ping -f h -PING hell (195.4.7.3): 56 data bytes -... ---- hell ping statistics --- -6029 packets transmitted, 6027 packets received, 0% packet loss -round-trip min/avg/max = 0.1/0.1/0.4 ms -[root@moon 44]# cat /proc/interrupts | grep 'CPU\|44:' - CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 - 44: 1068 1785 1785 1783 0 0 0 0 IO-APIC-level eth1 + [root@moon 44]# echo 0f > smp_affinity + [root@moon 44]# cat smp_affinity + 0000000f + [root@moon 44]# ping -f h + PING hell (195.4.7.3): 56 data bytes + ... + --- hell ping statistics --- + 6029 packets transmitted, 6027 packets received, 0% packet loss + round-trip min/avg/max = 0.1/0.1/0.4 ms + [root@moon 44]# cat /proc/interrupts | grep 'CPU\|44:' + CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 + 44: 1068 1785 1785 1783 0 0 0 0 IO-APIC-level eth1 As can be seen from the line above IRQ44 was delivered only to the first four processors (0-3). Now lets restrict that IRQ to CPU(4-7). -[root@moon 44]# echo f0 > smp_affinity -[root@moon 44]# cat smp_affinity -000000f0 -[root@moon 44]# ping -f h -PING hell (195.4.7.3): 56 data bytes -.. ---- hell ping statistics --- -2779 packets transmitted, 2777 packets received, 0% packet loss -round-trip min/avg/max = 0.1/0.5/585.4 ms -[root@moon 44]# cat /proc/interrupts | 'CPU\|44:' - CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 - 44: 1068 1785 1785 1783 1784 1069 1070 1069 IO-APIC-level eth1 +:: + + [root@moon 44]# echo f0 > smp_affinity + [root@moon 44]# cat smp_affinity + 000000f0 + [root@moon 44]# ping -f h + PING hell (195.4.7.3): 56 data bytes + .. + --- hell ping statistics --- + 2779 packets transmitted, 2777 packets received, 0% packet loss + round-trip min/avg/max = 0.1/0.5/585.4 ms + [root@moon 44]# cat /proc/interrupts | 'CPU\|44:' + CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 + 44: 1068 1785 1785 1783 1784 1069 1070 1069 IO-APIC-level eth1 This time around IRQ44 was delivered only to the last four processors. i.e counters for the CPU0-3 did not change. -Here is an example of limiting that same irq (44) to cpus 1024 to 1031: +Here is an example of limiting that same irq (44) to cpus 1024 to 1031:: -[root@moon 44]# echo 1024-1031 > smp_affinity_list -[root@moon 44]# cat smp_affinity_list -1024-1031 + [root@moon 44]# echo 1024-1031 > smp_affinity_list + [root@moon 44]# cat smp_affinity_list + 1024-1031 Note that to do this with a bitmask would require 32 bitmasks of zero to follow the pertinent one. -- 2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 19/29] memory-hotplug.txt: standardize document format |
| Message-ID | <tTnZq-Cs-71@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- use :Created: and :Updated: for the timestamps;
- comment its internal index;
- adjust titles and use proper markup;
- Whitespace fixes;
- Use cross references where needed;
- Use bulleted lists where needed;
- mark literal blocks;
- Use the ReST notation for a table.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/memory-hotplug.txt | 357 +++++++++++++++++++++------------------
1 file changed, 195 insertions(+), 162 deletions(-)
diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt
index 670f3ded0802..e2d1f455dcc7 100644
--- a/Documentation/memory-hotplug.txt
+++ b/Documentation/memory-hotplug.txt
@@ -2,43 +2,48 @@
Memory Hotplug
==============
-Created: Jul 28 2007
-Add description of notifier of memory hotplug Oct 11 2007
+:Created: Jul 28 2007
+:Updated: Add description of notifier of memory hotplug: Oct 11 2007
This document is about memory hotplug including how-to-use and current status.
Because Memory Hotplug is still under development, contents of this text will
be changed often.
-1. Introduction
- 1.1 purpose of memory hotplug
- 1.2. Phases of memory hotplug
- 1.3. Unit of Memory online/offline operation
-2. Kernel Configuration
-3. sysfs files for memory hotplug
-4. Physical memory hot-add phase
- 4.1 Hardware(Firmware) Support
- 4.2 Notify memory hot-add event by hand
-5. Logical Memory hot-add phase
- 5.1. State of memory
- 5.2. How to online memory
-6. Logical memory remove
- 6.1 Memory offline and ZONE_MOVABLE
- 6.2. How to offline memory
-7. Physical memory remove
-8. Memory hotplug event notifier
-9. Future Work List
-
-Note(1): x86_64's has special implementation for memory hotplug.
- This text does not describe it.
-Note(2): This text assumes that sysfs is mounted at /sys.
-
-
----------------
-1. Introduction
----------------
-
-1.1 purpose of memory hotplug
-------------
+.. CONTENTS
+
+ 1. Introduction
+ 1.1 purpose of memory hotplug
+ 1.2. Phases of memory hotplug
+ 1.3. Unit of Memory online/offline operation
+ 2. Kernel Configuration
+ 3. sysfs files for memory hotplug
+ 4. Physical memory hot-add phase
+ 4.1 Hardware(Firmware) Support
+ 4.2 Notify memory hot-add event by hand
+ 5. Logical Memory hot-add phase
+ 5.1. State of memory
+ 5.2. How to online memory
+ 6. Logical memory remove
+ 6.1 Memory offline and ZONE_MOVABLE
+ 6.2. How to offline memory
+ 7. Physical memory remove
+ 8. Memory hotplug event notifier
+ 9. Future Work List
+
+
+.. note::
+
+ (1) x86_64's has special implementation for memory hotplug.
+ This text does not describe it.
+ (2) This text assumes that sysfs is mounted at /sys.
+
+
+Introduction
+============
+
+purpose of memory hotplug
+-------------------------
+
Memory Hotplug allows users to increase/decrease the amount of memory.
Generally, there are two purposes.
@@ -53,9 +58,11 @@ hardware which supports memory power management.
Linux memory hotplug is designed for both purpose.
-1.2. Phases of memory hotplug
----------------
-There are 2 phases in Memory Hotplug.
+Phases of memory hotplug
+------------------------
+
+There are 2 phases in Memory Hotplug:
+
1) Physical Memory Hotplug phase
2) Logical Memory Hotplug phase.
@@ -70,7 +77,7 @@ management tables, and makes sysfs files for new memory's operation.
If firmware supports notification of connection of new memory to OS,
this phase is triggered automatically. ACPI can notify this event. If not,
"probe" operation by system administration is used instead.
-(see Section 4.).
+(see :ref:`memory_hotplug_physical_mem`).
Logical Memory Hotplug phase is to change memory state into
available/unavailable for users. Amount of memory from user's view is
@@ -83,11 +90,12 @@ Logical Memory Hotplug phase is triggered by write of sysfs file by system
administrator. For the hot-add case, it must be executed after Physical Hotplug
phase by hand.
(However, if you writes udev's hotplug scripts for memory hotplug, these
- phases can be execute in seamless way.)
+phases can be execute in seamless way.)
-1.3. Unit of Memory online/offline operation
-------------
+Unit of Memory online/offline operation
+---------------------------------------
+
Memory hotplug uses SPARSEMEM memory model which allows memory to be divided
into chunks of the same size. These chunks are called "sections". The size of
a memory section is architecture dependent. For example, power uses 16MiB, ia64
@@ -97,46 +105,50 @@ Memory sections are combined into chunks referred to as "memory blocks". The
size of a memory block is architecture dependent and represents the logical
unit upon which memory online/offline operations are to be performed. The
default size of a memory block is the same as memory section size unless an
-architecture specifies otherwise. (see Section 3.)
+architecture specifies otherwise. (see :ref:`memory_hotplug_sysfs_files`.)
To determine the size (in bytes) of a memory block please read this file:
/sys/devices/system/memory/block_size_bytes
------------------------
-2. Kernel Configuration
------------------------
+Kernel Configuration
+====================
+
To use memory hotplug feature, kernel must be compiled with following
config options.
-- For all memory hotplug
- Memory model -> Sparse Memory (CONFIG_SPARSEMEM)
- Allow for memory hot-add (CONFIG_MEMORY_HOTPLUG)
+- For all memory hotplug:
+ - Memory model -> Sparse Memory (CONFIG_SPARSEMEM)
+ - Allow for memory hot-add (CONFIG_MEMORY_HOTPLUG)
-- To enable memory removal, the following are also necessary
- Allow for memory hot remove (CONFIG_MEMORY_HOTREMOVE)
- Page Migration (CONFIG_MIGRATION)
+- To enable memory removal, the following are also necessary:
+ - Allow for memory hot remove (CONFIG_MEMORY_HOTREMOVE)
+ - Page Migration (CONFIG_MIGRATION)
-- For ACPI memory hotplug, the following are also necessary
- Memory hotplug (under ACPI Support menu) (CONFIG_ACPI_HOTPLUG_MEMORY)
- This option can be kernel module.
+- For ACPI memory hotplug, the following are also necessary:
+ - Memory hotplug (under ACPI Support menu) (CONFIG_ACPI_HOTPLUG_MEMORY)
+ - This option can be kernel module.
- As a related configuration, if your box has a feature of NUMA-node hotplug
via ACPI, then this option is necessary too.
- ACPI0004,PNP0A05 and PNP0A06 Container Driver (under ACPI Support menu)
- (CONFIG_ACPI_CONTAINER).
- This option can be kernel module too.
+ - ACPI0004,PNP0A05 and PNP0A06 Container Driver (under ACPI Support menu)
+ (CONFIG_ACPI_CONTAINER).
+
+ This option can be kernel module too.
+
+
+.. _memory_hotplug_sysfs_files:
+
+sysfs files for memory hotplug
+==============================
---------------------------------
-3 sysfs files for memory hotplug
---------------------------------
All memory blocks have their device information in sysfs. Each memory block
-is described under /sys/devices/system/memory as
+is described under /sys/devices/system/memory as:
-/sys/devices/system/memory/memoryXXX
-(XXX is the memory block id.)
+ /sys/devices/system/memory/memoryXXX
+ (XXX is the memory block id.)
For the memory block covered by the sysfs directory. It is expected that all
memory sections in this range are present and no memory holes exist in the
@@ -145,43 +157,53 @@ the existence of one should not affect the hotplug capabilities of the memory
block.
For example, assume 1GiB memory block size. A device for a memory starting at
-0x100000000 is /sys/device/system/memory/memory4
-(0x100000000 / 1Gib = 4)
+0x100000000 is /sys/device/system/memory/memory4::
+
+ (0x100000000 / 1Gib = 4)
+
This device covers address range [0x100000000 ... 0x140000000)
Under each memory block, you can see 5 files:
-/sys/devices/system/memory/memoryXXX/phys_index
-/sys/devices/system/memory/memoryXXX/phys_device
-/sys/devices/system/memory/memoryXXX/state
-/sys/devices/system/memory/memoryXXX/removable
-/sys/devices/system/memory/memoryXXX/valid_zones
+- /sys/devices/system/memory/memoryXXX/phys_index
+- /sys/devices/system/memory/memoryXXX/phys_device
+- /sys/devices/system/memory/memoryXXX/state
+- /sys/devices/system/memory/memoryXXX/removable
+- /sys/devices/system/memory/memoryXXX/valid_zones
+
+=================== ============================================================
+``phys_index`` read-only and contains memory block id, same as XXX.
+``state`` read-write
+
+ - at read: contains online/offline state of memory.
+ - at write: user can specify "online_kernel",
-'phys_index' : read-only and contains memory block id, same as XXX.
-'state' : read-write
- at read: contains online/offline state of memory.
- at write: user can specify "online_kernel",
"online_movable", "online", "offline" command
which will be performed on all sections in the block.
-'phys_device' : read-only: designed to show the name of physical memory
+``phys_device`` read-only: designed to show the name of physical memory
device. This is not well implemented now.
-'removable' : read-only: contains an integer value indicating
+``removable`` read-only: contains an integer value indicating
whether the memory block is removable or not
removable. A value of 1 indicates that the memory
block is removable and a value of 0 indicates that
it is not removable. A memory block is removable only if
every section in the block is removable.
-'valid_zones' : read-only: designed to show which zones this memory block
+``valid_zones`` read-only: designed to show which zones this memory block
can be onlined to.
- The first column shows it's default zone.
+
+ The first column shows it`s default zone.
+
"memory6/valid_zones: Normal Movable" shows this memoryblock
can be onlined to ZONE_NORMAL by default and to ZONE_MOVABLE
by online_movable.
+
"memory7/valid_zones: Movable Normal" shows this memoryblock
can be onlined to ZONE_MOVABLE by default and to ZONE_NORMAL
by online_kernel.
+=================== ============================================================
+
+.. note::
-NOTE:
These directories/files appear after physical memory hotplug phase.
If CONFIG_NUMA is enabled the memoryXXX/ directories can also be accessed
@@ -193,13 +215,14 @@ For example:
A backlink will also be created:
/sys/devices/system/memory/memory9/node0 -> ../../node/node0
+.. _memory_hotplug_physical_mem:
---------------------------------
-4. Physical memory hot-add phase
---------------------------------
+Physical memory hot-add phase
+=============================
+
+Hardware(Firmware) Support
+--------------------------
-4.1 Hardware(Firmware) Support
-------------
On x86_64/ia64 platform, memory hotplug by ACPI is supported.
In general, the firmware (ACPI) which supports memory hotplug defines
@@ -209,7 +232,8 @@ script. This will be done automatically.
But scripts for memory hotplug are not contained in generic udev package(now).
You may have to write it by yourself or online/offline memory by hand.
-Please see "How to online memory", "How to offline memory" in this text.
+Please see :ref:`memory_hotplug_how_to_online_memory` and
+:ref:`memory_hotplug_how_to_offline_memory`.
If firmware supports NUMA-node hotplug, and defines an object _HID "ACPI0004",
"PNP0A05", or "PNP0A06", notification is asserted to it, and ACPI handler
@@ -217,8 +241,9 @@ calls hotplug code for all of objects which are defined in it.
If memory device is found, memory hotplug code will be called.
-4.2 Notify memory hot-add event by hand
-------------
+Notify memory hot-add event by hand
+-----------------------------------
+
On some architectures, the firmware may not notify the kernel of a memory
hotplug event. Therefore, the memory "probe" interface is supported to
explicitly notify the kernel. This interface depends on
@@ -229,45 +254,48 @@ notification.
Probe interface is located at
/sys/devices/system/memory/probe
-You can tell the physical address of new memory to the kernel by
+You can tell the physical address of new memory to the kernel by::
-% echo start_address_of_new_memory > /sys/devices/system/memory/probe
+ % echo start_address_of_new_memory > /sys/devices/system/memory/probe
Then, [start_address_of_new_memory, start_address_of_new_memory +
memory_block_size] memory range is hot-added. In this case, hotplug script is
not called (in current implementation). You'll have to online memory by
-yourself. Please see "How to online memory" in this text.
+yourself. Please see :ref:`memory_hotplug_how_to_online_memory`.
-------------------------------
-5. Logical Memory hot-add phase
-------------------------------
+Logical Memory hot-add phase
+============================
-5.1. State of memory
-------------
-To see (online/offline) state of a memory block, read 'state' file.
+State of memory
+---------------
-% cat /sys/device/system/memory/memoryXXX/state
+To see (online/offline) state of a memory block, read 'state' file::
+ % cat /sys/device/system/memory/memoryXXX/state
-If the memory block is online, you'll read "online".
-If the memory block is offline, you'll read "offline".
+- If the memory block is online, you'll read "online".
+- If the memory block is offline, you'll read "offline".
+
+
+.. _memory_hotplug_how_to_online_memory:
+
+How to online memory
+--------------------
-5.2. How to online memory
-------------
When the memory is hot-added, the kernel decides whether or not to "online"
-it according to the policy which can be read from "auto_online_blocks" file:
+it according to the policy which can be read from "auto_online_blocks" file::
-% cat /sys/devices/system/memory/auto_online_blocks
+ % cat /sys/devices/system/memory/auto_online_blocks
The default depends on the CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE kernel config
option. If it is disabled the default is "offline" which means the newly added
memory is not in a ready-to-use state and you have to "online" the newly added
memory blocks manually. Automatic onlining can be requested by writing "online"
-to "auto_online_blocks" file:
+to "auto_online_blocks" file::
-% echo online > /sys/devices/system/memory/auto_online_blocks
+ % echo online > /sys/devices/system/memory/auto_online_blocks
This sets a global policy and impacts all memory blocks that will subsequently
be hotplugged. Currently offline blocks keep their state. It is possible, under
@@ -277,20 +305,22 @@ online. User space tools can check their "state" files
If the automatic onlining wasn't requested, failed, or some memory block was
offlined it is possible to change the individual block's state by writing to the
-"state" file:
+"state" file::
-% echo online > /sys/devices/system/memory/memoryXXX/state
+ % echo online > /sys/devices/system/memory/memoryXXX/state
This onlining will not change the ZONE type of the target memory block,
-If the memory block is in ZONE_NORMAL, you can change it to ZONE_MOVABLE:
+If the memory block is in ZONE_NORMAL, you can change it to ZONE_MOVABLE::
-% echo online_movable > /sys/devices/system/memory/memoryXXX/state
-(NOTE: current limit: this memory block must be adjacent to ZONE_MOVABLE)
+ % echo online_movable > /sys/devices/system/memory/memoryXXX/state
-And if the memory block is in ZONE_MOVABLE, you can change it to ZONE_NORMAL:
+.. note:: current limit: this memory block must be adjacent to ZONE_MOVABLE
-% echo online_kernel > /sys/devices/system/memory/memoryXXX/state
-(NOTE: current limit: this memory block must be adjacent to ZONE_NORMAL)
+And if the memory block is in ZONE_MOVABLE, you can change it to ZONE_NORMAL::
+
+ % echo online_kernel > /sys/devices/system/memory/memoryXXX/state
+
+.. note:: current limit: this memory block must be adjacent to ZONE_NORMAL
After this, memory block XXX's state will be 'online' and the amount of
available memory will be increased.
@@ -300,12 +330,12 @@ This may be changed in future.
-------------------------
-6. Logical memory remove
-------------------------
+Logical memory remove
+=====================
+
+Memory offline and ZONE_MOVABLE
+-------------------------------
-6.1 Memory offline and ZONE_MOVABLE
-------------
Memory offlining is more complicated than memory online. Because memory offline
has to make the whole memory block be unused, memory offline can fail if
the memory block includes memory which cannot be freed.
@@ -330,24 +360,27 @@ Assume the system has "TOTAL" amount of memory at boot time, this boot option
creates ZONE_MOVABLE as following.
1) When kernelcore=YYYY boot option is used,
- Size of memory not for movable pages (not for offline) is YYYY.
- Size of memory for movable pages (for offline) is TOTAL-YYYY.
+ Size of memory not for movable pages (not for offline) is YYYY.
+ Size of memory for movable pages (for offline) is TOTAL-YYYY.
2) When movablecore=ZZZZ boot option is used,
- Size of memory not for movable pages (not for offline) is TOTAL - ZZZZ.
- Size of memory for movable pages (for offline) is ZZZZ.
+ Size of memory not for movable pages (not for offline) is TOTAL - ZZZZ.
+ Size of memory for movable pages (for offline) is ZZZZ.
+.. note::
-Note: Unfortunately, there is no information to show which memory block belongs
-to ZONE_MOVABLE. This is TBD.
+ Unfortunately, there is no information to show which memory block belongs
+ to ZONE_MOVABLE. This is TBD.
+.. _memory_hotplug_how_to_offline_memory:
+
+How to offline memory
+---------------------
-6.2. How to offline memory
-------------
You can offline a memory block by using the same sysfs interface that was used
-in memory onlining.
+in memory onlining::
-% echo offline > /sys/devices/system/memory/memoryXXX/state
+ % echo offline > /sys/devices/system/memory/memoryXXX/state
If offline succeeds, the state of the memory block is changed to be "offline".
If it fails, some error core (like -EBUSY) will be returned by the kernel.
@@ -361,22 +394,22 @@ able to offline it (or not). (For example, a page is referred to by some kernel
internal call and released soon.)
Consideration:
-Memory hotplug's design direction is to make the possibility of memory offlining
-higher and to guarantee unplugging memory under any situation. But it needs
-more work. Returning -EBUSY under some situation may be good because the user
-can decide to retry more or not by himself. Currently, memory offlining code
-does some amount of retry with 120 seconds timeout.
+ Memory hotplug's design direction is to make the possibility of memory
+ offlining higher and to guarantee unplugging memory under any situation. But
+ it needs more work. Returning -EBUSY under some situation may be good because
+ the user can decide to retry more or not by himself. Currently, memory
+ offlining code does some amount of retry with 120 seconds timeout.
+
+Physical memory remove
+======================
--------------------------
-7. Physical memory remove
--------------------------
Need more implementation yet....
- Notification completion of remove works by OS to firmware.
- Guard from remove if not yet.
---------------------------------
-8. Memory hotplug event notifier
---------------------------------
+Memory hotplug event notifier
+=============================
+
Hotplugging events are sent to a notification queue.
There are six types of notification defined in include/linux/memory.h:
@@ -406,14 +439,14 @@ MEM_CANCEL_OFFLINE
MEM_OFFLINE
Generated after offlining memory is complete.
-A callback routine can be registered by calling
+A callback routine can be registered by calling::
hotplug_memory_notifier(callback_func, priority)
Callback functions with higher values of priority are called before callback
functions with lower values.
-A callback function must have the following prototype:
+A callback function must have the following prototype::
int callback_func(
struct notifier_block *self, unsigned long action, void *arg);
@@ -421,27 +454,28 @@ A callback function must have the following prototype:
The first argument of the callback function (self) is a pointer to the block
of the notifier chain that points to the callback function itself.
The second argument (action) is one of the event types described above.
-The third argument (arg) passes a pointer of struct memory_notify.
+The third argument (arg) passes a pointer of struct memory_notify::
-struct memory_notify {
- unsigned long start_pfn;
- unsigned long nr_pages;
- int status_change_nid_normal;
- int status_change_nid_high;
- int status_change_nid;
-}
+ struct memory_notify {
+ unsigned long start_pfn;
+ unsigned long nr_pages;
+ int status_change_nid_normal;
+ int status_change_nid_high;
+ int status_change_nid;
+ }
-start_pfn is start_pfn of online/offline memory.
-nr_pages is # of pages of online/offline memory.
-status_change_nid_normal is set node id when N_NORMAL_MEMORY of nodemask
-is (will be) set/clear, if this is -1, then nodemask status is not changed.
-status_change_nid_high is set node id when N_HIGH_MEMORY of nodemask
-is (will be) set/clear, if this is -1, then nodemask status is not changed.
-status_change_nid is set node id when N_MEMORY of nodemask is (will be)
-set/clear. It means a new(memoryless) node gets new memory by online and a
-node loses all memory. If this is -1, then nodemask status is not changed.
-If status_changed_nid* >= 0, callback should create/discard structures for the
-node if necessary.
+- start_pfn is start_pfn of online/offline memory.
+- nr_pages is # of pages of online/offline memory.
+- status_change_nid_normal is set node id when N_NORMAL_MEMORY of nodemask
+ is (will be) set/clear, if this is -1, then nodemask status is not changed.
+- status_change_nid_high is set node id when N_HIGH_MEMORY of nodemask
+ is (will be) set/clear, if this is -1, then nodemask status is not changed.
+- status_change_nid is set node id when N_MEMORY of nodemask is (will be)
+ set/clear. It means a new(memoryless) node gets new memory by online and a
+ node loses all memory. If this is -1, then nodemask status is not changed.
+
+ If status_changed_nid* >= 0, callback should create/discard structures for the
+ node if necessary.
The callback routine shall return one of the values
NOTIFY_DONE, NOTIFY_OK, NOTIFY_BAD, NOTIFY_STOP
@@ -455,9 +489,9 @@ further processing of the notification queue.
NOTIFY_STOP stops further processing of the notification queue.
---------------
-9. Future Work
---------------
+Future Work
+===========
+
- allowing memory hot-add to ZONE_MOVABLE. maybe we need some switch like
sysctl or new control file.
- showing memory block and physical device relationship.
@@ -465,4 +499,3 @@ NOTIFY_STOP stops further processing of the notification queue.
- support HugeTLB page migration and offlining.
- memmap removing at memory offline.
- physical remove memory.
-
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 21/29] nommu-mmap.txt: standardize document format |
| Message-ID | <tTnZp-Cs-69@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- Adjust identation for main title;
- fix level for chapter titles;
- use ".. important::" tag for an important note;
- use the right notation for paragraph auto-numbering "(#)";
- Fix footnotes syntax;
- fix one literal var to use the right ReST tag.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/nommu-mmap.txt | 52 +++++++++++++++++++-------------------------
1 file changed, 22 insertions(+), 30 deletions(-)
diff --git a/Documentation/nommu-mmap.txt b/Documentation/nommu-mmap.txt
index ae57b9ea0d41..39a62ab0f50a 100644
--- a/Documentation/nommu-mmap.txt
+++ b/Documentation/nommu-mmap.txt
@@ -1,6 +1,6 @@
- =============================
- NO-MMU MEMORY MAPPING SUPPORT
- =============================
+=============================
+NO-MMU MEMORY MAPPING SUPPORT
+=============================
The kernel has limited support for memory mapping under no-MMU conditions, such
as are used in uClinux environments. From the userspace point of view, memory
@@ -16,7 +16,7 @@ the CLONE_VM flag.
The behaviour is similar between the MMU and no-MMU cases, but not identical;
and it's also much more restricted in the latter case:
- (*) Anonymous mapping, MAP_PRIVATE
+ (#) Anonymous mapping, MAP_PRIVATE
In the MMU case: VM regions backed by arbitrary pages; copy-on-write
across fork.
@@ -24,14 +24,14 @@ and it's also much more restricted in the latter case:
In the no-MMU case: VM regions backed by arbitrary contiguous runs of
pages.
- (*) Anonymous mapping, MAP_SHARED
+ (#) Anonymous mapping, MAP_SHARED
These behave very much like private mappings, except that they're
shared across fork() or clone() without CLONE_VM in the MMU case. Since
the no-MMU case doesn't support these, behaviour is identical to
MAP_PRIVATE there.
- (*) File, MAP_PRIVATE, PROT_READ / PROT_EXEC, !PROT_WRITE
+ (#) File, MAP_PRIVATE, PROT_READ / PROT_EXEC, !PROT_WRITE
In the MMU case: VM regions backed by pages read from file; changes to
the underlying file are reflected in the mapping; copied across fork.
@@ -56,7 +56,7 @@ and it's also much more restricted in the latter case:
are visible in other processes (no MMU protection), but should not
happen.
- (*) File, MAP_PRIVATE, PROT_READ / PROT_EXEC, PROT_WRITE
+ (#) File, MAP_PRIVATE, PROT_READ / PROT_EXEC, PROT_WRITE
In the MMU case: like the non-PROT_WRITE case, except that the pages in
question get copied before the write actually happens. From that point
@@ -66,7 +66,7 @@ and it's also much more restricted in the latter case:
In the no-MMU case: works much like the non-PROT_WRITE case, except
that a copy is always taken and never shared.
- (*) Regular file / blockdev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
+ (#) Regular file / blockdev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
In the MMU case: VM regions backed by pages read from file; changes to
pages written back to file; writes to file reflected into pages backing
@@ -74,7 +74,7 @@ and it's also much more restricted in the latter case:
In the no-MMU case: not supported.
- (*) Memory backed regular file, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
+ (#) Memory backed regular file, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
In the MMU case: As for ordinary regular files.
@@ -85,7 +85,7 @@ and it's also much more restricted in the latter case:
as for the MMU case. If the filesystem does not provide any such
support, then the mapping request will be denied.
- (*) Memory backed blockdev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
+ (#) Memory backed blockdev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
In the MMU case: As for ordinary regular files.
@@ -94,7 +94,7 @@ and it's also much more restricted in the latter case:
truncate being called. The ramdisk driver could do this if it allocated
all its memory as a contiguous array upfront.
- (*) Memory backed chardev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
+ (#) Memory backed chardev, MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
In the MMU case: As for ordinary regular files.
@@ -105,21 +105,20 @@ and it's also much more restricted in the latter case:
provide any such support, then the mapping request will be denied.
-============================
FURTHER NOTES ON NO-MMU MMAP
============================
- (*) A request for a private mapping of a file may return a buffer that is not
+ (#) A request for a private mapping of a file may return a buffer that is not
page-aligned. This is because XIP may take place, and the data may not be
paged aligned in the backing store.
- (*) A request for an anonymous mapping will always be page aligned. If
+ (#) A request for an anonymous mapping will always be page aligned. If
possible the size of the request should be a power of two otherwise some
of the space may be wasted as the kernel must allocate a power-of-2
granule but will only discard the excess if appropriately configured as
this has an effect on fragmentation.
- (*) The memory allocated by a request for an anonymous mapping will normally
+ (#) The memory allocated by a request for an anonymous mapping will normally
be cleared by the kernel before being returned in accordance with the
Linux man pages (ver 2.22 or later).
@@ -145,23 +144,22 @@ FURTHER NOTES ON NO-MMU MMAP
uClibc uses this to speed up malloc(), and the ELF-FDPIC binfmt uses this
to allocate the brk and stack region.
- (*) A list of all the private copy and anonymous mappings on the system is
+ (#) A list of all the private copy and anonymous mappings on the system is
visible through /proc/maps in no-MMU mode.
- (*) A list of all the mappings in use by a process is visible through
+ (#) A list of all the mappings in use by a process is visible through
/proc/<pid>/maps in no-MMU mode.
- (*) Supplying MAP_FIXED or a requesting a particular mapping address will
+ (#) Supplying MAP_FIXED or a requesting a particular mapping address will
result in an error.
- (*) Files mapped privately usually have to have a read method provided by the
+ (#) Files mapped privately usually have to have a read method provided by the
driver or filesystem so that the contents can be read into the memory
allocated if mmap() chooses not to map the backing device directly. An
error will result if they don't. This is most likely to be encountered
with character device files, pipes, fifos and sockets.
-==========================
INTERPROCESS SHARED MEMORY
==========================
@@ -170,7 +168,6 @@ mode. The former through the usual mechanism, the latter through files created
on ramfs or tmpfs mounts.
-=======
FUTEXES
=======
@@ -180,12 +177,11 @@ mappings made by a process or if the mapping in which the address lies does not
support futexes (such as an I/O chardev mapping).
-=============
NO-MMU MREMAP
=============
The mremap() function is partially supported. It may change the size of a
-mapping, and may move it[*] if MREMAP_MAYMOVE is specified and if the new size
+mapping, and may move it [#]_ if MREMAP_MAYMOVE is specified and if the new size
of the mapping exceeds the size of the slab object currently occupied by the
memory to which the mapping refers, or if a smaller slab object could be used.
@@ -200,10 +196,9 @@ a previously mapped object. It may not be used to create holes in existing
mappings, move parts of existing mappings or resize parts of mappings. It must
act on a complete mapping.
-[*] Not currently supported.
+.. [#] Not currently supported.
-============================================
PROVIDING SHAREABLE CHARACTER DEVICE SUPPORT
============================================
@@ -235,7 +230,7 @@ direct the call to the device-specific driver. Under such circumstances, the
mapping request will be rejected if NOMMU_MAP_COPY is not specified, and a
copy mapped otherwise.
-IMPORTANT NOTE:
+.. important::
Some types of device may present a different appearance to anyone
looking at them in certain modes. Flash chips can be like this; for
@@ -249,7 +244,6 @@ IMPORTANT NOTE:
circumstances!
-==============================================
PROVIDING SHAREABLE MEMORY-BACKED FILE SUPPORT
==============================================
@@ -267,7 +261,6 @@ Memory backed devices are indicated by the mapping's backing device info having
the memory_backed flag set.
-========================================
PROVIDING SHAREABLE BLOCK DEVICE SUPPORT
========================================
@@ -276,7 +269,6 @@ character devices. If there isn't a real device underneath, then the driver
should allocate sufficient contiguous memory to honour any supported mapping.
-=================================
ADJUSTING PAGE TRIMMING BEHAVIOUR
=================================
@@ -288,4 +280,4 @@ allocator. In order to retain finer-grained control over fragmentation, this
behaviour can either be disabled completely, or bumped up to a higher page
watermark where trimming begins.
-Page trimming behaviour is configurable via the sysctl `vm.nr_trim_pages'.
+Page trimming behaviour is configurable via the sysctl ``vm.nr_trim_pages``.
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 27/29] percpu-rw-semaphore.txt: standardize document format |
| Message-ID | <tTnZq-Cs-79@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different format. Some doesn't even have titles! Change its representation to follow the adopted standard, using ReST markups for it to be parseable by Sphinx: This document is already adopting the standard format, with a single exception: we're using this convention for the document title: === foo === So, adjust the title of this document to follow the standard. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> --- Documentation/percpu-rw-semaphore.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/percpu-rw-semaphore.txt b/Documentation/percpu-rw-semaphore.txt index 7d3c82431909..247de6410855 100644 --- a/Documentation/percpu-rw-semaphore.txt +++ b/Documentation/percpu-rw-semaphore.txt @@ -1,5 +1,6 @@ +==================== Percpu rw semaphores --------------------- +==================== Percpu rw semaphores is a new read-write semaphore design that is optimized for locking for reading. -- 2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 28/29] phy.txt: standardize document format |
| Message-ID | <tTnZq-Cs-77@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different format. Some doesn't even have titles! Change its representation to follow the adopted standard, using ReST markups for it to be parseable by Sphinx: - mark titles; - use :Author: for authorship; - mark literal blocks. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> --- Documentation/phy.txt | 106 +++++++++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 39 deletions(-) diff --git a/Documentation/phy.txt b/Documentation/phy.txt index 383cdd863f08..457c3e0f86d6 100644 --- a/Documentation/phy.txt +++ b/Documentation/phy.txt @@ -1,10 +1,14 @@ - PHY SUBSYSTEM - Kishon Vijay Abraham I <kishon@ti.com> +============= +PHY subsystem +============= + +:Author: Kishon Vijay Abraham I <kishon@ti.com> This document explains the Generic PHY Framework along with the APIs provided, and how-to-use. -1. Introduction +Introduction +============ *PHY* is the abbreviation for physical layer. It is used to connect a device to the physical medium e.g., the USB controller has a PHY to provide functions @@ -21,7 +25,8 @@ better code maintainability. This framework will be of use only to devices that use external PHY (PHY functionality is not embedded within the controller). -2. Registering/Unregistering the PHY provider +Registering/Unregistering the PHY provider +========================================== PHY provider refers to an entity that implements one or more PHY instances. For the simple case where the PHY provider implements only a single instance of @@ -30,11 +35,14 @@ of_phy_simple_xlate. If the PHY provider implements multiple instances, it should provide its own implementation of of_xlate. of_xlate is used only for dt boot case. -#define of_phy_provider_register(dev, xlate) \ - __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) +:: -#define devm_of_phy_provider_register(dev, xlate) \ - __devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) + #define of_phy_provider_register(dev, xlate) \ + __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) + + #define devm_of_phy_provider_register(dev, xlate) \ + __devm_of_phy_provider_register((dev), NULL, THIS_MODULE, + (xlate)) of_phy_provider_register and devm_of_phy_provider_register macros can be used to register the phy_provider and it takes device and of_xlate as @@ -47,28 +55,35 @@ nodes within extra levels for context and extensibility, in which case the low level of_phy_provider_register_full() and devm_of_phy_provider_register_full() macros can be used to override the node containing the children. -#define of_phy_provider_register_full(dev, children, xlate) \ - __of_phy_provider_register(dev, children, THIS_MODULE, xlate) +:: -#define devm_of_phy_provider_register_full(dev, children, xlate) \ - __devm_of_phy_provider_register_full(dev, children, THIS_MODULE, xlate) + #define of_phy_provider_register_full(dev, children, xlate) \ + __of_phy_provider_register(dev, children, THIS_MODULE, xlate) -void devm_of_phy_provider_unregister(struct device *dev, - struct phy_provider *phy_provider); -void of_phy_provider_unregister(struct phy_provider *phy_provider); + #define devm_of_phy_provider_register_full(dev, children, xlate) \ + __devm_of_phy_provider_register_full(dev, children, + THIS_MODULE, xlate) + + void devm_of_phy_provider_unregister(struct device *dev, + struct phy_provider *phy_provider); + void of_phy_provider_unregister(struct phy_provider *phy_provider); devm_of_phy_provider_unregister and of_phy_provider_unregister can be used to unregister the PHY. -3. Creating the PHY +Creating the PHY +================ The PHY driver should create the PHY in order for other peripheral controllers to make use of it. The PHY framework provides 2 APIs to create the PHY. -struct phy *phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops); -struct phy *devm_phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops); +:: + + struct phy *phy_create(struct device *dev, struct device_node *node, + const struct phy_ops *ops); + struct phy *devm_phy_create(struct device *dev, + struct device_node *node, + const struct phy_ops *ops); The PHY drivers can use one of the above 2 APIs to create the PHY by passing the device pointer and phy ops. @@ -84,12 +99,16 @@ phy_ops to get back the private data. Before the controller can make use of the PHY, it has to get a reference to it. This framework provides the following APIs to get a reference to the PHY. -struct phy *phy_get(struct device *dev, const char *string); -struct phy *phy_optional_get(struct device *dev, const char *string); -struct phy *devm_phy_get(struct device *dev, const char *string); -struct phy *devm_phy_optional_get(struct device *dev, const char *string); -struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, - int index); +:: + + struct phy *phy_get(struct device *dev, const char *string); + struct phy *phy_optional_get(struct device *dev, const char *string); + struct phy *devm_phy_get(struct device *dev, const char *string); + struct phy *devm_phy_optional_get(struct device *dev, + const char *string); + struct phy *devm_of_phy_get_by_index(struct device *dev, + struct device_node *np, + int index); phy_get, phy_optional_get, devm_phy_get and devm_phy_optional_get can be used to get the PHY. In the case of dt boot, the string arguments @@ -111,30 +130,35 @@ the phy_init() and phy_exit() calls, and phy_power_on() and phy_power_off() calls are all NOP when applied to a NULL phy. The NULL phy is useful in devices for handling optional phy devices. -5. Releasing a reference to the PHY +Releasing a reference to the PHY +================================ When the controller no longer needs the PHY, it has to release the reference to the PHY it has obtained using the APIs mentioned in the above section. The PHY framework provides 2 APIs to release a reference to the PHY. -void phy_put(struct phy *phy); -void devm_phy_put(struct device *dev, struct phy *phy); +:: + + void phy_put(struct phy *phy); + void devm_phy_put(struct device *dev, struct phy *phy); Both these APIs are used to release a reference to the PHY and devm_phy_put destroys the devres associated with this PHY. -6. Destroying the PHY +Destroying the PHY +================== When the driver that created the PHY is unloaded, it should destroy the PHY it -created using one of the following 2 APIs. +created using one of the following 2 APIs:: -void phy_destroy(struct phy *phy); -void devm_phy_destroy(struct device *dev, struct phy *phy); + void phy_destroy(struct phy *phy); + void devm_phy_destroy(struct device *dev, struct phy *phy); Both these APIs destroy the PHY and devm_phy_destroy destroys the devres associated with this PHY. -7. PM Runtime +PM Runtime +========== This subsystem is pm runtime enabled. So while creating the PHY, pm_runtime_enable of the phy device created by this subsystem is called and @@ -150,7 +174,8 @@ There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync, phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and phy_pm_runtime_forbid for performing PM operations. -8. PHY Mappings +PHY Mappings +============ In order to get reference to a PHY without help from DeviceTree, the framework offers lookups which can be compared to clkdev that allow clk structures to be @@ -158,12 +183,15 @@ bound to devices. A lookup can be made be made during runtime when a handle to the struct phy already exists. The framework offers the following API for registering and unregistering the -lookups. +lookups:: -int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id); -void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id); + int phy_create_lookup(struct phy *phy, const char *con_id, + const char *dev_id); + void phy_remove_lookup(struct phy *phy, const char *con_id, + const char *dev_id); -9. DeviceTree Binding +DeviceTree Binding +================== The documentation for PHY dt binding can be found @ Documentation/devicetree/bindings/phy/phy-bindings.txt -- 2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 23/29] ntb.txt: standardize document format |
| Message-ID | <tTnZq-Cs-89@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different format. Some doesn't even have titles! Change its representation to follow the adopted standard, using ReST markups for it to be parseable by Sphinx. This file is using some other markup notation (likely, markdown). Convert it to the adopted standard: - Adjust the header level markup; - Adjust identation for debugfs files and module parameters. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> --- Documentation/ntb.txt | 55 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/Documentation/ntb.txt b/Documentation/ntb.txt index 1d9bbabb6c79..e4771e5c2ad7 100644 --- a/Documentation/ntb.txt +++ b/Documentation/ntb.txt @@ -1,4 +1,6 @@ -# NTB Drivers +=========== +NTB Drivers +=========== NTB (Non-Transparent Bridge) is a type of PCI-Express bridge chip that connects the separate memory systems of two computers to the same PCI-Express fabric. @@ -10,7 +12,8 @@ fixed address. Doorbell registers provide a way for peers to send interrupt events. Memory windows allow translated read and write access to the peer memory. -## NTB Core Driver (ntb) +NTB Core Driver (ntb) +===================== The NTB core driver defines an api wrapping the common feature set, and allows clients interested in NTB features to discover NTB the devices supported by @@ -18,7 +21,8 @@ hardware drivers. The term "client" is used here to mean an upper layer component making use of the NTB api. The term "driver," or "hardware driver," is used here to mean a driver for a specific vendor and model of NTB hardware. -## NTB Client Drivers +NTB Client Drivers +================== NTB client drivers should register with the NTB core driver. After registering, the client probe and remove functions will be called appropriately @@ -26,7 +30,8 @@ as ntb hardware, or hardware drivers, are inserted and removed. The registration uses the Linux Device framework, so it should feel familiar to anyone who has written a pci driver. -### NTB Transport Client (ntb\_transport) and NTB Netdev (ntb\_netdev) +NTB Transport Client (ntb\_transport) and NTB Netdev (ntb\_netdev) +------------------------------------------------------------------ The primary client for NTB is the Transport client, used in tandem with NTB Netdev. These drivers function together to create a logical link to the peer, @@ -37,7 +42,8 @@ Transport queue pair. Network data is copied between socket buffers and the Transport queue pair buffer. The Transport client may be used for other things besides Netdev, however no other applications have yet been written. -### NTB Ping Pong Test Client (ntb\_pingpong) +NTB Ping Pong Test Client (ntb\_pingpong) +----------------------------------------- The Ping Pong test client serves as a demonstration to exercise the doorbell and scratchpad registers of NTB hardware, and as an example simple NTB client. @@ -64,7 +70,8 @@ Module Parameters: * dyndbg - It is suggested to specify dyndbg=+p when loading this module, and then to observe debugging output on the console. -### NTB Tool Test Client (ntb\_tool) +NTB Tool Test Client (ntb\_tool) +-------------------------------- The Tool test client serves for debugging, primarily, ntb hardware and drivers. The Tool provides access through debugfs for reading, setting, and clearing the @@ -74,48 +81,60 @@ The Tool does not currently have any module parameters. Debugfs Files: -* *debugfs*/ntb\_tool/*hw*/ - A directory in debugfs will be created for each +* *debugfs*/ntb\_tool/*hw*/ + A directory in debugfs will be created for each NTB device probed by the tool. This directory is shortened to *hw* below. -* *hw*/db - This file is used to read, set, and clear the local doorbell. Not +* *hw*/db + This file is used to read, set, and clear the local doorbell. Not all operations may be supported by all hardware. To read the doorbell, read the file. To set the doorbell, write `s` followed by the bits to set (eg: `echo 's 0x0101' > db`). To clear the doorbell, write `c` followed by the bits to clear. -* *hw*/mask - This file is used to read, set, and clear the local doorbell mask. +* *hw*/mask + This file is used to read, set, and clear the local doorbell mask. See *db* for details. -* *hw*/peer\_db - This file is used to read, set, and clear the peer doorbell. +* *hw*/peer\_db + This file is used to read, set, and clear the peer doorbell. See *db* for details. -* *hw*/peer\_mask - This file is used to read, set, and clear the peer doorbell +* *hw*/peer\_mask + This file is used to read, set, and clear the peer doorbell mask. See *db* for details. -* *hw*/spad - This file is used to read and write local scratchpads. To read +* *hw*/spad + This file is used to read and write local scratchpads. To read the values of all scratchpads, read the file. To write values, write a series of pairs of scratchpad number and value (eg: `echo '4 0x123 7 0xabc' > spad` # to set scratchpads `4` and `7` to `0x123` and `0xabc`, respectively). -* *hw*/peer\_spad - This file is used to read and write peer scratchpads. See +* *hw*/peer\_spad + This file is used to read and write peer scratchpads. See *spad* for details. -## NTB Hardware Drivers +NTB Hardware Drivers +==================== NTB hardware drivers should register devices with the NTB core driver. After registering, clients probe and remove functions will be called. -### NTB Intel Hardware Driver (ntb\_hw\_intel) +NTB Intel Hardware Driver (ntb\_hw\_intel) +------------------------------------------ The Intel hardware driver supports NTB on Xeon and Atom CPUs. Module Parameters: -* b2b\_mw\_idx - If the peer ntb is to be accessed via a memory window, then use +* b2b\_mw\_idx + If the peer ntb is to be accessed via a memory window, then use this memory window to access the peer ntb. A value of zero or positive starts from the first mw idx, and a negative value starts from the last mw idx. Both sides MUST set the same value here! The default value is `-1`. -* b2b\_mw\_share - If the peer ntb is to be accessed via a memory window, and if +* b2b\_mw\_share + If the peer ntb is to be accessed via a memory window, and if the memory window is large enough, still allow the client to use the second half of the memory window for address translation to the peer. -* xeon\_b2b\_usd\_bar2\_addr64 - If using B2B topology on Xeon hardware, use +* xeon\_b2b\_usd\_bar2\_addr64 + If using B2B topology on Xeon hardware, use this 64 bit address on the bus between the NTB devices for the window at BAR2, on the upstream side of the link. * xeon\_b2b\_usd\_bar4\_addr64 - See *xeon\_b2b\_bar2\_addr64*. -- 2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 24/29] numastat.txt: standardize document format |
| Message-ID | <tTnZq-Cs-83@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different format. Some doesn't even have titles! Change its representation to follow the adopted standard, using ReST markups for it to be parseable by Sphinx: - mark the document title; - mark the table as such. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> --- Documentation/numastat.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/numastat.txt b/Documentation/numastat.txt index 520327790d54..aaf1667489f8 100644 --- a/Documentation/numastat.txt +++ b/Documentation/numastat.txt @@ -1,10 +1,12 @@ - +=============================== Numa policy hit/miss statistics +=============================== /sys/devices/system/node/node*/numastat All units are pages. Hugepages have separate counters. +=============== ============================================================ numa_hit A process wanted to allocate memory from this node, and succeeded. @@ -20,6 +22,7 @@ other_node A process ran on this node and got memory from another node. interleave_hit Interleaving wanted to allocate from this node and succeeded. +=============== ============================================================ For easier reading you can use the numastat utility from the numactl package (http://oss.sgi.com/projects/libnuma/). Note that it only works -- 2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 03/29] IRQ-domain.txt: standardize document format |
| Message-ID | <tTnZq-Cs-91@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- use proper markups for titles;
- mark literal blocks as such;
- add blank lines where needed.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/IRQ-domain.txt | 69 +++++++++++++++++++++++++++++++-------------
1 file changed, 49 insertions(+), 20 deletions(-)
diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
index 1f246eb25ca5..4a1cd7645d85 100644
--- a/Documentation/IRQ-domain.txt
+++ b/Documentation/IRQ-domain.txt
@@ -1,4 +1,6 @@
-irq_domain interrupt number mapping library
+===============================================
+The irq_domain interrupt number mapping library
+===============================================
The current design of the Linux kernel uses a single large number
space where each separate IRQ source is assigned a different number.
@@ -36,7 +38,9 @@ irq_domain also implements translation from an abstract irq_fwspec
structure to hwirq numbers (Device Tree and ACPI GSI so far), and can
be easily extended to support other IRQ topology data sources.
-=== irq_domain usage ===
+irq_domain usage
+================
+
An interrupt controller driver creates and registers an irq_domain by
calling one of the irq_domain_add_*() functions (each mapping method
has a different allocator function, more on that later). The function
@@ -62,15 +66,21 @@ If the driver has the Linux IRQ number or the irq_data pointer, and
needs to know the associated hwirq number (such as in the irq_chip
callbacks) then it can be directly obtained from irq_data->hwirq.
-=== Types of irq_domain mappings ===
+Types of irq_domain mappings
+============================
+
There are several mechanisms available for reverse mapping from hwirq
to Linux irq, and each mechanism uses a different allocation function.
Which reverse map type should be used depends on the use case. Each
of the reverse map types are described below:
-==== Linear ====
-irq_domain_add_linear()
-irq_domain_create_linear()
+Linear
+------
+
+::
+
+ irq_domain_add_linear()
+ irq_domain_create_linear()
The linear reverse map maintains a fixed size table indexed by the
hwirq number. When a hwirq is mapped, an irq_desc is allocated for
@@ -89,9 +99,13 @@ accepts a more general abstraction 'struct fwnode_handle'.
The majority of drivers should use the linear map.
-==== Tree ====
-irq_domain_add_tree()
-irq_domain_create_tree()
+Tree
+----
+
+::
+
+ irq_domain_add_tree()
+ irq_domain_create_tree()
The irq_domain maintains a radix tree map from hwirq numbers to Linux
IRQs. When an hwirq is mapped, an irq_desc is allocated and the
@@ -109,8 +123,12 @@ accepts a more general abstraction 'struct fwnode_handle'.
Very few drivers should need this mapping.
-==== No Map ===-
-irq_domain_add_nomap()
+No Map
+------
+
+::
+
+ irq_domain_add_nomap()
The No Map mapping is to be used when the hwirq number is
programmable in the hardware. In this case it is best to program the
@@ -121,10 +139,14 @@ Linux IRQ number into the hardware.
Most drivers cannot use this mapping.
-==== Legacy ====
-irq_domain_add_simple()
-irq_domain_add_legacy()
-irq_domain_add_legacy_isa()
+Legacy
+------
+
+::
+
+ irq_domain_add_simple()
+ irq_domain_add_legacy()
+ irq_domain_add_legacy_isa()
The Legacy mapping is a special case for drivers that already have a
range of irq_descs allocated for the hwirqs. It is used when the
@@ -163,14 +185,17 @@ that the driver using the simple domain call irq_create_mapping()
before any irq_find_mapping() since the latter will actually work
for the static IRQ assignment case.
-==== Hierarchy IRQ domain ====
+Hierarchy IRQ domain
+--------------------
+
On some architectures, there may be multiple interrupt controllers
involved in delivering an interrupt from the device to the target CPU.
-Let's look at a typical interrupt delivering path on x86 platforms:
+Let's look at a typical interrupt delivering path on x86 platforms::
-Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU
+ Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU
There are three interrupt controllers involved:
+
1) IOAPIC controller
2) Interrupt remapping controller
3) Local APIC controller
@@ -180,7 +205,8 @@ hardware architecture, an irq_domain data structure is built for each
interrupt controller and those irq_domains are organized into hierarchy.
When building irq_domain hierarchy, the irq_domain near to the device is
child and the irq_domain near to CPU is parent. So a hierarchy structure
-as below will be built for the example above.
+as below will be built for the example above::
+
CPU Vector irq_domain (root irq_domain to manage CPU vectors)
^
|
@@ -190,6 +216,7 @@ as below will be built for the example above.
IOAPIC irq_domain (manage IOAPIC delivery entries/pins)
There are four major interfaces to use hierarchy irq_domain:
+
1) irq_domain_alloc_irqs(): allocate IRQ descriptors and interrupt
controller related resources to deliver these interrupts.
2) irq_domain_free_irqs(): free IRQ descriptors and interrupt controller
@@ -199,7 +226,8 @@ There are four major interfaces to use hierarchy irq_domain:
4) irq_domain_deactivate_irq(): deactivate interrupt controller hardware
to stop delivering the interrupt.
-Following changes are needed to support hierarchy irq_domain.
+Following changes are needed to support hierarchy irq_domain:
+
1) a new field 'parent' is added to struct irq_domain; it's used to
maintain irq_domain hierarchy information.
2) a new field 'parent_data' is added to struct irq_data; it's used to
@@ -223,6 +251,7 @@ software architecture.
For an interrupt controller driver to support hierarchy irq_domain, it
needs to:
+
1) Implement irq_domain_ops.alloc and irq_domain_ops.free
2) Optionally implement irq_domain_ops.activate and
irq_domain_ops.deactivate.
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:40 +0200 |
| Subject | [PATCH v2 12/29] kselftest.rst: do some adjustments after ReST conversion |
| Message-ID | <tTnZq-Cs-93@gated-at.bofh.it> |
| In reply to | #1668294 |
Do some minor adjustments after ReST conversion:
- On most documents, we use prepend a "$ " before
command line arguments;
- Prefer to use :: on the preceding line;
- Split a multi-paragraph description as such.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/dev-tools/kselftest.rst | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst
index b3861500c42d..ebd03d11d2c2 100644
--- a/Documentation/dev-tools/kselftest.rst
+++ b/Documentation/dev-tools/kselftest.rst
@@ -19,15 +19,15 @@ Running the selftests (hotplug tests are run in limited mode)
To build the tests::
- make -C tools/testing/selftests
+ $ make -C tools/testing/selftests
To run the tests::
- make -C tools/testing/selftests run_tests
+ $ make -C tools/testing/selftests run_tests
To build and run the tests with a single command, use::
- make kselftest
+ $ make kselftest
Note that some tests will require root privileges.
@@ -40,11 +40,11 @@ single test to run, or a list of tests to run.
To run only tests targeted for a single subsystem::
- make -C tools/testing/selftests TARGETS=ptrace run_tests
+ $ make -C tools/testing/selftests TARGETS=ptrace run_tests
You can specify multiple tests to build and run::
- make TARGETS="size timers" kselftest
+ $ make TARGETS="size timers" kselftest
See the top-level tools/testing/selftests/Makefile for the list of all
possible targets.
@@ -55,11 +55,11 @@ Running the full range hotplug selftests
To build the hotplug tests::
- make -C tools/testing/selftests hotplug
+ $ make -C tools/testing/selftests hotplug
To run the hotplug tests::
- make -C tools/testing/selftests run_hotplug
+ $ make -C tools/testing/selftests run_hotplug
Note that some tests will require root privileges.
@@ -73,13 +73,13 @@ location.
To install selftests in default location::
- cd tools/testing/selftests
- ./kselftest_install.sh
+ $ cd tools/testing/selftests
+ $ ./kselftest_install.sh
To install selftests in a user specified location::
- cd tools/testing/selftests
- ./kselftest_install.sh install_dir
+ $ cd tools/testing/selftests
+ $ ./kselftest_install.sh install_dir
Running installed selftests
===========================
@@ -88,12 +88,10 @@ Kselftest install as well as the Kselftest tarball provide a script
named "run_kselftest.sh" to run the tests.
You can simply do the following to run the installed Kselftests. Please
-note some tests will require root privileges.
+note some tests will require root privileges::
-::
-
- cd kselftest
- ./run_kselftest.sh
+ $ cd kselftest
+ $ ./run_kselftest.sh
Contributing new tests
======================
@@ -114,8 +112,10 @@ Contributing new tests (details)
* Use TEST_GEN_XXX if such binaries or files are generated during
compiling.
+
TEST_PROGS, TEST_GEN_PROGS mean it is the excutable tested by
default.
+
TEST_PROGS_EXTENDED, TEST_GEN_PROGS_EXTENDED mean it is the
executable which is not tested by default.
TEST_FILES, TEST_GEN_FILES mean it is the file which is used by
--
2.9.4
[toc] | [prev] | [next] | [standalone]
| From | Mauro Carvalho Chehab <mchehab@s-opensource.com> |
|---|---|
| Date | 2017-06-17 17:50 +0200 |
| Subject | [PATCH v2 14/29] lockup-watchdogs.txt: standardize document format |
| Message-ID | <tTo93-Gz-5@gated-at.bofh.it> |
| In reply to | #1668294 |
Each text file under Documentation follows a different format. Some doesn't even have titles! Change its representation to follow the adopted standard, using ReST markups for it to be parseable by Sphinx. This file is almost at ReST format. Just one title needs to be adjusted, in order to follow the standard. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> --- Documentation/lockup-watchdogs.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/lockup-watchdogs.txt b/Documentation/lockup-watchdogs.txt index c8b8378513d6..290840c160af 100644 --- a/Documentation/lockup-watchdogs.txt +++ b/Documentation/lockup-watchdogs.txt @@ -30,7 +30,8 @@ timeout is set through the confusingly named "kernel.panic" sysctl), to cause the system to reboot automatically after a specified amount of time. -=== Implementation === +Implementation +============== The soft and hard lockup detectors are built on top of the hrtimer and perf subsystems, respectively. A direct consequence of this is that, -- 2.9.4
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web