* Re: [PATCH v10 0/5] Kernel parameter parser cleanup/enhancement
From: Andy Shevchenko @ 2018-06-05 17:05 UTC (permalink / raw)
To: Michal Suchanek
Cc: Jonathan Corbet, Arnd Bergmann, Frederic Weisbecker, Ingo Molnar,
Aaron Wu, Tony Luck, Andrew Morton, Thomas Gleixner,
Steven Rostedt,, Laura Abbott, Dominik Brodowski, Alexey Dobriyan,
Tom Lendacky, Jeffrey Hugo, Baoquan He, Ilya Matveychikov,
Linux Documentation List, Linux Kernel Mailing List
In-Reply-To: <cover.1528215659.git.msuchanek@suse.de>
On Tue, Jun 5, 2018 at 7:43 PM, Michal Suchanek <msuchanek@suse.de> wrote:
> Hello,
>
> due to work on the fadump_extra_args I looked at the kernel parameter parser
> and found its grammar rather curious.
>
> It supports double quotes but not any other quoting characters so double quotes
> cannot be quoted. What's more, the quotes can be anywhere in the parameter
> name or value and are interpteted but are removed only from start and end of
> the parameter value.
>
> These are the patches not specific to fadump which somewhat straighten the
> qouting grammar to make it on par with common shell interpreters.
I didn't notice any use of string_unescape_*() functionality. So, your
patch is kinda very specific to some narrow subset of escaping and
unescaping stuff.
Thus, it's still not on par with shell, right?
>
> Specifically double and single quotes can be used for quoting as well as
> backslashes with the usual shell semantic. All quoting characters are removed
> while the parameters are parsed.
>
> Previous versions (including the fadump part) can be found here:
>
> https://www.mail-archive.com/linuxppc-dev@lists.ozlabs.org/msg126148.html
> https://www.mail-archive.com/linuxppc-dev@lists.ozlabs.org/msg123639.html
>
> Thanks
>
> Michal
>
> Michal Suchanek (5):
> lib/cmdline.c: Add backslash support to kernel commandline parsing.
> Documentation/admin-guide: backslash support in kernel arguments.
> init/main.c: simplify repair_env_string.
> lib/cmdline.c: Implement single quotes in commandline argument
> parsing.
> Documentation/admin-guide: single quotes in kernel arguments.
>
> Documentation/admin-guide/kernel-parameters.rst | 5 +-
> init/main.c | 13 ++---
> lib/cmdline.c | 63 +++++++++++++++----------
> 3 files changed, 46 insertions(+), 35 deletions(-)
>
> --
> 2.13.6
>
--
With Best Regards,
Andy Shevchenko
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v10 0/5] Kernel parameter parser cleanup/enhancement
From: Michal Suchánek @ 2018-06-05 17:25 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Corbet, Arnd Bergmann, Frederic Weisbecker, Ingo Molnar,
Aaron Wu, Tony Luck, Andrew Morton, Thomas Gleixner,
Steven Rostedt,, Laura Abbott, Dominik Brodowski, Alexey Dobriyan,
Tom Lendacky, Jeffrey Hugo, Baoquan He, Ilya Matveychikov,
Linux Documentation List, Linux Kernel Mailing List
In-Reply-To: <CAHp75VdG4Vp2_6LMLv--kwiMkXO4mdc1DUgRQLBCtp2OoEmAZQ@mail.gmail.com>
On Tue, 5 Jun 2018 20:05:50 +0300
Andy Shevchenko <andy.shevchenko@gmail.com> wrote:
> On Tue, Jun 5, 2018 at 7:43 PM, Michal Suchanek <msuchanek@suse.de>
> wrote:
> > Hello,
> >
> > due to work on the fadump_extra_args I looked at the kernel
> > parameter parser and found its grammar rather curious.
> >
> > It supports double quotes but not any other quoting characters so
> > double quotes cannot be quoted. What's more, the quotes can be
> > anywhere in the parameter name or value and are interpteted but are
> > removed only from start and end of the parameter value.
> >
> > These are the patches not specific to fadump which somewhat
> > straighten the qouting grammar to make it on par with common shell
> > interpreters.
>
> I didn't notice any use of string_unescape_*() functionality. So, your
> patch is kinda very specific to some narrow subset of escaping and
> unescaping stuff.
It does what it says. It cannot use string_unescape because it needs to
determine the boundaries of quoted strings.
> Thus, it's still not on par with shell, right?
It does not interpret special character sequences other than quoting.
The feature would not be hard to add but I do not see the need.
Unfortunately, the existing string_unescape is totally not fitting to
be integrated into the parser for the purpose.
Thanks
Michal
>
> >
> > Specifically double and single quotes can be used for quoting as
> > well as backslashes with the usual shell semantic. All quoting
> > characters are removed while the parameters are parsed.
> >
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] docs: atomic_ops: atomic_set is a write (not read) operation
From: Jonathan Neuschäfer @ 2018-06-05 19:43 UTC (permalink / raw)
To: linux-doc
Cc: Jonathan Neuschäfer, Jonathan Corbet, Paul E. McKenney,
linux-kernel
Describe it as such.
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
---
Documentation/core-api/atomic_ops.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/core-api/atomic_ops.rst b/Documentation/core-api/atomic_ops.rst
index 2e7165f86f55..724583453e1f 100644
--- a/Documentation/core-api/atomic_ops.rst
+++ b/Documentation/core-api/atomic_ops.rst
@@ -29,7 +29,7 @@ updated by one CPU, local_t is probably more appropriate. Please see
local_t.
The first operations to implement for atomic_t's are the initializers and
-plain reads. ::
+plain writes. ::
#define ATOMIC_INIT(i) { (i) }
#define atomic_set(v, i) ((v)->counter = (i))
--
2.17.1
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH RESEND] Documentation: filesystems: update filesystem locking documentation
From: Sean Anderson @ 2018-06-05 19:46 UTC (permalink / raw)
To: Al Viro; +Cc: corbet, linux-doc, linux-fsdevel, Matthew Wilcox, Jeff Layton
In-Reply-To: <20180526034116.GO30522@ZenIV.linux.org.uk>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
> Your mission, should you choose to accept it, shall be to locate
> the old sig regarding the usual reaction to use of
> Quoted-Printable...
>
> IOW, fix your mail setup. Applied, but.
Not sure what you mean by "Quoted-Printable"... Is PGP/MIME the
incorrect way to send messages? I've switched to the "traditional"
option for this one, and I've enabled "mail.strictly_mime" in my
settings. Let me know if this fixes things for you.
-----BEGIN PGP SIGNATURE-----
iQGTBAEBCgB9FiEEkGEdW86NSNID6GAoPuiP7LShEG4FAlsW6JxfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDkw
NjExRDVCQ0U4RDQ4RDIwM0U4NjAyODNFRTg4RkVDQjRBMTEwNkUACgkQPuiP7LSh
EG6W6wf+MS92RRCzMWTlvdUQZhIdMMzLBwlU3D4Y6eiEWzRz1o7IJxmW+0hmUCws
xo2uC1iUifRSrulYMHOmB5kCRIjL5grpadiJRlJzO1/EKkV4MUA4LlVqh9Z2sXae
o8bxC42/NF+7XKrABBuB+xzi51XGYXG4TevoB/FIMzQIHtnQ0EOkQomAxClm31gx
HbV/GKraYYseINuQ3m1hOdKD+Ior4laySpqbPZLx+8wumIzArlcsXJiw3BpF194W
Blmt5mDNybRPNObEk6huRXsbxoFq95Cu1w8UzFCp2fI6XOZlS9Z+ZrpKixpzFJ2p
lkEPDgrxEeWIA2nxuIsFGwzPnibrpA==
=4mdc
-----END PGP SIGNATURE-----
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* doc: Italian translations
From: Federico Vaga @ 2018-06-05 22:48 UTC (permalink / raw)
To: Jonathan Corbet
Cc: linux-doc, linux-kernel, Alessia Mantegazza, Federico Vaga
Ciao Jon,
here again the doc-guide translated in Italian and the Italian
skeleton. This set of patches is a bit different than the privious
one. Main differences:
- I moved out translations from the main index
- I fixed the Italian translation for the kernel-doc.rst file
because I noticed that you restructured it and simplify
(my fault I did not check it before)
- I added my self as MAINTAINER of the Italian translation effort
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 2/6] doc:sphinx: fix parse-header description
From: Federico Vaga @ 2018-06-05 22:48 UTC (permalink / raw)
To: Jonathan Corbet
Cc: linux-doc, linux-kernel, Alessia Mantegazza, Federico Vaga
In-Reply-To: <20180605224903.9483-1-federico.vaga@vaga.pv.it>
The description speaks about the option ``--man`` but it
does not exist. Instead, there is the option ``--usage``
$ ./Documentation/sphinx/parse-headers.pl --man
Unknown option: man
Usage:
parse_headers.pl [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>]
Where <options> can be: --debug, --help or --man.
Signed-off-by: Federico Vaga <federico.vaga@vaga.pv.it>
---
| 2 +-
| 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--git a/Documentation/doc-guide/parse-headers.rst b/Documentation/doc-guide/parse-headers.rst
index 684490c68acb..24cfaa15dd81 100644
--- a/Documentation/doc-guide/parse-headers.rst
+++ b/Documentation/doc-guide/parse-headers.rst
@@ -32,7 +32,7 @@ SYNOPSIS
\ **parse_headers.pl**\ [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>]
-Where <options> can be: --debug, --help or --man.
+Where <options> can be: --debug, --help or --usage.
OPTIONS
--git a/Documentation/sphinx/parse-headers.pl b/Documentation/sphinx/parse-headers.pl
index d410f47567e9..c518050ffc3f 100755
--- a/Documentation/sphinx/parse-headers.pl
+++ b/Documentation/sphinx/parse-headers.pl
@@ -344,7 +344,7 @@ enums and defines and create cross-references to a Sphinx book.
B<parse_headers.pl> [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>]
-Where <options> can be: --debug, --help or --man.
+Where <options> can be: --debug, --help or --usage.
=head1 OPTIONS
--
2.14.4
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 3/6] doc: move away translations from top-level index
From: Federico Vaga @ 2018-06-05 22:49 UTC (permalink / raw)
To: Jonathan Corbet
Cc: linux-doc, linux-kernel, Alessia Mantegazza, Federico Vaga
In-Reply-To: <20180605224903.9483-1-federico.vaga@vaga.pv.it>
In translations/ we have now a dedicated index.rst where we add/remove
references to translations. Translations are in English alphabetical
order.
Signed-off-by: Federico Vaga <federico.vaga@vaga.pv.it>
---
Documentation/index.rst | 24 ++++--------------------
Documentation/translations/index.rst | 12 ++++++++++++
2 files changed, 16 insertions(+), 20 deletions(-)
create mode 100644 Documentation/translations/index.rst
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 3b99ab931d41..f7ab4d6a281e 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -101,29 +101,13 @@ implementation.
sh/index
-Korean translations
--------------------
+Translations
+------------
.. toctree::
- :maxdepth: 1
-
- translations/ko_KR/index
-
-Chinese translations
---------------------
-
-.. toctree::
- :maxdepth: 1
-
- translations/zh_CN/index
-
-Japanese translations
----------------------
-
-.. toctree::
- :maxdepth: 1
+ :maxdepth: 2
- translations/ja_JP/index
+ translations/index
Indices and tables
==================
diff --git a/Documentation/translations/index.rst b/Documentation/translations/index.rst
new file mode 100644
index 000000000000..4969c58920ef
--- /dev/null
+++ b/Documentation/translations/index.rst
@@ -0,0 +1,12 @@
+.. _translations:
+
+============
+Translations
+============
+
+.. toctree::
+ :maxdepth: 1
+
+ zh_CN/index
+ ko_KR/index
+ ja_JP/index
--
2.14.4
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 5/6] doc: add Italian language skeleton
From: Federico Vaga @ 2018-06-05 22:49 UTC (permalink / raw)
To: Jonathan Corbet
Cc: linux-doc, linux-kernel, Alessia Mantegazza, Federico Vaga
In-Reply-To: <20180605224903.9483-1-federico.vaga@vaga.pv.it>
Signed-off-by: Federico Vaga <federico.vaga@vaga.pv.it>
---
Documentation/translations/index.rst | 1 +
.../translations/it_IT/disclaimer-ita.rst | 13 +++
Documentation/translations/it_IT/index.rst | 112 +++++++++++++++++++++
MAINTAINERS | 6 ++
4 files changed, 132 insertions(+)
create mode 100644 Documentation/translations/it_IT/disclaimer-ita.rst
create mode 100644 Documentation/translations/it_IT/index.rst
diff --git a/Documentation/translations/index.rst b/Documentation/translations/index.rst
index 4969c58920ef..7f77c52d33aa 100644
--- a/Documentation/translations/index.rst
+++ b/Documentation/translations/index.rst
@@ -8,5 +8,6 @@ Translations
:maxdepth: 1
zh_CN/index
+ it_IT/index
ko_KR/index
ja_JP/index
diff --git a/Documentation/translations/it_IT/disclaimer-ita.rst b/Documentation/translations/it_IT/disclaimer-ita.rst
new file mode 100644
index 000000000000..d68e52de6a5d
--- /dev/null
+++ b/Documentation/translations/it_IT/disclaimer-ita.rst
@@ -0,0 +1,13 @@
+:orphan:
+
+.. note::
+ This document is maintained by Federico Vaga <federico.vaga@vaga.pv.it>.
+ If you find any difference between this document and the original file or a
+ problem with the translation, please contact the maintainer of this file.
+ Following people helped to translate or review:
+ Alessia Mantegazza <amantegazza@vaga.pv.it>
+
+.. warning::
+ The purpose of this file is to be easier to read and understand for Italian
+ speakers and is not intended as a fork. So, if you have any comments or
+ updates for this file please try to update the original English file first.
diff --git a/Documentation/translations/it_IT/index.rst b/Documentation/translations/it_IT/index.rst
new file mode 100644
index 000000000000..7613a9f9e6f9
--- /dev/null
+++ b/Documentation/translations/it_IT/index.rst
@@ -0,0 +1,112 @@
+.. _it_linux_doc:
+
+===================
+Traduzione italiana
+===================
+
+L'obiettivo di questa traduzione è di rendere più facile la lettura e
+la comprensione per chi preferisce leggere in lingua italiana.
+Tenete presente che la documentazione di riferimento rimane comunque
+quella in lingua inglese: :ref:`linux_doc`
+
+Questa traduzione cerca di essere il più fedele possibile all'originale ma
+è ovvio che alcune frasi vadano trasformate: non aspettatevi una traduzione
+letterale. Quando possibile, si eviteranno gli inglesismi ed al loro posto
+verranno utilizzate le corrispettive parole italiane.
+
+Se notate che la traduzione non è più aggiornata potete contattare
+direttamente il manutentore della traduzione italiana.
+
+Se notate che la documentazione contiene errori o dimenticanze, allora
+verificate la documentazione di riferimento in lingua inglese. Se il problema
+è presente anche nella documentazione di riferimento, contattate il suo
+manutentore. Se avete problemi a scrivere in inglese, potete comunque
+riportare il problema al manutentore della traduzione italiana.
+
+Manutentore della traduzione italiana: Federico Vaga <federico.vaga@vaga.pv.it>
+
+La documentazione del kernel Linux
+==================================
+
+Questo è il livello principale della documentazione del kernel in
+lingua italiana. La traduzione è incompleta, noterete degli avvisi
+che vi segnaleranno la mancanza di una traduzione o di un gruppo di
+traduzioni.
+
+Più in generale, la documentazione, come il kernel stesso, sono in
+costante sviluppo; particolarmente vero in quanto stiamo lavorando
+alla riorganizzazione della documentazione in modo più coerente.
+I miglioramenti alla documentazione sono sempre i benvenuti; per cui,
+se vuoi aiutare, iscriviti alla lista di discussione linux-doc presso
+vger.kernel.org.
+
+Documentazione sulla licenza dei sorgenti
+-----------------------------------------
+
+I seguenti documenti descrivono la licenza usata nei sorgenti del kernel Linux
+(GPLv2), come licenziare i singoli file; inoltre troverete i riferimenti al
+testo integrale della licenza.
+
+.. warning::
+
+ TODO ancora da tradurre
+
+Documentazione per gli utenti
+-----------------------------
+
+I seguenti manuali sono scritti per gli *utenti* del kernel - ovvero,
+coloro che cercano di farlo funzionare in modo ottimale su un dato sistema
+
+.. warning::
+
+ TODO ancora da tradurre
+
+Documentazione per gli sviluppatori di applicazioni
+---------------------------------------------------
+
+Il manuale delle API verso lo spazio utente è una collezione di documenti
+che descrivono le interfacce del kernel viste dagli sviluppatori
+di applicazioni.
+
+.. warning::
+
+ TODO ancora da tradurre
+
+
+Introduzione allo sviluppo del kernel
+-------------------------------------
+
+Questi manuali contengono informazioni su come contribuire allo sviluppo
+del kernel.
+Attorno al kernel Linux gira una comunità molto grande con migliaia di
+sviluppatori che contribuiscono ogni anno. Come in ogni grande comunità,
+sapere come le cose vengono fatte renderà il processo di integrazione delle
+vostre modifiche molto più semplice
+
+.. warning::
+
+ TODO ancora da tradurre
+
+Documentazione della API del kernel
+-----------------------------------
+
+Questi manuali forniscono dettagli su come funzionano i sottosistemi del
+kernel dal punto di vista degli sviluppatori del kernel. Molte delle
+informazioni contenute in questi manuali sono prese direttamente dai
+file sorgenti, informazioni aggiuntive vengono aggiunte solo se necessarie
+(o almeno ci proviamo — probabilmente *non* tutto quello che è davvero
+necessario).
+
+.. warning::
+
+ TODO ancora da tradurre
+
+Documentazione specifica per architettura
+-----------------------------------------
+
+Questi manuali forniscono dettagli di programmazione per le diverse
+implementazioni d'architettura.
+
+.. warning::
+
+ TODO ancora da tradurre
diff --git a/MAINTAINERS b/MAINTAINERS
index ca4afd68530c..0ee4ba5b4ca1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4367,6 +4367,12 @@ X: Documentation/spi
X: Documentation/media
T: git git://git.lwn.net/linux.git docs-next
+DOCUMENTATION/ITALIAN
+M: Federico Vaga <federico.vaga@vaga.pv.it>
+L: linux-doc@vger.kernel.org
+S: Maintained
+F: Documentation/translations/it_IT
+
DONGWOON DW9714 LENS VOICE COIL DRIVER
M: Sakari Ailus <sakari.ailus@linux.intel.com>
L: linux-media@vger.kernel.org
--
2.14.4
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 6/6] doc:it_IT: translation for doc-guide
From: Federico Vaga @ 2018-06-05 22:49 UTC (permalink / raw)
To: Jonathan Corbet
Cc: linux-doc, linux-kernel, Alessia Mantegazza, Federico Vaga
In-Reply-To: <20180605224903.9483-1-federico.vaga@vaga.pv.it>
This is the complete translation of 'doc-guide' in Italian.
Please note that code comments will stay in English because
thats the language that everyone should use to write comments.
External files (svg, dot) are taken from Documentation/doc-guide
instead of copying them into the Italian translation.
Signed-off-by: Federico Vaga <federico.vaga@vaga.pv.it>
Signed-off-by: Alessia Mantegazza <amantegazza@vaga.pv.it>
---
.../translations/it_IT/doc-guide/index.rst | 24 +
.../translations/it_IT/doc-guide/kernel-doc.rst | 554 +++++++++++++++++++++
| 196 ++++++++
.../translations/it_IT/doc-guide/sphinx.rst | 457 +++++++++++++++++
Documentation/translations/it_IT/index.rst | 5 +
5 files changed, 1236 insertions(+)
create mode 100644 Documentation/translations/it_IT/doc-guide/index.rst
create mode 100644 Documentation/translations/it_IT/doc-guide/kernel-doc.rst
create mode 100644 Documentation/translations/it_IT/doc-guide/parse-headers.rst
create mode 100644 Documentation/translations/it_IT/doc-guide/sphinx.rst
diff --git a/Documentation/translations/it_IT/doc-guide/index.rst b/Documentation/translations/it_IT/doc-guide/index.rst
new file mode 100644
index 000000000000..7a6562b547ee
--- /dev/null
+++ b/Documentation/translations/it_IT/doc-guide/index.rst
@@ -0,0 +1,24 @@
+.. include:: ../disclaimer-ita.rst
+
+.. note:: Per leggere la documentazione originale in inglese:
+ :ref:`Documentation/doc-guide/index.rst <doc_guide>`
+
+.. _it_doc_guide:
+
+==========================================
+Come scrivere la documentazione del kernel
+==========================================
+
+.. toctree::
+ :maxdepth: 1
+
+ sphinx.rst
+ kernel-doc.rst
+ parse-headers.rst
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
diff --git a/Documentation/translations/it_IT/doc-guide/kernel-doc.rst b/Documentation/translations/it_IT/doc-guide/kernel-doc.rst
new file mode 100644
index 000000000000..2bf1c1e2f394
--- /dev/null
+++ b/Documentation/translations/it_IT/doc-guide/kernel-doc.rst
@@ -0,0 +1,554 @@
+.. include:: ../disclaimer-ita.rst
+
+.. note:: Per leggere la documentazione originale in inglese:
+ :ref:`Documentation/doc-guide/index.rst <doc_guide>`
+
+.. _it_kernel_doc:
+
+Scrivere i commenti in kernel-doc
+=================================
+
+Nei file sorgenti del kernel Linux potrete trovare commenti di documentazione
+strutturanti secondo il formato kernel-doc. Essi possono descrivere funzioni,
+tipi di dati, e l'architettura del codice.
+
+.. note:: Il formato kernel-doc può sembrare simile a gtk-doc o Doxygen ma
+ in realtà è molto differente per ragioni storiche. I sorgenti del kernel
+ contengono decine di migliaia di commenti kernel-doc. Siete pregati
+ d'attenervi allo stile qui descritto.
+
+La struttura kernel-doc è estratta a partire dai commenti; da questi viene
+generato il `dominio Sphinx per il C`_ con un'adeguata descrizione per le
+funzioni ed i tipi di dato con i loro relativi collegamenti. Le descrizioni
+vengono filtrare per cercare i riferimenti ed i marcatori.
+
+Vedere di seguito per maggiori dettagli.
+
+.. _`dominio Sphinx per il C`: http://www.sphinx-doc.org/en/stable/domains.html
+
+Tutte le funzioni esportate verso i moduli esterni utilizzando
+``EXPORT_SYMBOL`` o ``EXPORT_SYMBOL_GPL`` dovrebbero avere un commento
+kernel-doc. Quando l'intenzione è di utilizzarle nei moduli, anche le funzioni
+e le strutture dati nei file d'intestazione dovrebbero avere dei commenti
+kernel-doc.
+
+È considerata una buona pratica quella di fornire una documentazione formattata
+secondo kernel-doc per le funzioni che sono visibili da altri file del kernel
+(ovvero, che non siano dichiarate utilizzando ``static``). Raccomandiamo,
+inoltre, di fornire una documentazione kernel-doc anche per procedure private
+(ovvero, dichiarate "static") al fine di fornire una struttura più coerente
+dei sorgenti. Quest'ultima raccomandazione ha una priorità più bassa ed è a
+discrezione dal manutentore (MAINTAINER) del file sorgente.
+
+
+
+Sicuramente la documentazione formattata con kernel-doc è necessaria per
+le funzioni che sono esportate verso i moduli esterni utilizzando
+``EXPORT_SYMBOL`` o ``EXPORT_SYMBOL_GPL``.
+
+Cerchiamo anche di fornire una documentazione formattata secondo kernel-doc
+per le funzioni che sono visibili da altri file del kernel (ovvero, che non
+siano dichiarate utilizzando "static")
+
+Raccomandiamo, inoltre, di fornire una documentazione formattata con kernel-doc
+anche per procedure private (ovvero, dichiarate "static") al fine di fornire
+una struttura più coerente dei sorgenti. Questa raccomandazione ha una priorità
+più bassa ed è a discrezione dal manutentore (MAINTAINER) del file sorgente.
+
+Le strutture dati visibili nei file di intestazione dovrebbero essere anch'esse
+documentate utilizzando commenti formattati con kernel-doc.
+
+Come formattare i commenti kernel-doc
+-------------------------------------
+
+I commenti kernel-doc iniziano con il marcatore ``/**``. Il programma
+``kernel-doc`` estrarrà i commenti marchiati in questo modo. Il resto
+del commento è formattato come un normale commento multilinea, ovvero
+con un asterisco all'inizio d'ogni riga e che si conclude con ``*/``
+su una riga separata.
+
+I commenti kernel-doc di funzioni e tipi dovrebbero essere posizionati
+appena sopra la funzione od il tipo che descrivono. Questo allo scopo di
+aumentare la probabilità che chi cambia il codice si ricordi di aggiornare
+anche la documentazione. I commenti kernel-doc di tipo più generale possono
+essere posizionati ovunque nel file.
+
+Al fine di verificare che i commenti siano formattati correttamente, potete
+eseguire il programma ``kernel-doc`` con un livello di verbosità alto e senza
+che questo produca alcuna documentazione. Per esempio::
+
+ scripts/kernel-doc -v -none drivers/foo/bar.c
+
+Il formato della documentazione è verificato della procedura di generazione
+del kernel quando viene richiesto di effettuare dei controlli extra con GCC::
+
+ make W=n
+
+Documentare le funzioni
+------------------------
+
+Generalmente il formato di un commento kernel-doc per funzioni e
+macro simil-funzioni è il seguente::
+
+ /**
+ * function_name() - Brief description of function.
+ * @arg1: Describe the first argument.
+ * @arg2: Describe the second argument.
+ * One can provide multiple line descriptions
+ * for arguments.
+ *
+ * A longer description, with more discussion of the function function_name()
+ * that might be useful to those using or modifying it. Begins with an
+ * empty comment line, and may include additional embedded empty
+ * comment lines.
+ *
+ * The longer description may have multiple paragraphs.
+ *
+ * Context: Describes whether the function can sleep, what locks it takes,
+ * releases, or expects to be held. It can extend over multiple
+ * lines.
+ * Return: Describe the return value of foobar.
+ *
+ * The return value description can also have multiple paragraphs, and should
+ * be placed at the end of the comment block.
+ */
+
+La descrizione introduttiva (*brief description*) che segue il nome della
+funzione può continuare su righe successive e termina con la descrizione di
+un argomento, una linea di commento vuota, oppure la fine del commento.
+
+Parametri delle funzioni
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Ogni argomento di una funzione dovrebbe essere descritto in ordine, subito
+dopo la descrizione introduttiva. Non lasciare righe vuote né fra la
+descrizione introduttiva e quella degli argomenti, né fra gli argomenti.
+
+Ogni ``@argument:`` può estendersi su più righe.
+
+.. note::
+
+ Se la descrizione di ``@argument:`` si estende su più righe,
+ la continuazione dovrebbe iniziare alla stessa colonna della riga
+ precedente::
+
+ * @argument: some long description
+ * that continues on next lines
+
+ or::
+
+ * @argument:
+ * some long description
+ * that continues on next lines
+
+Se una funzione ha un numero variabile di argomento, la sua descrizione
+dovrebbe essere scritta con la notazione kernel-doc::
+
+ * @...: description
+
+Contesto delle funzioni
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Il contesto in cui le funzioni vengono chiamate viene descritto in una
+sezione chiamata ``Context``. Questo dovrebbe informare sulla possibilità
+che una funzione dorma (*sleep*) o che possa essere chiamata in un contesto
+d'interruzione, così come i *lock* che prende, rilascia e che si aspetta che
+vengano presi dal chiamante.
+
+Esempi::
+
+ * Context: Any context.
+ * Context: Any context. Takes and releases the RCU lock.
+ * Context: Any context. Expects <lock> to be held by caller.
+ * Context: Process context. May sleep if @gfp flags permit.
+ * Context: Process context. Takes and releases <mutex>.
+ * Context: Softirq or process context. Takes and releases <lock>, BH-safe.
+ * Context: Interrupt context.
+
+Valore di ritorno
+~~~~~~~~~~~~~~~~~
+
+Il valore di ritorno, se c'è, viene descritto in una sezione dedicata di nome
+``Return``.
+
+.. note::
+
+ #) La descrizione multiriga non riconosce il termine d'una riga, per cui
+ se provate a formattare bene il vostro testo come nel seguente esempio::
+
+ * Return:
+ * 0 - OK
+ * -EINVAL - invalid argument
+ * -ENOMEM - out of memory
+
+ le righe verranno unite e il risultato sarà::
+
+ Return: 0 - OK -EINVAL - invalid argument -ENOMEM - out of memory
+
+ Quindi, se volete che le righe vengano effettivamente generate, dovete
+ utilizzare una lista ReST, ad esempio::
+
+ * Return:
+ * * 0 - OK to runtime suspend the device
+ * * -EBUSY - Device should not be runtime suspended
+
+ #) Se il vostro testo ha delle righe che iniziano con una frase seguita dai
+ due punti, allora ognuna di queste frasi verrà considerata come il nome
+ di una nuova sezione, e probabilmente non produrrà gli effetti desiderati.
+
+Documentare strutture, unioni ed enumerazioni
+---------------------------------------------
+
+Generalmente il formato di un commento kernel-doc per struct, union ed enum è::
+
+ /**
+ * struct struct_name - Brief description.
+ * @member1: Description of member1.
+ * @member2: Description of member2.
+ * One can provide multiple line descriptions
+ * for members.
+ *
+ * Description of the structure.
+ */
+
+Nell'esempio qui sopra, potete sostituire ``struct`` con ``union`` o ``enum``
+per descrivere unioni ed enumerati. ``member`` viene usato per indicare i
+membri di strutture ed unioni, ma anche i valori di un tipo enumerato.
+
+La descrizione introduttiva (*brief description*) che segue il nome della
+funzione può continuare su righe successive e termina con la descrizione di
+un argomento, una linea di commento vuota, oppure la fine del commento.
+
+Membri
+~~~~~~
+
+I membri di strutture, unioni ed enumerati devo essere documentati come i
+parametri delle funzioni; seguono la descrizione introduttiva e possono
+estendersi su più righe.
+
+All'interno d'una struttura o d'un unione, potete utilizzare le etichette
+``private:`` e ``public:``. I campi che sono nell'area ``private:`` non
+verranno inclusi nella documentazione finale.
+
+Le etichette ``private:`` e ``public:`` devono essere messe subito dopo
+il marcatore di un commento ``/*``. Opzionalmente, possono includere commenti
+fra ``:`` e il marcatore di fine commento ``*/``.
+
+Esempio::
+
+ /**
+ * struct my_struct - short description
+ * @a: first member
+ * @b: second member
+ * @d: fourth member
+ *
+ * Longer description
+ */
+ struct my_struct {
+ int a;
+ int b;
+ /* private: internal use only */
+ int c;
+ /* public: the next one is public */
+ int d;
+ };
+
+Strutture ed unioni annidate
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+È possibile documentare strutture ed unioni annidate, ad esempio::
+
+ /**
+ * struct nested_foobar - a struct with nested unions and structs
+ * @memb1: first member of anonymous union/anonymous struct
+ * @memb2: second member of anonymous union/anonymous struct
+ * @memb3: third member of anonymous union/anonymous struct
+ * @memb4: fourth member of anonymous union/anonymous struct
+ * @bar: non-anonymous union
+ * @bar.st1: struct st1 inside @bar
+ * @bar.st2: struct st2 inside @bar
+ * @bar.st1.memb1: first member of struct st1 on union bar
+ * @bar.st1.memb2: second member of struct st1 on union bar
+ * @bar.st2.memb1: first member of struct st2 on union bar
+ * @bar.st2.memb2: second member of struct st2 on union bar
+ */
+ struct nested_foobar {
+ /* Anonymous union/struct*/
+ union {
+ struct {
+ int memb1;
+ int memb2;
+ }
+ struct {
+ void *memb3;
+ int memb4;
+ }
+ }
+ union {
+ struct {
+ int memb1;
+ int memb2;
+ } st1;
+ struct {
+ void *memb1;
+ int memb2;
+ } st2;
+ } bar;
+ };
+
+.. note::
+
+ #) Quando documentate una struttura od unione annidata, ad esempio
+ di nome ``foo``, il suo campo ``bar`` dev'essere documentato
+ usando ``@foo.bar:``
+ #) Quando la struttura od unione annidata è anonima, il suo campo
+ ``bar`` dev'essere documentato usando ``@bar:``
+
+Commenti in linea per la documentazione dei membri
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+I membri d'una struttura possono essere documentati in linea all'interno
+della definizione stessa. Ci sono due stili: una singola riga di commento
+che inizia con ``/**`` e finisce con ``*/``; commenti multi riga come
+qualsiasi altro commento kernel-doc::
+
+ /**
+ * struct foo - Brief description.
+ * @foo: The Foo member.
+ */
+ struct foo {
+ int foo;
+ /**
+ * @bar: The Bar member.
+ */
+ int bar;
+ /**
+ * @baz: The Baz member.
+ *
+ * Here, the member description may contain several paragraphs.
+ */
+ int baz;
+ union {
+ /** @foobar: Single line description. */
+ int foobar;
+ };
+ /** @bar2: Description for struct @bar2 inside @foo */
+ struct {
+ /**
+ * @bar2.barbar: Description for @barbar inside @foo.bar2
+ */
+ int barbar;
+ } bar2;
+ };
+
+
+Documentazione dei tipi di dato
+-------------------------------
+Generalmente il formato di un commento kernel-doc per typedef è
+il seguente::
+
+ /**
+ * typedef type_name - Brief description.
+ *
+ * Description of the type.
+ */
+
+Anche i tipi di dato per prototipi di funzione possono essere documentati::
+
+ /**
+ * typedef type_name - Brief description.
+ * @arg1: description of arg1
+ * @arg2: description of arg2
+ *
+ * Description of the type.
+ *
+ * Context: Locking context.
+ * Return: Meaning of the return value.
+ */
+ typedef void (*type_name)(struct v4l2_ctrl *arg1, void *arg2);
+
+Marcatori e riferimenti
+-----------------------
+
+All'interno dei commenti di tipo kernel-doc vengono riconosciuti i seguenti
+*pattern* che vengono convertiti in marcatori reStructuredText ed in riferimenti
+del `dominio Sphinx per il C`_.
+
+.. attention:: Questi sono riconosciuti **solo** all'interno di commenti
+ kernel-doc, e **non** all'interno di documenti reStructuredText.
+
+``funcname()``
+ Riferimento ad una funzione.
+
+``@parameter``
+ Nome di un parametro di una funzione (nessun riferimento, solo formattazione).
+
+``%CONST``
+ Il nome di una costante (nessun riferimento, solo formattazione)
+
+````literal````
+ Un blocco di testo che deve essere riportato così com'è. La rappresentazione
+ finale utilizzerà caratteri a ``spaziatura fissa``.
+
+ Questo è utile se dovete utilizzare caratteri speciali che altrimenti
+ potrebbero assumere un significato diverso in kernel-doc o in reStructuredText
+
+ Questo è particolarmente utile se dovete scrivere qualcosa come ``%ph``
+ all'interno della descrizione di una funzione.
+
+``$ENVVAR``
+ Il nome di una variabile d'ambiente (nessun riferimento, solo formattazione).
+
+``&struct name``
+ Riferimento ad una struttura.
+
+``&enum name``
+ Riferimento ad un'enumerazione.
+
+``&typedef name``
+ Riferimento ad un tipo di dato.
+
+``&struct_name->member`` or ``&struct_name.member``
+ Riferimento ad un membro di una struttura o di un'unione. Il riferimento sarà
+ la struttura o l'unione, non il memembro.
+
+``&name``
+ Un generico riferimento ad un tipo. Usate, preferibilmente, il riferimento
+ completo come descritto sopra. Questo è dedicato ai commenti obsoleti.
+
+Riferimenti usando reStructuredText
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Per fare riferimento a funzioni e tipi di dato definiti nei commenti kernel-doc
+all'interno dei documenti reStructuredText, utilizzate i riferimenti dal
+`dominio Sphinx per il C`_. Per esempio::
+
+ See function :c:func:`foo` and struct/union/enum/typedef :c:type:`bar`.
+
+Nonostante il riferimento ai tipi di dato funzioni col solo nome,
+ovvero senza specificare struct/union/enum/typedef, potreste preferire il
+seguente::
+
+ See :c:type:`struct foo <foo>`.
+ See :c:type:`union bar <bar>`.
+ See :c:type:`enum baz <baz>`.
+ See :c:type:`typedef meh <meh>`.
+
+Questo produce dei collegamenti migliori, ed è in linea con il modo in cui
+kernel-doc gestisce i riferimenti.
+
+Per maggiori informazioni, siete pregati di consultare la documentazione
+del `dominio Sphinx per il C`_.
+
+Commenti per una documentazione generale
+----------------------------------------
+
+Al fine d'avere il codice ed i commenti nello stesso file, potete includere
+dei blocchi di documentazione kernel-doc con un formato libero invece
+che nel formato specifico per funzioni, strutture, unioni, enumerati o tipi
+di dato. Per esempio, questo tipo di commento potrebbe essere usato per la
+spiegazione delle operazioni di un driver o di una libreria
+
+Questo s'ottiene utilizzando la parola chiave ``DOC:`` a cui viene associato
+un titolo.
+
+Generalmente il formato di un commento generico o di visione d'insieme è
+il seguente::
+
+ /**
+ * DOC: Theory of Operation
+ *
+ * The whizbang foobar is a dilly of a gizmo. It can do whatever you
+ * want it to do, at any time. It reads your mind. Here's how it works.
+ *
+ * foo bar splat
+ *
+ * The only drawback to this gizmo is that is can sometimes damage
+ * hardware, software, or its subject(s).
+ */
+
+Il titolo che segue ``DOC:`` funziona da intestazione all'interno del file
+sorgente, ma anche come identificatore per l'estrazione di questi commenti di
+documentazione. Quindi, il titolo dev'essere unico all'interno del file.
+
+Includere i commenti di tipo kernel-doc
+=======================================
+
+I commenti di documentazione possono essere inclusi in un qualsiasi documento
+di tipo reStructuredText mediante l'apposita direttiva nell'estensione
+kernel-doc per Sphinx.
+
+Le direttive kernel-doc sono nel formato::
+
+ .. kernel-doc:: source
+ :option:
+
+Il campo *source* è il percorso ad un file sorgente, relativo alla cartella
+principale dei sorgenti del kernel. La direttiva supporta le seguenti opzioni:
+
+export: *[source-pattern ...]*
+ Include la documentazione per tutte le funzioni presenti nel file sorgente
+ (*source*) che sono state esportate utilizzando ``EXPORT_SYMBOL`` o
+ ``EXPORT_SYMBOL_GPL`` in *source* o in qualsiasi altro *source-pattern*
+ specificato.
+
+ Il campo *source-patter* è utile quando i commenti kernel-doc sono stati
+ scritti nei file d'intestazione, mentre ``EXPORT_SYMBOL`` e
+ ``EXPORT_SYMBOL_GPL`` si trovano vicino alla definizione delle funzioni.
+
+ Esempi::
+
+ .. kernel-doc:: lib/bitmap.c
+ :export:
+
+ .. kernel-doc:: include/net/mac80211.h
+ :export: net/mac80211/*.c
+
+internal: *[source-pattern ...]*
+ Include la documentazione per tutte le funzioni ed i tipi presenti nel file
+ sorgente (*source*) che **non** sono stati esportati utilizzando
+ ``EXPORT_SYMBOL`` o ``EXPORT_SYMBOL_GPL`` né in *source* né in qualsiasi
+ altro *source-pattern* specificato.
+
+ Esempio::
+
+ .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c
+ :internal:
+
+doc: *title*
+ Include la documentazione del paragrafo ``DOC:`` identificato dal titolo
+ (*title*) all'interno del file sorgente (*source*). Gli spazi in *title* sono
+ permessi; non virgolettate *title*. Il campo *title* è utilizzato per
+ identificare un paragrafo e per questo non viene incluso nella documentazione
+ finale. Verificate d'avere l'intestazione appropriata nei documenti
+ reStructuredText.
+
+ Esempio::
+
+ .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c
+ :doc: High Definition Audio over HDMI and Display Port
+
+functions: *function* *[...]*
+ Dal file sorgente (*source*) include la documentazione per le funzioni
+ elencate (*function*).
+
+ Esempio::
+
+ .. kernel-doc:: lib/bitmap.c
+ :functions: bitmap_parselist bitmap_parselist_user
+
+Senza alcuna opzione, la direttiva kernel-doc include tutti i commenti di
+documentazione presenti nel file sorgente (*source*).
+
+L'estensione kernel-doc fa parte dei sorgenti del kernel, la si può trovare
+in ``Documentation/sphinx/kerneldoc.py``. Internamente, viene utilizzato
+lo script ``scripts/kernel-doc`` per estrarre i commenti di documentazione
+dai file sorgenti.
+
+Come utilizzare kernel-doc per generare pagine man
+--------------------------------------------------
+
+Se volete utilizzare kernel-doc solo per generare delle pagine man, potete
+farlo direttamente dai sorgenti del kernel::
+
+ $ scripts/kernel-doc -man $(git grep -l '/\*\*' -- :^Documentation :^tools) | scripts/split-man.pl /tmp/man
--git a/Documentation/translations/it_IT/doc-guide/parse-headers.rst b/Documentation/translations/it_IT/doc-guide/parse-headers.rst
new file mode 100644
index 000000000000..b38918ca637e
--- /dev/null
+++ b/Documentation/translations/it_IT/doc-guide/parse-headers.rst
@@ -0,0 +1,196 @@
+.. include:: ../disclaimer-ita.rst
+
+.. note:: Per leggere la documentazione originale in inglese:
+ :ref:`Documentation/doc-guide/index.rst <doc_guide>`
+
+=========================================
+Includere gli i file di intestazione uAPI
+=========================================
+
+Qualche volta è utile includere dei file di intestazione e degli esempi di codice C
+al fine di descrivere l'API per lo spazio utente e per generare dei riferimenti
+fra il codice e la documentazione. Aggiungere i riferimenti ai file dell'API
+dello spazio utente ha ulteriori vantaggi: Sphinx genererà dei messaggi
+d'avviso se un simbolo non viene trovato nella documentazione. Questo permette
+di mantenere allineate la documentazione della uAPI (API spazio utente)
+con le modifiche del kernel.
+Il programma :ref:`parse_headers.pl <it_parse_headers>` genera questi riferimenti.
+Esso dev'essere invocato attraverso un Makefile, mentre si genera la
+documentazione. Per avere un esempio su come utilizzarlo all'interno del kernel
+consultate ``Documentation/media/Makefile``.
+
+.. _it_parse_headers:
+
+parse_headers.pl
+^^^^^^^^^^^^^^^^
+
+NOME
+****
+
+
+parse_headers.pl - analizza i file C al fine di identificare funzioni,
+strutture, enumerati e definizioni, e creare riferimenti per Sphinx
+
+SINTASSI
+********
+
+
+\ **parse_headers.pl**\ [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>]
+
+Dove <options> può essere: --debug, --usage o --help.
+
+
+OPZIONI
+*******
+
+
+
+\ **--debug**\
+
+ Lo script viene messo in modalità verbosa, utile per il debugging.
+
+
+\ **--usage**\
+
+ Mostra un messaggio d'aiuto breve e termina.
+
+
+\ **--help**\
+
+ Mostra un messaggio d'aiuto dettagliato e termina.
+
+
+DESCRIZIONE
+***********
+
+Converte un file d'intestazione o un file sorgente C (C_FILE) in un testo
+ReStructuredText incluso mediante il blocco ..parsed-literal
+con riferimenti alla documentazione che descrive l'API. Opzionalmente,
+il programma accetta anche un altro file (EXCEPTIONS_FILE) che
+descrive quali elementi debbano essere ignorati o il cui riferimento
+deve puntare ad elemento diverso dal predefinito.
+
+Il file generato sarà disponibile in (OUT_FILE).
+
+Il programma è capace di identificare *define*, funzioni, strutture,
+tipi di dato, enumerati e valori di enumerati, e di creare i riferimenti
+per ognuno di loro. Inoltre, esso è capace di distinguere le #define
+utilizzate per specificare i comandi ioctl di Linux.
+
+Il file EXCEPTIONS_FILE contiene due tipi di dichiarazioni:
+\ **ignore**\ o \ **replace**\ .
+
+La sintassi per ignore è:
+
+ignore \ **tipo**\ \ **nome**\
+
+La dichiarazione \ **ignore**\ significa che non verrà generato alcun
+riferimento per il simbolo \ **name**\ di tipo \ **tipo**\ .
+
+
+La sintassi per replace è:
+
+replace \ **tipo**\ \ **nome**\ \ **nuovo_valore**\
+
+La dichiarazione \ **replace**\ significa che verrà generato un
+riferimento per il simbolo \ **name**\ di tipo \ **tipo**\ , ma, invece
+di utilizzare il valore predefinito, verrà utilizzato il valore
+\ **nuovo_valore**\ .
+
+Per entrambe le dichiarazioni, il \ **tipo**\ può essere uno dei seguenti:
+
+
+\ **ioctl**\
+
+ La dichiarazione ignore o replace verrà applicata su definizioni di ioctl
+ come la seguente:
+
+ #define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
+
+
+
+\ **define**\
+
+ La dichiarazione ignore o replace verrà applicata su una qualsiasi #define
+ trovata in C_FILE.
+
+
+
+\ **typedef**\
+
+ La dichiarazione ignore o replace verrà applicata ad una dichiarazione typedef
+ in C_FILE.
+
+
+
+\ **struct**\
+
+ La dichiarazione ignore o replace verrà applicata ai nomi di strutture
+ in C_FILE.
+
+
+
+\ **enum**\
+
+ La dichiarazione ignore o replace verrà applicata ai nomi di enumerati
+ in C_FILE.
+
+
+
+\ **symbol**\
+
+ La dichiarazione ignore o replace verrà applicata ai nomi di valori di
+ enumerati in C_FILE.
+
+ Per le dichiarazioni di tipo replace, il campo \ **new_value**\ utilizzerà
+ automaticamente i riferimenti :c:type: per \ **typedef**\ , \ **enum**\ e
+ \ **struct**\. Invece, utilizzerà :ref: per \ **ioctl**\ , \ **define**\ e
+ \ **symbol**\. Il tipo di riferimento può essere definito esplicitamente
+ nella dichiarazione stessa.
+
+
+ESEMPI
+******
+
+
+ignore define _VIDEODEV2_H
+
+
+Ignora una definizione #define _VIDEODEV2_H nel file C_FILE.
+
+ignore symbol PRIVATE
+
+
+In un enumerato come il seguente:
+
+enum foo { BAR1, BAR2, PRIVATE };
+
+Non genererà alcun riferimento per \ **PRIVATE**\ .
+
+replace symbol BAR1 :c:type:\`foo\`
+replace symbol BAR2 :c:type:\`foo\`
+
+
+In un enumerato come il seguente:
+
+enum foo { BAR1, BAR2, PRIVATE };
+
+Genererà un riferimento ai valori BAR1 e BAR2 dal simbolo foo nel dominio C.
+
+
+BUGS
+****
+
+Riferire ogni malfunzionamento a Mauro Carvalho Chehab <mchehab@s-opensource.com>
+
+
+COPYRIGHT
+*********
+
+
+Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@s-opensource.com>.
+
+Licenza GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.
+
+Questo è software libero: siete liberi di cambiarlo e ridistribuirlo.
+Non c'è alcuna garanzia, nei limiti permessi dalla legge.
diff --git a/Documentation/translations/it_IT/doc-guide/sphinx.rst b/Documentation/translations/it_IT/doc-guide/sphinx.rst
new file mode 100644
index 000000000000..474b7e127893
--- /dev/null
+++ b/Documentation/translations/it_IT/doc-guide/sphinx.rst
@@ -0,0 +1,457 @@
+.. include:: ../disclaimer-ita.rst
+
+.. note:: Per leggere la documentazione originale in inglese:
+ :ref:`Documentation/doc-guide/index.rst <doc_guide>`
+
+Introduzione
+============
+
+Il kernel Linux usa `Sphinx`_ per la generazione della documentazione a partire
+dai file `reStructuredText`_ che si trovano nella cartella ``Documentation``.
+Per generare la documentazione in HTML o PDF, usate comandi ``make htmldocs`` o
+``make pdfdocs``. La documentazione così generata sarà disponibile nella
+cartella ``Documentation/output``.
+
+.. _Sphinx: http://www.sphinx-doc.org/
+.. _reStructuredText: http://docutils.sourceforge.net/rst.html
+
+I file reStructuredText possono contenere delle direttive che permettono di
+includere i commenti di documentazione, o di tipo kernel-doc, dai file
+sorgenti.
+Solitamente questi commenti sono utilizzati per descrivere le funzioni, i tipi
+e l'architettura del codice. I commenti di tipo kernel-doc hanno una struttura
+e formato speciale, ma a parte questo vengono processati come reStructuredText.
+
+Inoltre, ci sono migliaia di altri documenti in formato testo sparsi nella
+cartella ``Documentation``. Alcuni di questi verranno probabilmente convertiti,
+nel tempo, in formato reStructuredText, ma la maggior parte di questi rimarranno
+in formato testo.
+
+.. _it_sphinx_install:
+
+Installazione Sphinx
+====================
+
+I marcatori ReST utilizzati nei file in Documentation/ sono pensati per essere
+processati da ``Sphinx`` nella versione 1.3 o superiore. Se desiderate produrre
+un documento PDF è raccomandato l'utilizzo di una versione superiore alle 1.4.6.
+
+Esiste uno script che verifica i requisiti Sphinx. Per ulteriori dettagli
+consultate :ref:`it_sphinx-pre-install`.
+
+La maggior parte delle distribuzioni Linux forniscono Sphinx, ma l'insieme dei
+programmi e librerie è fragile e non è raro che dopo un aggiornamento di
+Sphinx, o qualche altro pacchetto Python, la documentazione non venga più
+generata correttamente.
+
+Un modo per evitare questo genere di problemi è quello di utilizzare una
+versione diversa da quella fornita dalla vostra distribuzione. Per fare questo,
+vi raccomandiamo di installare Sphinx dentro ad un ambiente virtuale usando
+``virtualenv-3`` o ``virtualenv`` a seconda di come Python 3 è stato
+pacchettizzato dalla vostra distribuzione.
+
+.. note::
+
+ #) Le versioni di Sphinx inferiori alla 1.5 non funzionano bene
+ con il pacchetto Python docutils versione 0.13.1 o superiore.
+ Se volete usare queste versioni, allora dovere eseguire
+ ``pip install 'docutils==0.12'``.
+
+ #) Viene raccomandato l'uso del tema RTD per la documentazione in HTML.
+ A seconda della versione di Sphinx, potrebbe essere necessaria
+ l'installazione tramite il comando ``pip install sphinx_rtd_theme``.
+
+ #) Alcune pagine ReST contengono delle formule matematiche. A causa del
+ modo in cui Sphinx funziona, queste espressioni sono scritte
+ utilizzando LaTeX. Per una corretta interpretazione, è necessario aver
+ installato texlive con i pacchetti amdfonts e amsmath.
+
+Riassumendo, se volete installare la versione 1.4.9 di Sphinx dovete eseguire::
+
+ $ virtualenv sphinx_1.4
+ $ . sphinx_1.4/bin/activate
+ (sphinx_1.4) $ pip install -r Documentation/sphinx/requirements.txt
+
+Dopo aver eseguito ``. sphinx_1.4/bin/activate``, il prompt cambierà per
+indicare che state usando il nuovo ambiente. Se aprite un nuova sessione,
+prima di generare la documentazione, dovrete rieseguire questo comando per
+rientrare nell'ambiente virtuale.
+
+Generazione d'immagini
+----------------------
+
+Il meccanismo che genera la documentazione del kernel contiene un'estensione
+capace di gestire immagini in formato Graphviz e SVG (per maggior informazioni
+vedere :ref:`it_sphinx_kfigure`).
+
+Per far si che questo funzioni, dovete installare entrambe i pacchetti
+Graphviz e ImageMagick. Il sistema di generazione della documentazione è in
+grado di procedere anche se questi pacchetti non sono installati, ma il
+risultato, ovviamente, non includerà le immagini.
+
+Generazione in PDF e LaTeX
+--------------------------
+
+Al momento, la generazione di questi documenti è supportata solo dalle
+versioni di Sphinx superiori alla 1.4.
+
+Per la generazione di PDF e LaTeX, avrete bisogno anche del pacchetto
+``XeLaTeX`` nella versione 3.14159265
+
+Per alcune distribuzioni Linux potrebbe essere necessario installare
+anche una serie di pacchetti ``texlive`` in modo da fornire il supporto
+minimo per il funzionamento di ``XeLaTeX``.
+
+.. _it_sphinx-pre-install:
+
+Verificare le dipendenze Sphinx
+-------------------------------
+
+Esiste uno script che permette di verificare automaticamente le dipendenze di
+Sphinx. Se lo script riesce a riconoscere la vostra distribuzione, allora
+sarà in grado di darvi dei suggerimenti su come procedere per completare
+l'installazione::
+
+ $ ./scripts/sphinx-pre-install
+ Checking if the needed tools for Fedora release 26 (Twenty Six) are available
+ Warning: better to also install "texlive-luatex85".
+ You should run:
+
+ sudo dnf install -y texlive-luatex85
+ /usr/bin/virtualenv sphinx_1.4
+ . sphinx_1.4/bin/activate
+ pip install -r Documentation/sphinx/requirements.txt
+
+ Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468.
+
+L'impostazione predefinita prevede il controllo dei requisiti per la generazione
+di documenti html e PDF, includendo anche il supporto per le immagini, le
+espressioni matematiche e LaTeX; inoltre, presume che venga utilizzato un
+ambiente virtuale per Python. I requisiti per generare i documenti html
+sono considerati obbligatori, gli altri sono opzionali.
+
+Questo script ha i seguenti parametri:
+
+``--no-pdf``
+ Disabilita i controlli per la generazione di PDF;
+
+``--no-virtualenv``
+ Utilizza l'ambiente predefinito dal sistema operativo invece che
+ l'ambiente virtuale per Python;
+
+
+Generazione della documentazione Sphinx
+=======================================
+
+Per generare la documentazione in formato HTML o PDF si eseguono i rispettivi
+comandi ``make htmldocs`` o ``make pdfdocs``. Esistono anche altri formati
+in cui è possibile generare la documentazione; per maggiori informazioni
+potere eseguire il comando ``make help``.
+La documentazione così generata sarà disponibile nella sottocartella
+``Documentation/output``.
+
+Ovviamente, per generare la documentazione, Sphinx (``sphinx-build``)
+dev'essere installato. Se disponibile, il tema *Read the Docs* per Sphinx
+verrà utilizzato per ottenere una documentazione HTML più gradevole.
+Per la documentazione in formato PDF, invece, avrete bisogno di ``XeLaTeX`
+e di ``convert(1)`` disponibile in ImageMagick (https://www.imagemagick.org).
+Tipicamente, tutti questi pacchetti sono disponibili e pacchettizzati nelle
+distribuzioni Linux.
+
+Per poter passare ulteriori opzioni a Sphinx potete utilizzare la variabile
+make ``SPHINXOPTS``. Per esempio, se volete che Sphinx sia più verboso durante
+la generazione potete usare il seguente comando ``make SPHINXOPTS=-v htmldocs``.
+
+Potete eliminare la documentazione generata tramite il comando
+``make cleandocs``.
+
+Scrivere la documentazione
+==========================
+
+Aggiungere nuova documentazione è semplice:
+
+1. aggiungete un file ``.rst`` nella sottocartella ``Documentation``
+2. aggiungete un riferimento ad esso nell'indice (`TOC tree`_) in
+ ``Documentation/index.rst``.
+
+.. _TOC tree: http://www.sphinx-doc.org/en/stable/markup/toctree.html
+
+Questo, di solito, è sufficiente per la documentazione più semplice (come
+quella che state leggendo ora), ma per una documentazione più elaborata è
+consigliato creare una sottocartella dedicata (o, quando possibile, utilizzarne
+una già esistente). Per esempio, il sottosistema grafico è documentato nella
+sottocartella ``Documentation/gpu``; questa documentazione è divisa in
+diversi file ``.rst`` ed un indice ``index.rst`` (con un ``toctree``
+dedicato) a cui si fa riferimento nell'indice principale.
+
+Consultate la documentazione di `Sphinx`_ e `reStructuredText`_ per maggiori
+informazione circa le loro potenzialità. In particolare, il
+`manuale introduttivo a reStructuredText`_ di Sphinx è un buon punto da
+cui cominciare. Esistono, inoltre, anche alcuni
+`costruttori specifici per Sphinx`_.
+
+.. _`manuale introduttivo a reStructuredText`: http://www.sphinx-doc.org/en/stable/rest.html
+.. _`costruttori specifici per Sphinx`: http://www.sphinx-doc.org/en/stable/markup/index.html
+
+Guide linea per la documentazione del kernel
+--------------------------------------------
+
+In questa sezione troverete alcune linee guida specifiche per la documentazione
+del kernel:
+
+* Non esagerate con i costrutti di reStructuredText. Mantenete la
+ documentazione semplice. La maggior parte della documentazione dovrebbe
+ essere testo semplice con una strutturazione minima che permetta la
+ conversione in diversi formati.
+
+* Mantenete la strutturazione il più fedele possibile all'originale quando
+ convertite un documento in formato reStructuredText.
+
+* Aggiornate i contenuti quando convertite della documentazione, non limitatevi
+ solo alla formattazione.
+
+* Mantenete la decorazione dei livelli di intestazione come segue:
+
+ 1. ``=`` con una linea superiore per il titolo del documento::
+
+ ======
+ Titolo
+ ======
+
+ 2. ``=`` per i capitoli::
+
+ Capitoli
+ ========
+
+ 3. ``-`` per le sezioni::
+
+ Sezioni
+ -------
+
+ 4. ``~`` per le sottosezioni::
+
+ Sottosezioni
+ ~~~~~~~~~~~~
+
+ Sebbene RST non forzi alcun ordine specifico (*Piuttosto che imporre
+ un numero ed un ordine fisso di decorazioni, l'ordine utilizzato sarà
+ quello incontrato*), avere uniformità dei livelli principali rende più
+ semplice la lettura dei documenti.
+
+* Per inserire blocchi di testo con caratteri a dimensione fissa (codici di
+ esempio, casi d'uso, eccetera): utilizzate ``::`` quando non è necessario
+ evidenziare la sintassi, specialmente per piccoli frammenti; invece,
+ utilizzate ``.. code-block:: <language>`` per blocchi di più lunghi che
+ potranno beneficiare dell'avere la sintassi evidenziata.
+
+
+Il dominio C
+------------
+
+Il **Dominio Sphinx C** (denominato c) è adatto alla documentazione delle API C.
+Per esempio, un prototipo di una funzione:
+
+.. code-block:: rst
+
+ .. c:function:: int ioctl( int fd, int request )
+
+Il dominio C per kernel-doc ha delle funzionalità aggiuntive. Per esempio,
+potete assegnare un nuovo nome di riferimento ad una funzione con un nome
+molto comune come ``open`` o ``ioctl``:
+
+.. code-block:: rst
+
+ .. c:function:: int ioctl( int fd, int request )
+ :name: VIDIOC_LOG_STATUS
+
+Il nome della funzione (per esempio ioctl) rimane nel testo ma il nome del suo
+riferimento cambia da ``ioctl`` a ``VIDIOC_LOG_STATUS``. Anche la voce
+nell'indice cambia in ``VIDIOC_LOG_STATUS`` e si potrà quindi fare riferimento
+a questa funzione scrivendo:
+
+.. code-block:: rst
+
+ :c:func:`VIDIOC_LOG_STATUS`
+
+
+Tabelle a liste
+---------------
+
+Raccomandiamo l'uso delle tabelle in formato lista (*list table*). Le tabelle
+in formato lista sono liste di liste. In confronto all'ASCII-art potrebbero
+non apparire di facile lettura nei file in formato testo. Il loro vantaggio è
+che sono facili da creare o modificare e che la differenza di una modifica è
+molto più significativa perché limitata alle modifiche del contenuto.
+
+La ``flat-table`` è anch'essa una lista di liste simile alle ``list-table``
+ma con delle funzionalità aggiuntive:
+
+* column-span: col ruolo ``cspan`` una cella può essere estesa attraverso
+ colonne successive
+
+* raw-span: col ruolo ``rspan`` una cella può essere estesa attraverso
+ righe successive
+
+* auto-span: la cella più a destra viene estesa verso destra per compensare
+ la mancanza di celle. Con l'opzione ``:fill-cells:`` questo comportamento
+ può essere cambiato da *auto-span* ad *auto-fill*, il quale inserisce
+ automaticamente celle (vuote) invece che estendere l'ultima.
+
+opzioni:
+
+* ``:header-rows:`` [int] conta le righe di intestazione
+* ``:stub-columns:`` [int] conta le colonne di stub
+* ``:widths:`` [[int] [int] ... ] larghezza delle colonne
+* ``:fill-cells:`` invece di estendere automaticamente una cella su quelle
+ mancanti, ne crea di vuote.
+
+ruoli:
+
+* ``:cspan:`` [int] colonne successive (*morecols*)
+* ``:rspan:`` [int] righe successive (*morerows*)
+
+L'esempio successivo mostra come usare questo marcatore. Il primo livello della
+nostra lista di liste è la *riga*. In una *riga* è possibile inserire solamente
+la lista di celle che compongono la *riga* stessa. Fanno eccezione i *commenti*
+( ``..`` ) ed i *collegamenti* (per esempio, un riferimento a
+``:ref:`last row <last row>``` / :ref:`last row <it last row>`)
+
+.. code-block:: rst
+
+ .. flat-table:: table title
+ :widths: 2 1 1 3
+
+ * - head col 1
+ - head col 2
+ - head col 3
+ - head col 4
+
+ * - column 1
+ - field 1.1
+ - field 1.2 with autospan
+
+ * - column 2
+ - field 2.1
+ - :rspan:`1` :cspan:`1` field 2.2 - 3.3
+
+ * .. _`it last row`:
+
+ - column 3
+
+Che verrà rappresentata nel seguente modo:
+
+ .. flat-table:: table title
+ :widths: 2 1 1 3
+
+ * - head col 1
+ - head col 2
+ - head col 3
+ - head col 4
+
+ * - column 1
+ - field 1.1
+ - field 1.2 with autospan
+
+ * - column 2
+ - field 2.1
+ - :rspan:`1` :cspan:`1` field 2.2 - 3.3
+
+ * .. _`it last row`:
+
+ - column 3
+
+.. _it_sphinx_kfigure:
+
+Figure ed immagini
+==================
+
+Se volete aggiungere un'immagine, utilizzate le direttive ``kernel-figure``
+e ``kernel-image``. Per esempio, per inserire una figura di un'immagine in
+formato SVG::
+
+ .. kernel-figure:: ../../../doc-guide/svg_image.svg
+ :alt: una semplice immagine SVG
+
+ Una semplice immagine SVG
+
+.. _it_svg_image_example:
+
+.. kernel-figure:: ../../../doc-guide/svg_image.svg
+ :alt: una semplice immagine SVG
+
+ Una semplice immagine SVG
+
+Le direttive del kernel per figure ed immagini supportano il formato **DOT**,
+per maggiori informazioni
+
+* DOT: http://graphviz.org/pdf/dotguide.pdf
+* Graphviz: http://www.graphviz.org/content/dot-language
+
+Un piccolo esempio (:ref:`it_hello_dot_file`)::
+
+ .. kernel-figure:: ../../../doc-guide/hello.dot
+ :alt: ciao mondo
+
+ Esempio DOT
+
+.. _it_hello_dot_file:
+
+.. kernel-figure:: ../../../doc-guide/hello.dot
+ :alt: ciao mondo
+
+ Esempio DOT
+
+Tramite la direttiva ``kernel-render`` è possibile aggiungere codice specifico;
+ad esempio nel formato **DOT** di Graphviz.::
+
+ .. kernel-render:: DOT
+ :alt: foobar digraph
+ :caption: Codice **DOT** (Graphviz) integrato
+
+ digraph foo {
+ "bar" -> "baz";
+ }
+
+La rappresentazione dipenderà dei programmi installati. Se avete Graphviz
+installato, vedrete un'immagine vettoriale. In caso contrario, il codice grezzo
+verrà rappresentato come *blocco testuale* (:ref:`it_hello_dot_render`).
+
+.. _it_hello_dot_render:
+
+.. kernel-render:: DOT
+ :alt: foobar digraph
+ :caption: Codice **DOT** (Graphviz) integrato
+
+ digraph foo {
+ "bar" -> "baz";
+ }
+
+La direttiva *render* ha tutte le opzioni della direttiva *figure*, con
+l'aggiunta dell'opzione ``caption``. Se ``caption`` ha un valore allora
+un nodo *figure* viene aggiunto. Altrimenti verrà aggiunto un nodo *image*.
+L'opzione ``caption`` è necessaria in caso si vogliano aggiungere dei
+riferimenti (:ref:`it_hello_svg_render`).
+
+Per la scrittura di codice **SVG**::
+
+ .. kernel-render:: SVG
+ :caption: Integrare codice **SVG**
+ :alt: so-nw-arrow
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" ...>
+ ...
+ </svg>
+
+.. _it_hello_svg_render:
+
+.. kernel-render:: SVG
+ :caption: Integrare codice **SVG**
+ :alt: so-nw-arrow
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <svg xmlns="http://www.w3.org/2000/svg"
+ version="1.1" baseProfile="full" width="70px" height="40px" viewBox="0 0 700 400">
+ <line x1="180" y1="370" x2="500" y2="50" stroke="black" stroke-width="15px"/>
+ <polygon points="585 0 525 25 585 50" transform="rotate(135 525 25)"/>
+ </svg>
diff --git a/Documentation/translations/it_IT/index.rst b/Documentation/translations/it_IT/index.rst
index 7613a9f9e6f9..dae01886b073 100644
--- a/Documentation/translations/it_IT/index.rst
+++ b/Documentation/translations/it_IT/index.rst
@@ -83,6 +83,11 @@ sviluppatori che contribuiscono ogni anno. Come in ogni grande comunità,
sapere come le cose vengono fatte renderà il processo di integrazione delle
vostre modifiche molto più semplice
+.. toctree::
+ :maxdepth: 2
+
+ doc-guide/index
+
.. warning::
TODO ancora da tradurre
--
2.14.4
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 4/6] doc: add some chapter labels
From: Federico Vaga @ 2018-06-05 22:49 UTC (permalink / raw)
To: Jonathan Corbet
Cc: linux-doc, linux-kernel, Alessia Mantegazza, Federico Vaga
In-Reply-To: <20180605224903.9483-1-federico.vaga@vaga.pv.it>
The idea is to make it easier to create references (doc-guide does the same).
This will be used, for example but not only, in translations to point to
the main document.
Signed-off-by: Federico Vaga <federico.vaga@vaga.pv.it>
---
Documentation/index.rst | 2 ++
Documentation/kernel-hacking/index.rst | 2 ++
2 files changed, 4 insertions(+)
diff --git a/Documentation/index.rst b/Documentation/index.rst
index f7ab4d6a281e..245ab83d0e6f 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -3,6 +3,8 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
+.. _linux_doc:
+
The Linux Kernel documentation
==============================
diff --git a/Documentation/kernel-hacking/index.rst b/Documentation/kernel-hacking/index.rst
index fcb0eda3cca3..f53027652290 100644
--- a/Documentation/kernel-hacking/index.rst
+++ b/Documentation/kernel-hacking/index.rst
@@ -1,3 +1,5 @@
+.. _kernel_hacking:
+
=====================
Kernel Hacking Guides
=====================
--
2.14.4
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/6] doc:doc-guide: fix a typo and an error
From: Federico Vaga @ 2018-06-05 22:48 UTC (permalink / raw)
To: Jonathan Corbet
Cc: linux-doc, linux-kernel, Alessia Mantegazza, Federico Vaga
In-Reply-To: <20180605224903.9483-1-federico.vaga@vaga.pv.it>
typo in sphinx.rst
error in parse-header.rst
Signed-off-by: Federico Vaga <federico.vaga@vaga.pv.it>
---
| 2 +-
Documentation/doc-guide/sphinx.rst | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--git a/Documentation/doc-guide/parse-headers.rst b/Documentation/doc-guide/parse-headers.rst
index 82a3e43b6864..684490c68acb 100644
--- a/Documentation/doc-guide/parse-headers.rst
+++ b/Documentation/doc-guide/parse-headers.rst
@@ -133,7 +133,7 @@ For both statements, \ **type**\ can be either one of the following:
\ **symbol**\
- The ignore or replace statement will apply to the name of enum statements
+ The ignore or replace statement will apply to the name of enum value
at C_FILE.
For replace statements, \ **new_value**\ will automatically use :c:type:
diff --git a/Documentation/doc-guide/sphinx.rst b/Documentation/doc-guide/sphinx.rst
index a2417633fdd8..f0796daa95b4 100644
--- a/Documentation/doc-guide/sphinx.rst
+++ b/Documentation/doc-guide/sphinx.rst
@@ -28,7 +28,7 @@ The ReST markups currently used by the Documentation/ files are meant to be
built with ``Sphinx`` version 1.3 or upper. If you're desiring to build
PDF outputs, it is recommended to use version 1.4.6 or upper.
-There's a script that checks for the Spinx requirements. Please see
+There's a script that checks for the Sphinx requirements. Please see
:ref:`sphinx-pre-install` for further details.
Most distributions are shipped with Sphinx, but its toolchain is fragile,
--
2.14.4
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v5 0/2] perf: riscv: Preliminary Perf Event Support on RISC-V
From: Alan Kao @ 2018-06-06 3:16 UTC (permalink / raw)
To: Palmer Dabbelt
Cc: atish.patra, sols, nickhu, corbet, peterz, linux-doc,
linux-kernel, acme, alexander.shishkin, mingo, albert, namhyung,
linux-riscv, jolsa, greentime
In-Reply-To: <mhng-aec39091-7a3b-4def-99f3-577e023c6919@palmer-si-x1c4>
On Wed, Apr 25, 2018 at 09:39:04AM -0700, Palmer Dabbelt wrote:
> On Tue, 24 Apr 2018 20:19:36 PDT (-0700), alankao@andestech.com wrote:
> >Hi Atish, Palmer,
> >
> >On Tue, Apr 24, 2018 at 06:15:49PM -0700, Atish Patra wrote:
> >>On 4/24/18 5:29 PM, Palmer Dabbelt wrote:
> >>>On Tue, 24 Apr 2018 15:16:16 PDT (-0700), atish.patra@wdc.com wrote:
> >>>>On 4/24/18 12:44 PM, Palmer Dabbelt wrote:
> >>>>>On Tue, 24 Apr 2018 12:27:26 PDT (-0700), atish.patra@wdc.com wrote:
> >>>>>>On 4/24/18 11:07 AM, Atish Patra wrote:
> >>>>>>>On 4/19/18 4:28 PM, Alan Kao wrote:
> >>>>>>>However, I got an rcu-stall for the test "47: Event times".
> >>>>>>># ./perf test -v 47
> >>>>>>Got it working. The test tries to attach the event to CPU0 which doesn't
> >>>>>>exist in HighFive Unleashed. Changing it to cpu1 works.
> >>>>>>
> >>>>>>diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c
> >>>>>>index 1a2686f..eb11632f 100644
> >>>>>>--- a/tools/perf/tests/event-times.c
> >>>>>>+++ b/tools/perf/tests/event-times.c
> >>>>>>@@ -113,9 +113,9 @@ static int attach__cpu_disabled(struct perf_evlist
> >>>>>>*evlist)
> >>>>>> struct cpu_map *cpus;
> >>>>>> int err;
> >>>>>>
> >>>>>>- pr_debug("attaching to CPU 0 as enabled\n");
> >>>>>>+ pr_debug("attaching to CPU 1 as disabled\n");
> >>>>>>
> >>>>>>- cpus = cpu_map__new("0");
> >>>>>>+ cpus = cpu_map__new("1");
> >>>>>> if (cpus == NULL) {
> >>>>>> pr_debug("failed to call cpu_map__new\n");
> >>>>>> return -1;
> >>>>>>@@ -142,9 +142,9 @@ static int attach__cpu_enabled(struct perf_evlist
> >>>>>>*evlist)
> >>>>>> struct cpu_map *cpus;
> >>>>>> int err;
> >>>>>>
> >>>>>>- pr_debug("attaching to CPU 0 as enabled\n");
> >>>>>>+ pr_debug("attaching to CPU 1 as enabled\n");
> >>>>>>
> >>>>>>- cpus = cpu_map__new("0");
> >>>>>>+ cpus = cpu_map__new("1");
> >>>>>> if (cpus == NULL) {
> >>>>>> pr_debug("failed to call cpu_map__new\n");
> >>>>>> return -1;
> >>>>>>
> >>>>>>
> >>>>>>Palmer,
> >>>>>>Would it be better to officially document it somewhere that CPU0 doesn't
> >>>>>>exist in the HighFive Unleashed board ?
> >>>>>>I fear that there will be other standard tests/code path that may fail
> >>>>>>because of inherent assumption of cpu0 presence.
> >>>>>
> >>>>>I think the best way to fix this is to just have BBL (or whatever the
> >>>>>bootloader is) renumber the CPUs so they're contiguous and begin with 0.
> >>>>
> >>>>Do you mean BBL will update the device tree that kernel eventually parse
> >>>>and set the hart id?
> >>>>Sounds good to me unless it acts as a big hack in future boot loaders.
> >>>
> >>>Right now the machine-mode and supervisor-mode hart IDs are logically separate:
> >>>the bootloader just provides the hart ID as a register argument when starting
> >>>the kernel.
> >>
> >>Yes.
> >>
> >> BBL already needs to enumerate the harts by looking through the
> >>>device tree for various other reasons (at least to mask off the harts that
> >>>Linux doesn't support), so it's not that much effort to just maintain a mapping
> >>>from supervisor-mode hart IDs to machine-mode hart IDs.
> >>>
> >>
> >>But Linux also parses the device tree to get hart ID in
> >>riscv_of_processor_hart(). This is used to setup the possible/present cpu
> >>map in setup_smp().
> >>
> >>Thus, Linux also need to see a device tree with cpu0-3 instead of cpu1-4.
> >>Otherwise, present cpu map will be incorrect. Isn't it ?
> >>
> >>>I have some patches floating around that do this, but appear to do it
> >>>incorrectly enough that nothing boots so maybe I'm missing something that makes
> >>>this complicated :).
> >>>
> >>
> >>Just a wild guess: May be the because of the above reason ;)
> >>
> >
> >Thanks for the test and discussion. It looks like am implementation issue from
> >Unleash, so ... is there anything I should fix and provide a further patch?
>
> You're welcome to fix BBL if you want, but that's unrelated to this patch
> set. I'm going to look over the code again as soon as I get a chance to,
> thanks for submitting the patches!
Any updates?
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 0/7] Uprobes: Support SDT markers having reference count (semaphore)
From: Ravi Bangoria @ 2018-06-06 8:33 UTC (permalink / raw)
To: oleg, srikar, rostedt, mhiramat
Cc: peterz, mingo, acme, alexander.shishkin, jolsa, namhyung,
linux-kernel, corbet, linux-doc, ananth, alexis.berlemont,
naveen.n.rao, Ravi Bangoria
Why RFC again:
This series is different from earlier versions[1]. Earlier series
implemented this feature in trace_uprobe while this has implemented
the logic in core uprobe. Few reasons for this:
1. One of the major reason was the deadlock between uprobe_lock and
mm->mmap inside trace_uprobe_mmap(). That deadlock was not easy to fix
because mm->mmap is not in control of trace_uprobe_mmap() and it has
to take uprobe_lock to loop over trace_uprobe list. More details can
be found at[2]. With this new approach, there are no deadlocks found
so far.
2. Many of the core uprobe function and data-structures needs to be
exported to make earlier implementation simple. With this new approach,
reference counter logic is been implemented in core uprobe and thus
no need to export anything.
Description:
Userspace Statically Defined Tracepoints[3] are dtrace style markers
inside userspace applications. Applications like PostgreSQL, MySQL,
Pthread, Perl, Python, Java, Ruby, Node.js, libvirt, QEMU, glib etc
have these markers embedded in them. These markers are added by developer
at important places in the code. Each marker source expands to a single
nop instruction in the compiled code but there may be additional
overhead for computing the marker arguments which expands to couple of
instructions. In case the overhead is more, execution of it can be
omitted by runtime if() condition when no one is tracing on the marker:
if (reference_counter > 0) {
Execute marker instructions;
}
Default value of reference counter is 0. Tracer has to increment the
reference counter before tracing on a marker and decrement it when
done with the tracing.
Currently, perf tool has limited supports for SDT markers. I.e. it
can not trace markers surrounded by reference counter. Also, it's
not easy to add reference counter logic in userspace tool like perf,
so basic idea for this patchset is to add reference counter logic in
the trace_uprobe infrastructure. Ex,[4]
# cat tick.c
...
for (i = 0; i < 100; i++) {
DTRACE_PROBE1(tick, loop1, i);
if (TICK_LOOP2_ENABLED()) {
DTRACE_PROBE1(tick, loop2, i);
}
printf("hi: %d\n", i);
sleep(1);
}
...
Here tick:loop1 is marker without reference counter where as tick:loop2
is surrounded by reference counter condition.
# perf buildid-cache --add /tmp/tick
# perf probe sdt_tick:loop1
# perf probe sdt_tick:loop2
# perf stat -e sdt_tick:loop1,sdt_tick:loop2 -- /tmp/tick
hi: 0
hi: 1
hi: 2
^C
Performance counter stats for '/tmp/tick':
3 sdt_tick:loop1
0 sdt_tick:loop2
2.747086086 seconds time elapsed
Perf failed to record data for tick:loop2. Same experiment with this
patch series:
# ./perf buildid-cache --add /tmp/tick
# ./perf probe sdt_tick:loop2
# ./perf stat -e sdt_tick:loop2 /tmp/tick
hi: 0
hi: 1
hi: 2
^C
Performance counter stats for '/tmp/tick':
3 sdt_tick:loop2
2.561851452 seconds time elapsed
Note:
- 'reference counter' is called as 'semaphore' in original Dtrace
(or Systemtap, bcc and even in ELF) documentation and code. But the
term 'semaphore' is misleading in this context. This is just a counter
used to hold number of tracers tracing on a marker. This is not really
used for any synchronization. So we are referring it as 'reference
counter' in kernel / perf code.
- This patches still has one issue. If there are multiple instances of
same application running and user wants to trace any particular
instance, trace_uprobe is updating reference counter in all instances.
This is not a problem on user side because instruction is not replaced
with trap/int3 and thus user will only see samples from his interested
process. But still this is more of a correctness issue. I'm working on
a fix for this.
[1] https://lkml.org/lkml/2018/4/17/23
[2] https://lkml.org/lkml/2018/5/25/111
[3] https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation
[4] https://github.com/iovisor/bcc/issues/327#issuecomment-200576506
Ravi Bangoria (7):
Uprobes: Simplify uprobe_register() body
Uprobes: Support SDT markers having reference count (semaphore)
Uprobes/sdt: Fix multiple update of same reference counter
trace_uprobe/sdt: Prevent multiple reference counter for same uprobe
Uprobes/sdt: Prevent multiple reference counter for same uprobe
Uprobes/sdt: Document about reference counter
perf probe: Support SDT markers having reference counter (semaphore)
Documentation/trace/uprobetracer.rst | 16 +-
include/linux/uprobes.h | 5 +
kernel/events/uprobes.c | 502 +++++++++++++++++++++++++++++++----
kernel/trace/trace.c | 2 +-
kernel/trace/trace_uprobe.c | 74 +++++-
tools/perf/util/probe-event.c | 39 ++-
tools/perf/util/probe-event.h | 1 +
tools/perf/util/probe-file.c | 34 ++-
tools/perf/util/probe-file.h | 1 +
tools/perf/util/symbol-elf.c | 46 +++-
tools/perf/util/symbol.h | 7 +
11 files changed, 643 insertions(+), 84 deletions(-)
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 3/7] Uprobes/sdt: Fix multiple update of same reference counter
From: Ravi Bangoria @ 2018-06-06 8:33 UTC (permalink / raw)
To: oleg, srikar, rostedt, mhiramat
Cc: peterz, mingo, acme, alexander.shishkin, jolsa, namhyung,
linux-kernel, corbet, linux-doc, ananth, alexis.berlemont,
naveen.n.rao, Ravi Bangoria
In-Reply-To: <20180606083344.31320-1-ravi.bangoria@linux.ibm.com>
When virtual memory map for binary/library is being prepared, there is
no direct one to one mapping between mmap() and virtual memory area. Ex,
when loader loads the library, it first calls mmap(size = total_size),
where total_size is addition of size of all elf sections that are going
to be mapped. Then it splits individual vmas with new mmap()/mprotect()
calls. Loader does this to ensure it gets continuous address range for
a library. load_elf_binary() also uses similar tricks while preparing
mappings of binary.
Ex for pyhton library,
# strace python
mmap(NULL, 2738968, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fff92460000
mmap(0x7fff926a0000, 327680, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x230000) = 0x7fff926a0000
mprotect(0x7fff926a0000, 65536, PROT_READ) = 0
Here, the first mmap() maps the whole library into one region. Second
mmap() and third mprotect() split out the whole region into smaller
vmas and sets appropriate protection flags.
Now, in this case, uprobe_mmap() updates the reference counter twice
-- by second mmap() call and by third mprotect() call -- because both
regions contain reference counter.
But while de-registration, reference counter will get decremented only
once leaving reference counter > 0 even if no one is tracing on that
marker.
Example with python library before patch:
# readelf -n /lib64/libpython2.7.so.1.0 | grep -A1 function__entry
Name: function__entry
... Semaphore: 0x00000000002899d8
Probe on a marker:
# echo "p:sdt_python/function__entry /usr/lib64/libpython2.7.so.1.0:0x16a4d4(0x2799d8)" > uprobe_events
Start tracing:
# perf record -e sdt_python:function__entry -a
Run python workload:
# python
# cat /proc/`pgrep python`/maps | grep libpython
7fffadb00000-7fffadd40000 r-xp 00000000 08:05 403934 /usr/lib64/libpython2.7.so.1.0
7fffadd40000-7fffadd50000 r--p 00230000 08:05 403934 /usr/lib64/libpython2.7.so.1.0
7fffadd50000-7fffadd90000 rw-p 00240000 08:05 403934 /usr/lib64/libpython2.7.so.1.0
Reference counter value has been incremented twice:
# dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fffadd899d8 )) 2>/dev/null | xxd
0000000: 02 .
Kill perf:
#
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.322 MB perf.data (1273 samples) ]
Reference conter is still 1 even when no one is tracing on it:
# dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fffadd899d8 )) 2>/dev/null | xxd
0000000: 01 .
Ensure increment and decrement happens in sync by keeping list of
{consumer, mm} tuple in struct uprobe. Check presence of it in the list
before incrementing the reference counter. I.e. for each {consumer, mm}
tuple, reference counter must be incremented only by one. Note that we
don't check the presence of mm in the list at decrement time.
We consider only two cases while _incrementing_ the reference counter:
1. Target binary is already running when we start tracing. In this
case, find all mm which maps region of target binary containing
reference counter. Loop over all mms and increment the counter if
{consumer, mm} is not already present in the list.
2. Tracer is already tracing before target binary starts execution. In
this case, update reference counter only if {consumer, vma->vm_mm}
is not already present in the list.
There is also a third case which we don't consider, a fork() case.
When process with markers forks itself, we don't explicitly increment
the reference counter in child process because it should be taken care
by dup_mmap(). We also don't add the child mm in the list. This is
fine because we don't check presence of mm in the list at decrement
time.
After patch:
Start perf record and then run python...
Reference counter value has been incremented only once:
# dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fff9cbf99d8 )) 2>/dev/null | xxd
0000000: 01 .
Kill perf:
#
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.364 MB perf.data (1427 samples) ]
Reference conter is reset to 0:
# dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fff9cbb99d8 )) 2>/dev/null | xxd
0000000: 00 .
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
kernel/events/uprobes.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 150 insertions(+), 6 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index ed3c588..279c8fc 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -69,6 +69,20 @@ enum {
REF_CTR_OFFSET
};
+/*
+ * List of {consumer, mm} tupple. Unlike uprobe->consumers,
+ * uc is not a list here. It's just a single consumer. Ex,
+ * if there are 2 consumers and 3 target mms for a uprobe,
+ * total number of elements in uprobe->sml = 2 * 3 = 6. This
+ * list is used to ensure reference counter increment and
+ * decrement happen in sync.
+ */
+struct sdt_mm_list {
+ struct list_head list;
+ struct uprobe_consumer *uc;
+ struct mm_struct *mm;
+};
+
struct uprobe {
struct rb_node rb_node; /* node in the rb tree */
atomic_t ref;
@@ -79,6 +93,8 @@ struct uprobe {
struct inode *inode; /* Also hold a ref to inode */
loff_t offset;
loff_t ref_ctr_offset;
+ struct sdt_mm_list sml;
+ struct mutex sml_lock;
unsigned long flags;
/*
@@ -503,6 +519,8 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset,
uprobe->ref_ctr_offset = ref_ctr_offset;
init_rwsem(&uprobe->register_rwsem);
init_rwsem(&uprobe->consumer_rwsem);
+ mutex_init(&uprobe->sml_lock);
+ INIT_LIST_HEAD(&(uprobe->sml.list));
/* add to uprobes_tree, sorted on inode:offset */
cur_uprobe = insert_uprobe(uprobe);
@@ -848,6 +866,49 @@ static inline struct map_info *free_map_info(struct map_info *info)
return err;
}
+static bool sdt_check_mm_list(struct uprobe *uprobe, struct mm_struct *mm,
+ struct uprobe_consumer *uc)
+{
+ struct sdt_mm_list *sml;
+
+ list_for_each_entry(sml, &(uprobe->sml.list), list)
+ if (sml->mm == mm && sml->uc == uc)
+ return true;
+
+ return false;
+}
+
+static int sdt_add_mm_list(struct uprobe *uprobe, struct mm_struct *mm,
+ struct uprobe_consumer *uc)
+{
+ struct sdt_mm_list *sml = kzalloc(sizeof(*sml), GFP_KERNEL);
+
+ if (!sml) {
+ pr_info("Failed to add mm into list.\n");
+ return -ENOMEM;
+ }
+
+ sml->mm = mm;
+ sml->uc = uc;
+ list_add(&(sml->list), &(uprobe->sml.list));
+ return 0;
+}
+
+static void sdt_del_mm_list(struct uprobe *uprobe, struct mm_struct *mm,
+ struct uprobe_consumer *uc)
+{
+ struct list_head *pos, *q;
+ struct sdt_mm_list *sml;
+
+ list_for_each_safe(pos, q, &(uprobe->sml.list)) {
+ sml = list_entry(pos, struct sdt_mm_list, list);
+ if (sml->mm == mm && sml->uc == uc) {
+ list_del(pos);
+ kfree(sml);
+ }
+ }
+}
+
static bool sdt_valid_vma(struct uprobe *uprobe,
struct vm_area_struct *vma,
unsigned long vaddr)
@@ -917,7 +978,8 @@ static struct vm_area_struct *sdt_find_vma(struct uprobe *uprobe,
return ret;
}
-static int sdt_increment_ref_ctr(struct uprobe *uprobe)
+static int
+sdt_increment_ref_ctr(struct uprobe *uprobe, struct uprobe_consumer *uc)
{
struct map_info *info, *first = NULL;
int ctr = 0, ret = 0, tmp = 0;
@@ -934,16 +996,35 @@ static int sdt_increment_ref_ctr(struct uprobe *uprobe)
first = info;
while (info) {
down_write(&info->mm->mmap_sem);
+ mutex_lock(&uprobe->sml_lock);
+
+ if (sdt_check_mm_list(uprobe, info->mm, uc)) {
+ mutex_unlock(&uprobe->sml_lock);
+ up_write(&info->mm->mmap_sem);
+ info = info->next;
+ continue;
+ }
+
if (sdt_find_vma(uprobe, info->mm, info->vaddr)) {
ret = sdt_update_ref_ctr(info->mm, info->vaddr, 1);
if (unlikely(ret)) {
+ mutex_unlock(&uprobe->sml_lock);
+ up_write(&info->mm->mmap_sem);
+ goto rollback;
+ }
+
+ ctr++;
+
+ ret = sdt_add_mm_list(uprobe, info->mm, uc);
+ if (unlikely(ret)) {
+ mutex_unlock(&uprobe->sml_lock);
up_write(&info->mm->mmap_sem);
goto rollback;
}
}
+ mutex_unlock(&uprobe->sml_lock);
up_write(&info->mm->mmap_sem);
info = info->next;
- ctr++;
}
ret = 0;
goto out;
@@ -956,11 +1037,15 @@ static int sdt_increment_ref_ctr(struct uprobe *uprobe)
info = first;
while (ctr) {
down_write(&info->mm->mmap_sem);
+ mutex_lock(&uprobe->sml_lock);
if (sdt_find_vma(uprobe, info->mm, info->vaddr)) {
tmp = sdt_update_ref_ctr(info->mm, info->vaddr, -1);
if (unlikely(tmp))
pr_warn("ref_ctr rollback failed. (%d)\n", tmp);
+
+ sdt_del_mm_list(uprobe, info->mm, uc);
}
+ mutex_unlock(&uprobe->sml_lock);
up_write(&info->mm->mmap_sem);
info = info->next;
ctr--;
@@ -977,7 +1062,12 @@ static int sdt_increment_ref_ctr(struct uprobe *uprobe)
return ret;
}
-static int sdt_decrement_ref_ctr(struct uprobe *uprobe)
+/*
+ * We don't check presence of {uc,mm} in sml here. We just decrement
+ * the reference counter if we find vma holding the reference counter.
+ */
+static int
+sdt_decrement_ref_ctr(struct uprobe *uprobe, struct uprobe_consumer *uc)
{
struct map_info *info;
int ret = 0, err = 0;
@@ -990,6 +1080,7 @@ static int sdt_decrement_ref_ctr(struct uprobe *uprobe)
while (info) {
down_write(&info->mm->mmap_sem);
+ mutex_lock(&uprobe->sml_lock);
if (sdt_find_vma(uprobe, info->mm, info->vaddr)) {
ret = sdt_update_ref_ctr(info->mm, info->vaddr, -1);
@@ -997,6 +1088,8 @@ static int sdt_decrement_ref_ctr(struct uprobe *uprobe)
err = !err && ret ? ret : err;
}
+ sdt_del_mm_list(uprobe, info->mm, uc);
+ mutex_unlock(&uprobe->sml_lock);
up_write(&info->mm->mmap_sem);
mmput(info->mm);
info = free_map_info(info);
@@ -1014,7 +1107,7 @@ static void __uprobe_unregister(struct uprobe *uprobe,
int err;
if (ref_ctr_dec && uprobe->ref_ctr_offset)
- sdt_decrement_ref_ctr(uprobe);
+ sdt_decrement_ref_ctr(uprobe, uc);
if (WARN_ON(!consumer_del(uprobe, uc)))
return;
@@ -1102,7 +1195,7 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
ret = register_for_each_vma(uprobe, uc);
if (!ret && ref_ctr_offset)
- ret = sdt_increment_ref_ctr(uprobe);
+ ret = sdt_increment_ref_ctr(uprobe, uc);
if (ret)
__uprobe_unregister(uprobe, uc, false);
@@ -1258,6 +1351,26 @@ static void build_probe_list(struct inode *inode, int off_type,
spin_unlock(&uprobes_treelock);
}
+static int __sdt_uprobe_mmap(struct uprobe *uprobe, struct mm_struct *mm,
+ unsigned long vaddr, struct uprobe_consumer *uc)
+{
+ int ret;
+
+ if (sdt_check_mm_list(uprobe, mm, uc))
+ return 0;
+
+ ret = sdt_update_ref_ctr(mm, vaddr, 1);
+ if (unlikely(ret))
+ return ret;
+
+ ret = sdt_add_mm_list(uprobe, mm, uc);
+ if (likely(!ret))
+ return ret;
+
+ /* Failed to add mm into the list. Rollback ref_ctr update */
+ return sdt_update_ref_ctr(mm, vaddr, -1);
+}
+
/* Called with down_write(&vma->vm_mm->mmap_sem) */
static int sdt_uprobe_mmap(struct vm_area_struct *vma, struct inode *inode)
{
@@ -1280,10 +1393,14 @@ static int sdt_uprobe_mmap(struct vm_area_struct *vma, struct inode *inode)
/* Increment reference counter for each consumer. */
down_read(&uprobe->consumer_rwsem);
+ mutex_lock(&uprobe->sml_lock);
+
for (uc = uprobe->consumers; uc; uc = uc->next) {
- ret = sdt_update_ref_ctr(vma->vm_mm, vaddr, 1);
+ ret = __sdt_uprobe_mmap(uprobe, vma->vm_mm, vaddr, uc);
err = !err && ret ? ret : err;
}
+
+ mutex_unlock(&uprobe->sml_lock);
up_read(&uprobe->consumer_rwsem);
put_uprobe(uprobe);
}
@@ -1477,6 +1594,29 @@ static struct xol_area *get_xol_area(void)
return area;
}
+static void sdt_mm_release(struct rb_node *n, struct mm_struct *mm)
+{
+ struct uprobe *uprobe;
+ struct uprobe_consumer *uc;
+
+ if (!n)
+ return;
+
+ uprobe = rb_entry(n, struct uprobe, rb_node);
+
+ down_read(&uprobe->consumer_rwsem);
+ mutex_lock(&uprobe->sml_lock);
+
+ for (uc = uprobe->consumers; uc; uc = uc->next)
+ sdt_del_mm_list(uprobe, mm, uc);
+
+ mutex_unlock(&uprobe->sml_lock);
+ up_read(&uprobe->consumer_rwsem);
+
+ sdt_mm_release(n->rb_left, mm);
+ sdt_mm_release(n->rb_right, mm);
+}
+
/*
* uprobe_clear_state - Free the area allocated for slots.
*/
@@ -1484,6 +1624,10 @@ void uprobe_clear_state(struct mm_struct *mm)
{
struct xol_area *area = mm->uprobes_state.xol_area;
+ spin_lock(&uprobes_treelock);
+ sdt_mm_release(uprobes_tree.rb_node, mm);
+ spin_unlock(&uprobes_treelock);
+
if (!area)
return;
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 5/7] Uprobes/sdt: Prevent multiple reference counter for same uprobe
From: Ravi Bangoria @ 2018-06-06 8:33 UTC (permalink / raw)
To: oleg, srikar, rostedt, mhiramat
Cc: peterz, mingo, acme, alexander.shishkin, jolsa, namhyung,
linux-kernel, corbet, linux-doc, ananth, alexis.berlemont,
naveen.n.rao, Ravi Bangoria
In-Reply-To: <20180606083344.31320-1-ravi.bangoria@linux.ibm.com>
Even if we don't allow to create same uprobe with different reference
counter offset via trace_uprobe, user can still create such uprobes
by creating one uprobe using trace_uprobe and other by directly
calling uprobe_register() from kernel module. Prevent such scenarios.
Note that, we are restricting user to not use both ways (trace_uprobe
and kernel module) simultaneously. Ex, User can not trace single uprobe
(with reference counter) simultaneously with Systemtap and perf at the
same time.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
kernel/events/uprobes.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 279c8fc..5e07f99 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -526,6 +526,12 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset,
cur_uprobe = insert_uprobe(uprobe);
/* a uprobe exists for this inode:offset combination */
if (cur_uprobe) {
+ if (cur_uprobe->ref_ctr_offset != uprobe->ref_ctr_offset) {
+ pr_warn("Err: Reference counter mismatch.\n");
+ put_uprobe(cur_uprobe);
+ kfree(uprobe);
+ return ERR_PTR(-EINVAL);
+ }
kfree(uprobe);
uprobe = cur_uprobe;
}
@@ -1184,6 +1190,9 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
uprobe = alloc_uprobe(inode, offset, ref_ctr_offset);
if (!uprobe)
return -ENOMEM;
+ if (IS_ERR(uprobe))
+ return PTR_ERR(uprobe);
+
/*
* We can race with uprobe_unregister()->delete_uprobe().
* Check uprobe_is_active() and retry if it is false.
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 7/7] perf probe: Support SDT markers having reference counter (semaphore)
From: Ravi Bangoria @ 2018-06-06 8:33 UTC (permalink / raw)
To: oleg, srikar, rostedt, mhiramat
Cc: peterz, mingo, acme, alexander.shishkin, jolsa, namhyung,
linux-kernel, corbet, linux-doc, ananth, alexis.berlemont,
naveen.n.rao, Ravi Bangoria
In-Reply-To: <20180606083344.31320-1-ravi.bangoria@linux.ibm.com>
With this, perf buildid-cache will save SDT markers with reference
counter in probe cache. Perf probe will be able to probe markers
having reference counter. Ex,
# readelf -n /tmp/tick | grep -A1 loop2
Name: loop2
... Semaphore: 0x0000000010020036
# ./perf buildid-cache --add /tmp/tick
# ./perf probe sdt_tick:loop2
# ./perf stat -e sdt_tick:loop2 /tmp/tick
hi: 0
hi: 1
hi: 2
^C
Performance counter stats for '/tmp/tick':
3 sdt_tick:loop2
2.561851452 seconds time elapsed
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
---
tools/perf/util/probe-event.c | 39 ++++++++++++++++++++++++++++++++----
tools/perf/util/probe-event.h | 1 +
tools/perf/util/probe-file.c | 34 ++++++++++++++++++++++++++------
tools/perf/util/probe-file.h | 1 +
tools/perf/util/symbol-elf.c | 46 ++++++++++++++++++++++++++++++++-----------
tools/perf/util/symbol.h | 7 +++++++
6 files changed, 106 insertions(+), 22 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 3094f11..0911c9f 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1820,6 +1820,12 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
tp->offset = strtoul(fmt2_str, NULL, 10);
}
+ if (tev->uprobes) {
+ fmt2_str = strchr(p, '(');
+ if (fmt2_str)
+ tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0);
+ }
+
tev->nargs = argc - 2;
tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
if (tev->args == NULL) {
@@ -2013,6 +2019,22 @@ static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
return err;
}
+static int
+synthesize_uprobe_trace_def(struct probe_trace_event *tev, struct strbuf *buf)
+{
+ struct probe_trace_point *tp = &tev->point;
+ int err;
+
+ err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address);
+
+ if (err >= 0 && tp->ref_ctr_offset) {
+ if (!uprobe_ref_ctr_is_supported())
+ return -1;
+ err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset);
+ }
+ return err >= 0 ? 0 : -1;
+}
+
char *synthesize_probe_trace_command(struct probe_trace_event *tev)
{
struct probe_trace_point *tp = &tev->point;
@@ -2042,15 +2064,17 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
}
/* Use the tp->address for uprobes */
- if (tev->uprobes)
- err = strbuf_addf(&buf, "%s:0x%lx", tp->module, tp->address);
- else if (!strncmp(tp->symbol, "0x", 2))
+ if (tev->uprobes) {
+ err = synthesize_uprobe_trace_def(tev, &buf);
+ } else if (!strncmp(tp->symbol, "0x", 2)) {
/* Absolute address. See try_to_find_absolute_address() */
err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "",
tp->module ? ":" : "", tp->address);
- else
+ } else {
err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "",
tp->module ? ":" : "", tp->symbol, tp->offset);
+ }
+
if (err)
goto error;
@@ -2634,6 +2658,13 @@ static void warn_uprobe_event_compat(struct probe_trace_event *tev)
{
int i;
char *buf = synthesize_probe_trace_command(tev);
+ struct probe_trace_point *tp = &tev->point;
+
+ if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) {
+ pr_warning("A semaphore is associated with %s:%s and "
+ "seems your kernel doesn't support it.\n",
+ tev->group, tev->event);
+ }
/* Old uprobe event doesn't support memory dereference */
if (!tev->uprobes || tev->nargs == 0 || !buf)
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 45b14f0..15a98c3 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -27,6 +27,7 @@ struct probe_trace_point {
char *symbol; /* Base symbol */
char *module; /* Module name */
unsigned long offset; /* Offset from symbol */
+ unsigned long ref_ctr_offset; /* SDT reference counter offset */
unsigned long address; /* Actual address of the trace point */
bool retprobe; /* Return probe flag */
};
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index b76088f..aac7817 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -696,8 +696,16 @@ int probe_cache__add_entry(struct probe_cache *pcache,
#ifdef HAVE_GELF_GETNOTE_SUPPORT
static unsigned long long sdt_note__get_addr(struct sdt_note *note)
{
- return note->bit32 ? (unsigned long long)note->addr.a32[0]
- : (unsigned long long)note->addr.a64[0];
+ return note->bit32 ?
+ (unsigned long long)note->addr.a32[SDT_NOTE_IDX_LOC] :
+ (unsigned long long)note->addr.a64[SDT_NOTE_IDX_LOC];
+}
+
+static unsigned long long sdt_note__get_ref_ctr_offset(struct sdt_note *note)
+{
+ return note->bit32 ?
+ (unsigned long long)note->addr.a32[SDT_NOTE_IDX_REFCTR] :
+ (unsigned long long)note->addr.a64[SDT_NOTE_IDX_REFCTR];
}
static const char * const type_to_suffix[] = {
@@ -775,14 +783,21 @@ static char *synthesize_sdt_probe_command(struct sdt_note *note,
{
struct strbuf buf;
char *ret = NULL, **args;
- int i, args_count;
+ int i, args_count, err;
+ unsigned long long ref_ctr_offset;
if (strbuf_init(&buf, 32) < 0)
return NULL;
- if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
- sdtgrp, note->name, pathname,
- sdt_note__get_addr(note)) < 0)
+ err = strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
+ sdtgrp, note->name, pathname,
+ sdt_note__get_addr(note));
+
+ ref_ctr_offset = sdt_note__get_ref_ctr_offset(note);
+ if (ref_ctr_offset && err >= 0)
+ err = strbuf_addf(&buf, "(0x%llx)", ref_ctr_offset);
+
+ if (err < 0)
goto error;
if (!note->args)
@@ -998,6 +1013,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)
enum ftrace_readme {
FTRACE_README_PROBE_TYPE_X = 0,
FTRACE_README_KRETPROBE_OFFSET,
+ FTRACE_README_UPROBE_REF_CTR,
FTRACE_README_END,
};
@@ -1009,6 +1025,7 @@ enum ftrace_readme {
[idx] = {.pattern = pat, .avail = false}
DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
+ DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"),
};
static bool scan_ftrace_readme(enum ftrace_readme type)
@@ -1064,3 +1081,8 @@ bool kretprobe_offset_is_supported(void)
{
return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
}
+
+bool uprobe_ref_ctr_is_supported(void)
+{
+ return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR);
+}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index 63f29b1..2a24918 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -69,6 +69,7 @@ struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache,
int probe_cache__show_all_caches(struct strfilter *filter);
bool probe_type_is_available(enum probe_type type);
bool kretprobe_offset_is_supported(void);
+bool uprobe_ref_ctr_is_supported(void);
#else /* ! HAVE_LIBELF_SUPPORT */
static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused)
{
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 29770ea..0281d5e 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1947,6 +1947,34 @@ void kcore_extract__delete(struct kcore_extract *kce)
}
#ifdef HAVE_GELF_GETNOTE_SUPPORT
+
+static void sdt_adjust_loc(struct sdt_note *tmp, GElf_Addr base_off)
+{
+ if (!base_off)
+ return;
+
+ if (tmp->bit32)
+ tmp->addr.a32[SDT_NOTE_IDX_LOC] =
+ tmp->addr.a32[SDT_NOTE_IDX_LOC] + base_off -
+ tmp->addr.a32[SDT_NOTE_IDX_BASE];
+ else
+ tmp->addr.a64[SDT_NOTE_IDX_LOC] =
+ tmp->addr.a64[SDT_NOTE_IDX_LOC] + base_off -
+ tmp->addr.a64[SDT_NOTE_IDX_BASE];
+}
+
+static void sdt_adjust_refctr(struct sdt_note *tmp, GElf_Addr base_addr,
+ GElf_Addr base_off)
+{
+ if (!base_off)
+ return;
+
+ if (tmp->bit32 && tmp->addr.a32[SDT_NOTE_IDX_REFCTR])
+ tmp->addr.a32[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
+ else if (tmp->addr.a64[SDT_NOTE_IDX_REFCTR])
+ tmp->addr.a64[SDT_NOTE_IDX_REFCTR] -= (base_addr - base_off);
+}
+
/**
* populate_sdt_note : Parse raw data and identify SDT note
* @elf: elf of the opened file
@@ -1964,7 +1992,6 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
const char *provider, *name, *args;
struct sdt_note *tmp = NULL;
GElf_Ehdr ehdr;
- GElf_Addr base_off = 0;
GElf_Shdr shdr;
int ret = -EINVAL;
@@ -2060,17 +2087,12 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len,
* base address in the description of the SDT note. If its different,
* then accordingly, adjust the note location.
*/
- if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL)) {
- base_off = shdr.sh_offset;
- if (base_off) {
- if (tmp->bit32)
- tmp->addr.a32[0] = tmp->addr.a32[0] + base_off -
- tmp->addr.a32[1];
- else
- tmp->addr.a64[0] = tmp->addr.a64[0] + base_off -
- tmp->addr.a64[1];
- }
- }
+ if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_BASE_SCN, NULL))
+ sdt_adjust_loc(tmp, shdr.sh_offset);
+
+ /* Adjust reference counter offset */
+ if (elf_section_by_name(*elf, &ehdr, &shdr, SDT_PROBES_SCN, NULL))
+ sdt_adjust_refctr(tmp, shdr.sh_addr, shdr.sh_offset);
list_add_tail(&tmp->note_list, sdt_notes);
return 0;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 1a16438..61ed90c 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -382,12 +382,19 @@ struct sdt_note {
int cleanup_sdt_note_list(struct list_head *sdt_notes);
int sdt_notes__get_count(struct list_head *start);
+#define SDT_PROBES_SCN ".probes"
#define SDT_BASE_SCN ".stapsdt.base"
#define SDT_NOTE_SCN ".note.stapsdt"
#define SDT_NOTE_TYPE 3
#define SDT_NOTE_NAME "stapsdt"
#define NR_ADDR 3
+enum {
+ SDT_NOTE_IDX_LOC = 0,
+ SDT_NOTE_IDX_BASE,
+ SDT_NOTE_IDX_REFCTR,
+};
+
struct mem_info *mem_info__new(void);
struct mem_info *mem_info__get(struct mem_info *mi);
void mem_info__put(struct mem_info *mi);
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 6/7] Uprobes/sdt: Document about reference counter
From: Ravi Bangoria @ 2018-06-06 8:33 UTC (permalink / raw)
To: oleg, srikar, rostedt, mhiramat
Cc: peterz, mingo, acme, alexander.shishkin, jolsa, namhyung,
linux-kernel, corbet, linux-doc, ananth, alexis.berlemont,
naveen.n.rao, Ravi Bangoria
In-Reply-To: <20180606083344.31320-1-ravi.bangoria@linux.ibm.com>
Reference counter gate the invocation of probe. If present,
by default reference count is 0. Kernel needs to increment
it before tracing the probe and decrement it when done. This
is identical to semaphore in Userspace Statically Defined
Tracepoints (USDT).
Document usage of reference counter.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
---
Documentation/trace/uprobetracer.rst | 16 +++++++++++++---
kernel/trace/trace.c | 2 +-
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/Documentation/trace/uprobetracer.rst b/Documentation/trace/uprobetracer.rst
index 98d3f69..0c27c65 100644
--- a/Documentation/trace/uprobetracer.rst
+++ b/Documentation/trace/uprobetracer.rst
@@ -22,15 +22,25 @@ Synopsis of uprobe_tracer
-------------------------
::
- p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a uprobe
- r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe)
- -:[GRP/]EVENT : Clear uprobe or uretprobe event
+ p[:[GRP/]EVENT] PATH:OFFSET[(REF_CTR_OFFSET)] [FETCHARGS]
+ r[:[GRP/]EVENT] PATH:OFFSET[(REF_CTR_OFFSET)] [FETCHARGS]
+ -:[GRP/]EVENT
+
+ p : Set a uprobe
+ r : Set a return uprobe (uretprobe)
+ - : Clear uprobe or uretprobe event
GRP : Group name. If omitted, "uprobes" is the default value.
EVENT : Event name. If omitted, the event name is generated based
on PATH+OFFSET.
PATH : Path to an executable or a library.
OFFSET : Offset where the probe is inserted.
+ REF_CTR_OFFSET: Reference counter offset. Optional field. Reference count
+ gate the invocation of probe. If present, by default
+ reference count is 0. Kernel needs to increment it before
+ tracing the probe and decrement it when done. This is
+ identical to semaphore in Userspace Statically Defined
+ Tracepoints (USDT).
FETCHARGS : Arguments. Each probe can have up to 128 args.
%REG : Fetch register REG
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index bcd9303..f85639b 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4616,7 +4616,7 @@ static int tracing_trace_options_open(struct inode *inode, struct file *file)
"place (kretprobe): [<module>:]<symbol>[+<offset>]|<memaddr>\n"
#endif
#ifdef CONFIG_UPROBE_EVENTS
- "\t place: <path>:<offset>\n"
+ " place (uprobe): <path>:<offset>[(ref_ctr_offset)]\n"
#endif
"\t args: <name>=fetcharg[:type]\n"
"\t fetcharg: %<register>, @<address>, @<symbol>[+|-<offset>],\n"
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/7] Uprobes: Simplify uprobe_register() body
From: Ravi Bangoria @ 2018-06-06 8:33 UTC (permalink / raw)
To: oleg, srikar, rostedt, mhiramat
Cc: peterz, mingo, acme, alexander.shishkin, jolsa, namhyung,
linux-kernel, corbet, linux-doc, ananth, alexis.berlemont,
naveen.n.rao, Ravi Bangoria
In-Reply-To: <20180606083344.31320-1-ravi.bangoria@linux.ibm.com>
Simplify uprobe_register() function body and let __uprobe_register()
handle everything. Also move dependency functions around to fix build
failures.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
kernel/events/uprobes.c | 69 ++++++++++++++++++++++++++-----------------------
1 file changed, 36 insertions(+), 33 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 1725b90..c377a85 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -840,13 +840,8 @@ static inline struct map_info *free_map_info(struct map_info *info)
return err;
}
-static int __uprobe_register(struct uprobe *uprobe, struct uprobe_consumer *uc)
-{
- consumer_add(uprobe, uc);
- return register_for_each_vma(uprobe, uc);
-}
-
-static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc)
+static void
+__uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc)
{
int err;
@@ -860,24 +855,46 @@ static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *u
}
/*
- * uprobe_register - register a probe
+ * uprobe_unregister - unregister a already registered probe.
+ * @inode: the file in which the probe has to be removed.
+ * @offset: offset from the start of the file.
+ * @uc: identify which probe if multiple probes are colocated.
+ */
+void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
+{
+ struct uprobe *uprobe;
+
+ uprobe = find_uprobe(inode, offset);
+ if (WARN_ON(!uprobe))
+ return;
+
+ down_write(&uprobe->register_rwsem);
+ __uprobe_unregister(uprobe, uc);
+ up_write(&uprobe->register_rwsem);
+ put_uprobe(uprobe);
+}
+EXPORT_SYMBOL_GPL(uprobe_unregister);
+
+/*
+ * __uprobe_register - register a probe
* @inode: the file in which the probe has to be placed.
* @offset: offset from the start of the file.
* @uc: information on howto handle the probe..
*
- * Apart from the access refcount, uprobe_register() takes a creation
+ * Apart from the access refcount, __uprobe_register() takes a creation
* refcount (thro alloc_uprobe) if and only if this @uprobe is getting
* inserted into the rbtree (i.e first consumer for a @inode:@offset
* tuple). Creation refcount stops uprobe_unregister from freeing the
* @uprobe even before the register operation is complete. Creation
* refcount is released when the last @uc for the @uprobe
- * unregisters. Caller of uprobe_register() is required to keep @inode
+ * unregisters. Caller of __uprobe_register() is required to keep @inode
* (and the containing mount) referenced.
*
* Return errno if it cannot successully install probes
* else return 0 (success)
*/
-int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
+static int __uprobe_register(struct inode *inode, loff_t offset,
+ struct uprobe_consumer *uc)
{
struct uprobe *uprobe;
int ret;
@@ -904,7 +921,8 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
down_write(&uprobe->register_rwsem);
ret = -EAGAIN;
if (likely(uprobe_is_active(uprobe))) {
- ret = __uprobe_register(uprobe, uc);
+ consumer_add(uprobe, uc);
+ ret = register_for_each_vma(uprobe, uc);
if (ret)
__uprobe_unregister(uprobe, uc);
}
@@ -915,6 +933,12 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
goto retry;
return ret;
}
+
+int uprobe_register(struct inode *inode, loff_t offset,
+ struct uprobe_consumer *uc)
+{
+ return __uprobe_register(inode, offset, uc);
+}
EXPORT_SYMBOL_GPL(uprobe_register);
/*
@@ -946,27 +970,6 @@ int uprobe_apply(struct inode *inode, loff_t offset,
return ret;
}
-/*
- * uprobe_unregister - unregister a already registered probe.
- * @inode: the file in which the probe has to be removed.
- * @offset: offset from the start of the file.
- * @uc: identify which probe if multiple probes are colocated.
- */
-void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
-{
- struct uprobe *uprobe;
-
- uprobe = find_uprobe(inode, offset);
- if (WARN_ON(!uprobe))
- return;
-
- down_write(&uprobe->register_rwsem);
- __uprobe_unregister(uprobe, uc);
- up_write(&uprobe->register_rwsem);
- put_uprobe(uprobe);
-}
-EXPORT_SYMBOL_GPL(uprobe_unregister);
-
static int unapply_uprobe(struct uprobe *uprobe, struct mm_struct *mm)
{
struct vm_area_struct *vma;
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 2/7] Uprobes: Support SDT markers having reference count (semaphore)
From: Ravi Bangoria @ 2018-06-06 8:33 UTC (permalink / raw)
To: oleg, srikar, rostedt, mhiramat
Cc: peterz, mingo, acme, alexander.shishkin, jolsa, namhyung,
linux-kernel, corbet, linux-doc, ananth, alexis.berlemont,
naveen.n.rao, Ravi Bangoria
In-Reply-To: <20180606083344.31320-1-ravi.bangoria@linux.ibm.com>
Userspace Statically Defined Tracepoints[1] are dtrace style markers
inside userspace applications. Applications like PostgreSQL, MySQL,
Pthread, Perl, Python, Java, Ruby, Node.js, libvirt, QEMU, glib etc
have these markers embedded in them. These markers are added by developer
at important places in the code. Each marker source expands to a single
nop instruction in the compiled code but there may be additional
overhead for computing the marker arguments which expands to couple of
instructions. In case the overhead is more, execution of it can be
omitted by runtime if() condition when no one is tracing on the marker:
if (reference_counter > 0) {
Execute marker instructions;
}
Default value of reference counter is 0. Tracer has to increment the
reference counter before tracing on a marker and decrement it when
done with the tracing. Implement the reference counter logic in Uprobe.
New function uprobe_register_refctr() has been added for this. Also,
it's not exported so, for now, the interface to use reference counter
is only through trace_uprobe.
trace_uprobe definition with reference counter will now be:
<path>:<offset>[(ref_ctr_offset)]
where ref_ctr_offset is an optional field.
[1] https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation
Note: 'reference counter' is called as 'semaphore' in original Dtrace
(or Systemtap, bcc and even in ELF) documentation and code. But the
term 'semaphore' is misleading in this context. This is just a counter
used to hold number of tracers tracing on a marker. This is not really
used for any synchronization. So we are referring it as 'reference
counter' in kernel / perf code.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
include/linux/uprobes.h | 5 +
kernel/events/uprobes.c | 298 +++++++++++++++++++++++++++++++++++++++-----
kernel/trace/trace_uprobe.c | 38 +++++-
3 files changed, 309 insertions(+), 32 deletions(-)
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index 0a294e9..58666c6 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -123,6 +123,7 @@ struct uprobes_state {
extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs);
extern int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t);
extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
+extern int uprobe_register_refctr(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, loff_t ref_ctr_offset);
extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool);
extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
extern int uprobe_mmap(struct vm_area_struct *vma);
@@ -160,6 +161,10 @@ struct uprobes_state {
{
return -ENOSYS;
}
+static inline int uprobe_register_refctr(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, unsigned long ref_ctr_offset)
+{
+ return -ENOSYS;
+}
static inline int
uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool add)
{
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index c377a85..ed3c588 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -64,6 +64,11 @@
/* Have a copy of original instruction */
#define UPROBE_COPY_INSN 0
+enum {
+ UPROBE_OFFSET = 0,
+ REF_CTR_OFFSET
+};
+
struct uprobe {
struct rb_node rb_node; /* node in the rb tree */
atomic_t ref;
@@ -73,6 +78,7 @@ struct uprobe {
struct uprobe_consumer *consumers;
struct inode *inode; /* Also hold a ref to inode */
loff_t offset;
+ loff_t ref_ctr_offset;
unsigned long flags;
/*
@@ -483,7 +489,8 @@ static struct uprobe *insert_uprobe(struct uprobe *uprobe)
return u;
}
-static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
+static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset,
+ loff_t ref_ctr_offset)
{
struct uprobe *uprobe, *cur_uprobe;
@@ -493,6 +500,7 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
uprobe->inode = inode;
uprobe->offset = offset;
+ uprobe->ref_ctr_offset = ref_ctr_offset;
init_rwsem(&uprobe->register_rwsem);
init_rwsem(&uprobe->consumer_rwsem);
@@ -840,11 +848,174 @@ static inline struct map_info *free_map_info(struct map_info *info)
return err;
}
-static void
-__uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc)
+static bool sdt_valid_vma(struct uprobe *uprobe,
+ struct vm_area_struct *vma,
+ unsigned long vaddr)
+{
+ return uprobe->ref_ctr_offset &&
+ vma->vm_file &&
+ file_inode(vma->vm_file) == uprobe->inode &&
+ vma->vm_flags & VM_WRITE &&
+ vma->vm_start <= vaddr &&
+ vma->vm_end > vaddr;
+}
+
+static struct vm_area_struct *sdt_find_vma(struct uprobe *uprobe,
+ struct mm_struct *mm,
+ unsigned long vaddr)
+{
+ struct vm_area_struct *vma = find_vma(mm, vaddr);
+
+ return (vma && sdt_valid_vma(uprobe, vma, vaddr)) ? vma : NULL;
+}
+
+/*
+ * Reference counter gate the invocation of probe. If present,
+ * by default reference counter is 0. One needs to increment
+ * it before tracing the probe and decrement it when done.
+ */
+static int
+sdt_update_ref_ctr(struct mm_struct *mm, unsigned long vaddr, short d)
+{
+ void *kaddr;
+ struct page *page;
+ struct vm_area_struct *vma;
+ int ret = 0;
+ short *ptr;
+
+ if (vaddr == 0 || d == 0)
+ return -EINVAL;
+
+ ret = get_user_pages_remote(NULL, mm, vaddr, 1,
+ FOLL_FORCE | FOLL_WRITE, &page, &vma, NULL);
+ if (unlikely(ret <= 0)) {
+ /*
+ * We are asking for 1 page. If get_user_pages_remote() fails,
+ * it may return 0, in that case we have to return error.
+ */
+ ret = (ret == 0) ? -EBUSY : ret;
+ pr_warn("Failed to %s ref_ctr. (%d)\n",
+ d > 0 ? "increment" : "decrement", ret);
+ return ret;
+ }
+
+ kaddr = kmap_atomic(page);
+ ptr = kaddr + (vaddr & ~PAGE_MASK);
+
+ if (unlikely(*ptr + d < 0)) {
+ pr_warn("ref_ctr going negative. vaddr: 0x%lx, "
+ "curr val: %d, delta: %d\n", vaddr, *ptr, d);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ *ptr += d;
+ ret = 0;
+out:
+ kunmap_atomic(kaddr);
+ put_page(page);
+ return ret;
+}
+
+static int sdt_increment_ref_ctr(struct uprobe *uprobe)
+{
+ struct map_info *info, *first = NULL;
+ int ctr = 0, ret = 0, tmp = 0;
+
+ percpu_down_write(&dup_mmap_sem);
+
+ info = build_map_info(uprobe->inode->i_mapping,
+ uprobe->ref_ctr_offset, false);
+ if (IS_ERR(info)) {
+ percpu_up_write(&dup_mmap_sem);
+ return PTR_ERR(info);
+ }
+
+ first = info;
+ while (info) {
+ down_write(&info->mm->mmap_sem);
+ if (sdt_find_vma(uprobe, info->mm, info->vaddr)) {
+ ret = sdt_update_ref_ctr(info->mm, info->vaddr, 1);
+ if (unlikely(ret)) {
+ up_write(&info->mm->mmap_sem);
+ goto rollback;
+ }
+ }
+ up_write(&info->mm->mmap_sem);
+ info = info->next;
+ ctr++;
+ }
+ ret = 0;
+ goto out;
+
+rollback:
+ /*
+ * We failed to update reference counter in any one of
+ * the target mm. Rollback alredy updated mms.
+ */
+ info = first;
+ while (ctr) {
+ down_write(&info->mm->mmap_sem);
+ if (sdt_find_vma(uprobe, info->mm, info->vaddr)) {
+ tmp = sdt_update_ref_ctr(info->mm, info->vaddr, -1);
+ if (unlikely(tmp))
+ pr_warn("ref_ctr rollback failed. (%d)\n", tmp);
+ }
+ up_write(&info->mm->mmap_sem);
+ info = info->next;
+ ctr--;
+ }
+
+out:
+ info = first;
+ while (info) {
+ mmput(info->mm);
+ info = free_map_info(info);
+ }
+
+ percpu_up_write(&dup_mmap_sem);
+ return ret;
+}
+
+static int sdt_decrement_ref_ctr(struct uprobe *uprobe)
+{
+ struct map_info *info;
+ int ret = 0, err = 0;
+
+ percpu_down_write(&dup_mmap_sem);
+ info = build_map_info(uprobe->inode->i_mapping,
+ uprobe->ref_ctr_offset, false);
+ if (IS_ERR(info))
+ goto out;
+
+ while (info) {
+ down_write(&info->mm->mmap_sem);
+
+ if (sdt_find_vma(uprobe, info->mm, info->vaddr)) {
+ ret = sdt_update_ref_ctr(info->mm, info->vaddr, -1);
+ /* Save error and continue. */
+ err = !err && ret ? ret : err;
+ }
+
+ up_write(&info->mm->mmap_sem);
+ mmput(info->mm);
+ info = free_map_info(info);
+ }
+
+out:
+ percpu_up_write(&dup_mmap_sem);
+ return err;
+}
+
+static void __uprobe_unregister(struct uprobe *uprobe,
+ struct uprobe_consumer *uc,
+ bool ref_ctr_dec)
{
int err;
+ if (ref_ctr_dec && uprobe->ref_ctr_offset)
+ sdt_decrement_ref_ctr(uprobe);
+
if (WARN_ON(!consumer_del(uprobe, uc)))
return;
@@ -869,7 +1040,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume
return;
down_write(&uprobe->register_rwsem);
- __uprobe_unregister(uprobe, uc);
+ __uprobe_unregister(uprobe, uc, true);
up_write(&uprobe->register_rwsem);
put_uprobe(uprobe);
}
@@ -880,21 +1051,27 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume
* @inode: the file in which the probe has to be placed.
* @offset: offset from the start of the file.
* @uc: information on howto handle the probe..
+ * @ref_ctr_offset: Reference counter offset
*
* Apart from the access refcount, __uprobe_register() takes a creation
* refcount (thro alloc_uprobe) if and only if this @uprobe is getting
- * inserted into the rbtree (i.e first consumer for a @inode:@offset
- * tuple). Creation refcount stops uprobe_unregister from freeing the
- * @uprobe even before the register operation is complete. Creation
- * refcount is released when the last @uc for the @uprobe
- * unregisters. Caller of __uprobe_register() is required to keep @inode
- * (and the containing mount) referenced.
+ * inserted into the rbtree (i.e first consumer for a
+ * @inode:@offset:@ref_ctr_offset tuple). Creation refcount stops
+ * uprobe_unregister from freeing the @uprobe even before the register
+ * operation is complete. Creation refcount is released when the last
+ * @uc for the @uprobe unregisters. Caller of __uprobe_register() is
+ * required to keep @inode (and the containing mount) referenced.
+ *
+ * Note that, 'refcount' and 'ref_ctr_offset' are totally different
+ * entities and each has it's own purpose. 'ref_ctr_offset' is the file
+ * offset of the counter which gates the uprobe and it has nothing to
+ * do with the value of 'refcount'.
*
- * Return errno if it cannot successully install probes
- * else return 0 (success)
+ * Return errno if it cannot successully install probes else return 0
+ * (success).
*/
static int __uprobe_register(struct inode *inode, loff_t offset,
- struct uprobe_consumer *uc)
+ struct uprobe_consumer *uc, loff_t ref_ctr_offset)
{
struct uprobe *uprobe;
int ret;
@@ -907,11 +1084,11 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
if (!inode->i_mapping->a_ops->readpage && !shmem_mapping(inode->i_mapping))
return -EIO;
/* Racy, just to catch the obvious mistakes */
- if (offset > i_size_read(inode))
+ if (offset > i_size_read(inode) || ref_ctr_offset > i_size_read(inode))
return -EINVAL;
retry:
- uprobe = alloc_uprobe(inode, offset);
+ uprobe = alloc_uprobe(inode, offset, ref_ctr_offset);
if (!uprobe)
return -ENOMEM;
/*
@@ -922,9 +1099,13 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
ret = -EAGAIN;
if (likely(uprobe_is_active(uprobe))) {
consumer_add(uprobe, uc);
+
ret = register_for_each_vma(uprobe, uc);
+ if (!ret && ref_ctr_offset)
+ ret = sdt_increment_ref_ctr(uprobe);
+
if (ret)
- __uprobe_unregister(uprobe, uc);
+ __uprobe_unregister(uprobe, uc, false);
}
up_write(&uprobe->register_rwsem);
put_uprobe(uprobe);
@@ -937,10 +1118,17 @@ static int __uprobe_register(struct inode *inode, loff_t offset,
int uprobe_register(struct inode *inode, loff_t offset,
struct uprobe_consumer *uc)
{
- return __uprobe_register(inode, offset, uc);
+ return __uprobe_register(inode, offset, uc, 0);
}
EXPORT_SYMBOL_GPL(uprobe_register);
+/* Currently, the only user of this is trace_uprobe. */
+int uprobe_register_refctr(struct inode *inode, loff_t offset,
+ struct uprobe_consumer *uc, loff_t ref_ctr_offset)
+{
+ return __uprobe_register(inode, offset, uc, ref_ctr_offset);
+}
+
/*
* uprobe_apply - unregister a already registered probe.
* @inode: the file in which the probe has to be removed.
@@ -997,22 +1185,30 @@ static int unapply_uprobe(struct uprobe *uprobe, struct mm_struct *mm)
return err;
}
+static loff_t uprobe_get_offset(struct uprobe *u, int off_type)
+{
+ return (off_type == UPROBE_OFFSET) ? u->offset : u->ref_ctr_offset;
+}
+
static struct rb_node *
-find_node_in_range(struct inode *inode, loff_t min, loff_t max)
+find_node_in_range(struct inode *inode, int off_type, loff_t min, loff_t max)
{
struct rb_node *n = uprobes_tree.rb_node;
+ struct uprobe *u;
+ loff_t offset;
while (n) {
- struct uprobe *u = rb_entry(n, struct uprobe, rb_node);
+ u = rb_entry(n, struct uprobe, rb_node);
+ offset = uprobe_get_offset(u, off_type);
if (inode < u->inode) {
n = n->rb_left;
} else if (inode > u->inode) {
n = n->rb_right;
} else {
- if (max < u->offset)
+ if (max < offset)
n = n->rb_left;
- else if (min > u->offset)
+ else if (min > offset)
n = n->rb_right;
else
break;
@@ -1025,7 +1221,7 @@ static int unapply_uprobe(struct uprobe *uprobe, struct mm_struct *mm)
/*
* For a given range in vma, build a list of probes that need to be inserted.
*/
-static void build_probe_list(struct inode *inode,
+static void build_probe_list(struct inode *inode, int off_type,
struct vm_area_struct *vma,
unsigned long start, unsigned long end,
struct list_head *head)
@@ -1033,24 +1229,27 @@ static void build_probe_list(struct inode *inode,
loff_t min, max;
struct rb_node *n, *t;
struct uprobe *u;
+ loff_t offset;
INIT_LIST_HEAD(head);
min = vaddr_to_offset(vma, start);
max = min + (end - start) - 1;
spin_lock(&uprobes_treelock);
- n = find_node_in_range(inode, min, max);
+ n = find_node_in_range(inode, off_type, min, max);
if (n) {
for (t = n; t; t = rb_prev(t)) {
u = rb_entry(t, struct uprobe, rb_node);
- if (u->inode != inode || u->offset < min)
+ offset = uprobe_get_offset(u, off_type);
+ if (u->inode != inode || offset < min)
break;
list_add(&u->pending_list, head);
get_uprobe(u);
}
for (t = n; (t = rb_next(t)); ) {
u = rb_entry(t, struct uprobe, rb_node);
- if (u->inode != inode || u->offset > max)
+ offset = uprobe_get_offset(u, off_type);
+ if (u->inode != inode || offset > max)
break;
list_add(&u->pending_list, head);
get_uprobe(u);
@@ -1059,6 +1258,39 @@ static void build_probe_list(struct inode *inode,
spin_unlock(&uprobes_treelock);
}
+/* Called with down_write(&vma->vm_mm->mmap_sem) */
+static int sdt_uprobe_mmap(struct vm_area_struct *vma, struct inode *inode)
+{
+ struct list_head tmp_list;
+ struct uprobe *uprobe, *u;
+ struct uprobe_consumer *uc;
+ unsigned long vaddr;
+ int ret = 0, err = 0;
+
+ build_probe_list(inode, REF_CTR_OFFSET, vma, vma->vm_start,
+ vma->vm_end, &tmp_list);
+
+ list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
+ if (!uprobe->ref_ctr_offset || !uprobe_is_active(uprobe))
+ continue;
+
+ vaddr = offset_to_vaddr(vma, uprobe->ref_ctr_offset);
+ if (!sdt_valid_vma(uprobe, vma, vaddr))
+ continue;
+
+ /* Increment reference counter for each consumer. */
+ down_read(&uprobe->consumer_rwsem);
+ for (uc = uprobe->consumers; uc; uc = uc->next) {
+ ret = sdt_update_ref_ctr(vma->vm_mm, vaddr, 1);
+ err = !err && ret ? ret : err;
+ }
+ up_read(&uprobe->consumer_rwsem);
+ put_uprobe(uprobe);
+ }
+
+ return err;
+}
+
/*
* Called from mmap_region/vma_adjust with mm->mmap_sem acquired.
*
@@ -1071,7 +1303,7 @@ int uprobe_mmap(struct vm_area_struct *vma)
struct uprobe *uprobe, *u;
struct inode *inode;
- if (no_uprobe_events() || !valid_vma(vma, true))
+ if (no_uprobe_events())
return 0;
inode = file_inode(vma->vm_file);
@@ -1079,7 +1311,14 @@ int uprobe_mmap(struct vm_area_struct *vma)
return 0;
mutex_lock(uprobes_mmap_hash(inode));
- build_probe_list(inode, vma, vma->vm_start, vma->vm_end, &tmp_list);
+ if (vma->vm_flags & VM_WRITE)
+ sdt_uprobe_mmap(vma, inode);
+
+ if (!valid_vma(vma, true))
+ goto out;
+
+ build_probe_list(inode, UPROBE_OFFSET, vma, vma->vm_start,
+ vma->vm_end, &tmp_list);
/*
* We can race with uprobe_unregister(), this uprobe can be already
* removed. But in this case filter_chain() must return false, all
@@ -1093,8 +1332,9 @@ int uprobe_mmap(struct vm_area_struct *vma)
}
put_uprobe(uprobe);
}
- mutex_unlock(uprobes_mmap_hash(inode));
+out:
+ mutex_unlock(uprobes_mmap_hash(inode));
return 0;
}
@@ -1111,7 +1351,7 @@ int uprobe_mmap(struct vm_area_struct *vma)
max = min + (end - start) - 1;
spin_lock(&uprobes_treelock);
- n = find_node_in_range(inode, min, max);
+ n = find_node_in_range(inode, UPROBE_OFFSET, min, max);
spin_unlock(&uprobes_treelock);
return !!n;
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index ac89287..d5b6ca9 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -59,6 +59,7 @@ struct trace_uprobe {
struct inode *inode;
char *filename;
unsigned long offset;
+ unsigned long ref_ctr_offset;
unsigned long nhit;
struct trace_probe tp;
};
@@ -364,10 +365,10 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
static int create_trace_uprobe(int argc, char **argv)
{
struct trace_uprobe *tu;
- char *arg, *event, *group, *filename;
+ char *arg, *event, *group, *filename, *rctr, *rctr_end;
char buf[MAX_EVENT_NAME_LEN];
struct path path;
- unsigned long offset;
+ unsigned long offset, ref_ctr_offset;
bool is_delete, is_return;
int i, ret;
@@ -376,6 +377,7 @@ static int create_trace_uprobe(int argc, char **argv)
is_return = false;
event = NULL;
group = NULL;
+ ref_ctr_offset = 0;
/* argc must be >= 1 */
if (argv[0][0] == '-')
@@ -450,6 +452,26 @@ static int create_trace_uprobe(int argc, char **argv)
goto fail_address_parse;
}
+ /* Parse reference counter offset if specified. */
+ rctr = strchr(arg, '(');
+ if (rctr) {
+ rctr_end = strchr(rctr, ')');
+ if (rctr > rctr_end || *(rctr_end + 1) != 0) {
+ ret = -EINVAL;
+ pr_info("Invalid reference counter offset.\n");
+ goto fail_address_parse;
+ }
+
+ *rctr++ = '\0';
+ *rctr_end = '\0';
+ ret = kstrtoul(rctr, 0, &ref_ctr_offset);
+ if (ret) {
+ pr_info("Invalid reference counter offset.\n");
+ goto fail_address_parse;
+ }
+ }
+
+ /* Parse uprobe offset. */
ret = kstrtoul(arg, 0, &offset);
if (ret)
goto fail_address_parse;
@@ -484,6 +506,7 @@ static int create_trace_uprobe(int argc, char **argv)
goto fail_address_parse;
}
tu->offset = offset;
+ tu->ref_ctr_offset = ref_ctr_offset;
tu->path = path;
tu->filename = kstrdup(filename, GFP_KERNEL);
@@ -602,6 +625,9 @@ static int probes_seq_show(struct seq_file *m, void *v)
trace_event_name(&tu->tp.call), tu->filename,
(int)(sizeof(void *) * 2), tu->offset);
+ if (tu->ref_ctr_offset)
+ seq_printf(m, "(0x%lx)", tu->ref_ctr_offset);
+
for (i = 0; i < tu->tp.nr_args; i++)
seq_printf(m, " %s=%s", tu->tp.args[i].name, tu->tp.args[i].comm);
@@ -917,7 +943,13 @@ typedef bool (*filter_func_t)(struct uprobe_consumer *self,
tu->consumer.filter = filter;
tu->inode = d_real_inode(tu->path.dentry);
- ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
+ if (tu->ref_ctr_offset) {
+ ret = uprobe_register_refctr(tu->inode, tu->offset,
+ &tu->consumer, tu->ref_ctr_offset);
+ } else {
+ ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
+ }
+
if (ret)
goto err_buffer;
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 4/7] trace_uprobe/sdt: Prevent multiple reference counter for same uprobe
From: Ravi Bangoria @ 2018-06-06 8:33 UTC (permalink / raw)
To: oleg, srikar, rostedt, mhiramat
Cc: peterz, mingo, acme, alexander.shishkin, jolsa, namhyung,
linux-kernel, corbet, linux-doc, ananth, alexis.berlemont,
naveen.n.rao, Ravi Bangoria
In-Reply-To: <20180606083344.31320-1-ravi.bangoria@linux.ibm.com>
Rightnow, there can be multiple trace_uprobes with same inode+offset
but internally they all points to same uprobe. To allow user to
specify multiple ref_ctr_offset for single inode+offset combo, core
uprobe logic has to be changed. It's also unlikely to have more than
one reference counter for single uprobe. Restrict it.
Ex,
# echo "p:sdt_tick/loop2 /home/ravi/tick:0x6e4(0x10036) > uprobe_events
# echo "p:sdt_tick/loop2_1 /home/ravi/tick:0x6e4(0x10030) >> uprobe_events
bash: echo: write error: Invalid argument
# dmesg | tail -1
trace_kprobe: Reference counter offset mismatch.
One exception to this is when user is trying to replace the old entry
with the new one. We allow this if the new entry does not conflict with
any other existing entry.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
kernel/trace/trace_uprobe.c | 36 ++++++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index d5b6ca9..e8914f7 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -324,6 +324,34 @@ static int unregister_trace_uprobe(struct trace_uprobe *tu)
return 0;
}
+/*
+ * Uprobe with multiple reference counter is not allowed. i.e.
+ * If inode and offset matches, reference counter offset *must*
+ * match as well. Only one exception to this is when we are
+ * replacing old trace_uprobe with new one(same group/event).
+ */
+static struct trace_uprobe *find_old_trace_uprobe(struct trace_uprobe *new)
+{
+ struct trace_uprobe *tmp, *old = NULL;
+ struct inode *new_inode = d_real_inode(new->path.dentry);
+
+ old = find_probe_event(trace_event_name(&new->tp.call),
+ new->tp.call.class->system);
+ if (!new->ref_ctr_offset)
+ return old;
+
+ list_for_each_entry(tmp, &uprobe_list, list) {
+ if (new_inode == d_real_inode(tmp->path.dentry) &&
+ new->offset == tmp->offset &&
+ new->ref_ctr_offset != tmp->ref_ctr_offset &&
+ tmp != old) {
+ pr_warn("Reference counter offset mismatch.");
+ return ERR_PTR(-EINVAL);
+ }
+ }
+ return old;
+}
+
/* Register a trace_uprobe and probe_event */
static int register_trace_uprobe(struct trace_uprobe *tu)
{
@@ -333,8 +361,12 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
mutex_lock(&uprobe_lock);
/* register as an event */
- old_tu = find_probe_event(trace_event_name(&tu->tp.call),
- tu->tp.call.class->system);
+ old_tu = find_old_trace_uprobe(tu);
+ if (IS_ERR(old_tu)) {
+ ret = PTR_ERR(old_tu);
+ goto end;
+ }
+
if (old_tu) {
/* delete old event */
ret = unregister_trace_uprobe(old_tu);
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH 0/7] Uprobes: Support SDT markers having reference count (semaphore)
From: Ravi Bangoria @ 2018-06-06 8:35 UTC (permalink / raw)
To: oleg, srikar, rostedt, mhiramat
Cc: peterz, mingo, acme, alexander.shishkin, jolsa, namhyung,
linux-kernel, corbet, linux-doc, ananth, alexis.berlemont,
naveen.n.rao, Ravi Bangoria
In-Reply-To: <20180606083344.31320-1-ravi.bangoria@linux.ibm.com>
On 06/06/2018 02:03 PM, Ravi Bangoria wrote:
> Why RFC again:
>
Please consider this as [RFC]. I just forgot to tag it in the subject.
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC PATCH 0/6] net: ethernet: ti: cpsw: add MQPRIO and CBS Qdisc offload
From: Ivan Khoronzhuk @ 2018-06-06 8:53 UTC (permalink / raw)
To: Vinicius Costa Gomes
Cc: grygorii.strashko, davem, corbet, akpm, netdev, linux-doc,
linux-kernel, linux-omap, henrik, jesus.sanchez-palencia
In-Reply-To: <87602y1n4j.fsf@intel.com>
On Mon, Jun 04, 2018 at 02:23:56PM -0300, Vinicius Costa Gomes wrote:
>Hi Ivan,
>
>Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> writes:
>
>> This series adds MQPRIO and CBS Qdisc offload for TI cpsw driver.
>> It potentially can be used in audio video bridging (AVB) and time
>> sensitive networking (TSN).
>>
>> Patchset was tested on AM572x EVM and BBB boards. Last patch from this
>> series adds detailed description of configuration with examples. For
>> consistency reasons, in role of talker and listener, tools from
>> patchset "TSN: Add qdisc based config interface for CBS" were used and
>> can be seen here: https://www.spinics.net/lists/netdev/msg460869.html
>>
>> Based on net-next/master
>>
>
>I didn't test this, but it looks fine from my side.
>
>I agree with Grygorii, that if no comments, this should be re-sent as a
>patch series next.
Thanks, I'll do it on this week.
>
>
>> Ivan Khoronzhuk (6):
>> net: ethernet: ti: cpsw: use cpdma channels in backward order for txq
>> net: ethernet: ti: cpdma: fit rated channels in backward order
>> net: ethernet: ti: cpsw: add MQPRIO Qdisc offload
>> net: ethernet: ti: cpsw: add CBS Qdisc offload
>> net: ethernet: ti: cpsw: restore shaper configuration while down/up
>> Documentation: networking: cpsw: add MQPRIO & CBS offload examples
>>
>> Documentation/networking/cpsw.txt | 540 ++++++++++++++++++++++++
>> drivers/net/ethernet/ti/cpsw.c | 364 +++++++++++++++-
>> drivers/net/ethernet/ti/davinci_cpdma.c | 31 +-
>> 3 files changed, 913 insertions(+), 22 deletions(-)
>> create mode 100644 Documentation/networking/cpsw.txt
>>
>> --
>> 2.17.0
>
>
>Cheers,
>--
>Vinicius
--
Regards,
Ivan Khoronzhuk
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] docs: atomic_ops: atomic_set is a write (not read) operation
From: Paul E. McKenney @ 2018-06-06 8:07 UTC (permalink / raw)
To: Jonathan Neuschäfer; +Cc: linux-doc, Jonathan Corbet, linux-kernel
In-Reply-To: <20180605194326.23596-1-j.neuschaefer@gmx.net>
On Tue, Jun 05, 2018 at 09:43:23PM +0200, Jonathan Neuschäfer wrote:
> Describe it as such.
>
> Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
I have queued this, but if someone else would prefer to take it:
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> ---
> Documentation/core-api/atomic_ops.rst | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/core-api/atomic_ops.rst b/Documentation/core-api/atomic_ops.rst
> index 2e7165f86f55..724583453e1f 100644
> --- a/Documentation/core-api/atomic_ops.rst
> +++ b/Documentation/core-api/atomic_ops.rst
> @@ -29,7 +29,7 @@ updated by one CPU, local_t is probably more appropriate. Please see
> local_t.
>
> The first operations to implement for atomic_t's are the initializers and
> -plain reads. ::
> +plain writes. ::
>
> #define ATOMIC_INIT(i) { (i) }
> #define atomic_set(v, i) ((v)->counter = (i))
> --
> 2.17.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 52/53] docs-rst: get rid of Documentation/sphinx/tmplcvt script
From: Mauro Carvalho Chehab @ 2017-05-16 12:16 UTC (permalink / raw)
To: Linux Doc Mailing List
Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, linux-kernel,
Jonathan Corbet, David Woodhouse, Brian Norris, Boris Brezillon,
Marek Vasut, Richard Weinberger, Cyrille Pitchen, linux-mtd,
Jani Nikula
In-Reply-To: <cover.1494935649.git.mchehab@s-opensource.com>
As everything was converted to ReST, we don't need this
script anymore.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
Documentation/sphinx/tmplcvt | 28 ----------------------------
1 file changed, 28 deletions(-)
delete mode 100755 Documentation/sphinx/tmplcvt
diff --git a/Documentation/sphinx/tmplcvt b/Documentation/sphinx/tmplcvt
deleted file mode 100755
index 6848f0a26fa5..000000000000
--- a/Documentation/sphinx/tmplcvt
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-#
-# Convert a template file into something like RST
-#
-# fix <function>
-# feed to pandoc
-# fix \_
-# title line?
-#
-set -eu
-
-if [ "$#" != "2" ]; then
- echo "$0 <docbook file> <rst file>"
- exit
-fi
-
-DIR=$(dirname $0)
-
-in=$1
-rst=$2
-tmp=$rst.tmp
-
-cp $in $tmp
-sed --in-place -f $DIR/convert_template.sed $tmp
-pandoc -s -S -f docbook -t rst -o $rst $tmp
-sed --in-place -f $DIR/post_convert.sed $rst
-rm $tmp
-echo "book writen to $rst"
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 51/53] usb: fix the comment with regards to DocBook
From: Mauro Carvalho Chehab @ 2017-05-16 12:16 UTC (permalink / raw)
To: Linux Doc Mailing List
Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, linux-kernel,
Jonathan Corbet, David Woodhouse, Brian Norris, Boris Brezillon,
Marek Vasut, Richard Weinberger, Cyrille Pitchen, linux-mtd,
Felipe Balbi, Greg Kroah-Hartman, linux-usb
In-Reply-To: <cover.1494935649.git.mchehab@s-opensource.com>
The USB gadget documentation is not at DocBook anymore.
The main file was converted to ReST, and stored at
Documentation/driver-api/usb/gadget.rst, but there are
still several plain text files related to gadget under
Documentation/usb.
So, be generic and just mention documentation
without specifying where it is.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
drivers/usb/gadget/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index c164d6b788c3..b3c879b75a39 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -41,7 +41,7 @@ menuconfig USB_GADGET
don't have this kind of hardware (except maybe inside Linux PDAs).
For more information, see <http://www.linux-usb.org/gadget> and
- the kernel DocBook documentation for this API.
+ the kernel documentation for this API.
if USB_GADGET
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox