code:
###############
Timerlat tracer
###############

The timerlat tracer aims to help the preemptive kernel developers to
find sources of wakeup latencies of real-time threads. Like cyclictest,
the tracer sets a periodic timer that wakes up a thread. The thread then
computes a *wakeup latency* value as the difference between the *current
time* and the *absolute time* that the timer was set to expire. The main
goal of timerlat is tracing in such a way to help kernel developers.

Usage
-----

Write the ASCII text "timerlat" into the current_tracer file of the
tracing system (generally mounted at /sys/kernel/tracing).

For example::

        [root@f32 ~]# cd /sys/kernel/tracing/
        [root@f32 tracing]# echo timerlat > current_tracer

It is possible to follow the trace by reading the trace file::

  [root@f32 tracing]# cat trace
  # tracer: timerlat
  #
  #                              _-----=> irqs-off
  #                             / _----=> need-resched
  #                            | / _---=> hardirq/softirq
  #                            || / _--=> preempt-depth
  #                            || /
  #                            ||||             ACTIVATION
  #         TASK-PID      CPU# ||||   TIMESTAMP    ID            CONTEXT                LATENCY
  #            | |         |   ||||      |         |                  |                       |
          <idle>-0       [000] d.h1    54.029328: #1     context    irq timer_latency       932 ns
           <...>-867     [000] ....    54.029339: #1     context thread timer_latency     11700 ns
          <idle>-0       [001] dNh1    54.029346: #1     context    irq timer_latency      2833 ns
           <...>-868     [001] ....    54.029353: #1     context thread timer_latency      9820 ns
          <idle>-0       [000] d.h1    54.030328: #2     context    irq timer_latency       769 ns
           <...>-867     [000] ....    54.030330: #2     context thread timer_latency      3070 ns
          <idle>-0       [001] d.h1    54.030344: #2     context    irq timer_latency       935 ns
           <...>-868     [001] ....    54.030347: #2     context thread timer_latency      4351 ns

The tracer creates a per-cpu kernel thread with real-time priority that
prints two lines at every activation. The first is the *timer latency*
observed at the *hardirq* context before the activation of the thread.
The second is the *timer latency* observed by the thread. The ACTIVATION
ID field serves to relate the *irq* execution to its respective *thread*
execution.

The *irq*/*thread* splitting is important to clarify in which context
the unexpected high value is coming from. The *irq* context can be
delayed by hardware-related actions, such as SMIs, NMIs, IRQs,
or by thread masking interrupts. Once the timer happens, the delay
can also be influenced by blocking caused by threads. For example, by
postponing the scheduler execution via preempt_disable(), scheduler
execution, or masking interrupts. Threads can also be delayed by the
interference from other threads and IRQs.

Tracer options
---------------------

The timerlat tracer is built on top of osnoise tracer.
So its configuration is also done in the osnoise/ config
directory. The timerlat configs are:

 - cpus: CPUs at which a timerlat thread will execute.
 - timerlat_period_us: the period of the timerlat thread.
 - stop_tracing_us: stop the system tracing if a
   timer latency at the *irq* context higher than the configured
   value happens. Writing 0 disables this option.
 - stop_tracing_total_us: stop the system tracing if a
   timer latency at the *thread* context is higher than the configured
   value happens. Writing 0 disables this option.
 - print_stack: save the stack of the IRQ occurrence. The stack is printed
   after the *thread context* event, or at the IRQ handler if *stop_tracing_us*
   is hit.

timerlat and osnoise
----------------------------

The timerlat can also take advantage of the osnoise: traceevents.
For example::

        [root@f32 ~]# cd /sys/kernel/tracing/
        [root@f32 tracing]# echo timerlat > current_tracer
        [root@f32 tracing]# echo 1 > events/osnoise/enable
        [root@f32 tracing]# echo 25 > osnoise/stop_tracing_total_us
        [root@f32 tracing]# tail -10 trace
             cc1-87882   [005] d..h...   548.771078: #402268 context    irq timer_latency     13585 ns
             cc1-87882   [005] dNLh1..   548.771082: irq_noise: local_timer:236 start 548.771077442 duration 7597 ns
             cc1-87882   [005] dNLh2..   548.771099: irq_noise: qxl:21 start 548.771085017 duration 7139 ns
             cc1-87882   [005] d...3..   548.771102: thread_noise:      cc1:87882 start 548.771078243 duration 9909 ns
      timerlat/5-1035    [005] .......   548.771104: #402268 context thread timer_latency     39960 ns

In this case, the root cause of the timer latency does not point to a
single cause but to multiple ones. Firstly, the timer IRQ was delayed
for 13 us, which may point to a long IRQ disabled section (see IRQ
stacktrace section). Then the timer interrupt that wakes up the timerlat
thread took 7597 ns, and the qxl:21 device IRQ took 7139 ns. Finally,
the cc1 thread noise took 9909 ns of time before the context switch.
Such pieces of evidence are useful for the developer to use other
tracing methods to figure out how to debug and optimize the system.

It is worth mentioning that the *duration* values reported
by the osnoise: events are *net* values. For example, the
thread_noise does not include the duration of the overhead caused
by the IRQ execution (which indeed accounted for 12736 ns). But
the values reported by the timerlat tracer (timerlat_latency)
are *gross* values.

The art below illustrates a CPU timeline and how the timerlat tracer
observes it at the top and the osnoise: events at the bottom. Each "-"
in the timelines means circa 1 us, and the time moves ==>::

      External     timer irq                   thread
       clock        latency                    latency
       event        13585 ns                   39960 ns
         |             ^                         ^
         v             |                         |
         |-------------|                         |
         |-------------+-------------------------|
                       ^                         ^
  ========================================================================
                    [tmr irq]  [dev irq]
  [another thread...^       v..^       v.......][timerlat/ thread]  <-- CPU timeline
  =========================================================================
                    |-------|  |-------|
                            |--^       v-------|
                            |          |       |
                            |          |       + thread_noise: 9909 ns
                            |          +-> irq_noise: 6139 ns
                            +-> irq_noise: 7597 ns

IRQ stacktrace
---------------------------

The osnoise/print_stack option is helpful for the cases in which a thread
noise causes the major factor for the timer latency, because of preempt or
irq disabled. For example::

        [root@f32 tracing]# echo 500 > osnoise/stop_tracing_total_us
        [root@f32 tracing]# echo 500 > osnoise/print_stack
        [root@f32 tracing]# echo timerlat > current_tracer
        [root@f32 tracing]# tail -21 per_cpu/cpu7/trace
          insmod-1026    [007] dN.h1..   200.201948: irq_noise: local_timer:236 start 200.201939376 duration 7872 ns
          insmod-1026    [007] d..h1..   200.202587: #29800 context    irq timer_latency      1616 ns
          insmod-1026    [007] dN.h2..   200.202598: irq_noise: local_timer:236 start 200.202586162 duration 11855 ns
          insmod-1026    [007] dN.h3..   200.202947: irq_noise: local_timer:236 start 200.202939174 duration 7318 ns
          insmod-1026    [007] d...3..   200.203444: thread_noise:   insmod:1026 start 200.202586933 duration 838681 ns
      timerlat/7-1001    [007] .......   200.203445: #29800 context thread timer_latency    859978 ns
      timerlat/7-1001    [007] ....1..   200.203446: <stack trace>
  => timerlat_irq
  => __hrtimer_run_queues
  => hrtimer_interrupt
  => __sysvec_apic_timer_interrupt
  => asm_call_irq_on_stack
  => sysvec_apic_timer_interrupt
  => asm_sysvec_apic_timer_interrupt
  => delay_tsc
  => dummy_load_1ms_pd_init
  => do_one_initcall
  => do_init_module
  => __do_sys_finit_module
  => do_syscall_64
  => entry_SYSCALL_64_after_hwframe

In this case, it is possible to see that the thread added the highest
contribution to the *timer latency* and the stack trace, saved during
the timerlat IRQ handler, points to a function named
dummy_load_1ms_pd_init, which had the following code (on purpose)::

	static int __init dummy_load_1ms_pd_init(void)
	{
		preempt_disable();
		mdelay(1);
		preempt_enable();
		return 0;

	}


code:
=========================================================
Notes on Analysing Behaviour Using Events and Tracepoints
=========================================================
:Author: Mel Gorman (PCL information heavily based on email from Ingo Molnar)

1. Introduction
===============

Tracepoints (see Documentation/trace/tracepoints.rst) can be used without
creating custom kernel modules to register probe functions using the event
tracing infrastructure.

Simplistically, tracepoints represent important events that can be
taken in conjunction with other tracepoints to build a "Big Picture" of
what is going on within the system. There are a large number of methods for
gathering and interpreting these events. Lacking any current Best Practises,
this document describes some of the methods that can be used.

This document assumes that debugfs is mounted on /sys/kernel/debug and that
the appropriate tracing options have been configured into the kernel. It is
assumed that the PCL tool tools/perf has been installed and is in your path.

2. Listing Available Events
===========================

2.1 Standard Utilities
----------------------

All possible events are visible from /sys/kernel/debug/tracing/events. Simply
calling::

  $ find /sys/kernel/debug/tracing/events -type d

will give a fair indication of the number of events available.

2.2 PCL (Performance Counters for Linux)
----------------------------------------

Discovery and enumeration of all counters and events, including tracepoints,
are available with the perf tool. Getting a list of available events is a
simple case of::

  $ perf list 2>&1 | grep Tracepoint
  ext4:ext4_free_inode                     [Tracepoint event]
  ext4:ext4_request_inode                  [Tracepoint event]
  ext4:ext4_allocate_inode                 [Tracepoint event]
  ext4:ext4_write_begin                    [Tracepoint event]
  ext4:ext4_ordered_write_end              [Tracepoint event]
  [ .... remaining output snipped .... ]

3. Enabling Events
==================

3.1 System-Wide Event Enabling
------------------------------

See Documentation/trace/events.rst for a proper description on how events
can be enabled system-wide. A short example of enabling all events related
to page allocation would look something like::

  $ for i in `find /sys/kernel/debug/tracing/events -name "enable" | grep mm_`; do echo 1 > $i; done

3.2 System-Wide Event Enabling with SystemTap
---------------------------------------------

In SystemTap, tracepoints are accessible using the kernel.trace() function
call. The following is an example that reports every 5 seconds what processes
were allocating the pages.
::

  global page_allocs

  probe kernel.trace("mm_page_alloc") {
  	page_allocs[execname()]++
  }

  function print_count() {
  	printf ("%-25s %-s\n", "#Pages Allocated", "Process Name")
  	foreach (proc in page_allocs-)
  		printf("%-25d %s\n", page_allocs[proc], proc)
  	printf ("\n")
  	delete page_allocs
  }

  probe timer.s(5) {
          print_count()
  }

3.3 System-Wide Event Enabling with PCL
---------------------------------------

By specifying the -a switch and analysing sleep, the system-wide events
for a duration of time can be examined.
::

 $ perf stat -a \
	-e kmem:mm_page_alloc -e kmem:mm_page_free \
	-e kmem:mm_page_free_batched \
	sleep 10
 Performance counter stats for 'sleep 10':

           9630  kmem:mm_page_alloc
           2143  kmem:mm_page_free
           7424  kmem:mm_page_free_batched

   10.002577764  seconds time elapsed

Similarly, one could execute a shell and exit it as desired to get a report
at that point.

3.4 Local Event Enabling
------------------------

Documentation/trace/ftrace.rst describes how to enable events on a per-thread
basis using set_ftrace_pid.

3.5 Local Event Enablement with PCL
-----------------------------------

Events can be activated and tracked for the duration of a process on a local
basis using PCL such as follows.
::

  $ perf stat -e kmem:mm_page_alloc -e kmem:mm_page_free \
		 -e kmem:mm_page_free_batched ./hackbench 10
  Time: 0.909

    Performance counter stats for './hackbench 10':

          17803  kmem:mm_page_alloc
          12398  kmem:mm_page_free
           4827  kmem:mm_page_free_batched

    0.973913387  seconds time elapsed

4. Event Filtering
==================

Documentation/trace/ftrace.rst covers in-depth how to filter events in
ftrace.  Obviously using grep and awk of trace_pipe is an option as well
as any script reading trace_pipe.

5. Analysing Event Variances with PCL
=====================================

Any workload can exhibit variances between runs and it can be important
to know what the standard deviation is. By and large, this is left to the
performance analyst to do it by hand. In the event that the discrete event
occurrences are useful to the performance analyst, then perf can be used.
::

  $ perf stat --repeat 5 -e kmem:mm_page_alloc -e kmem:mm_page_free
			-e kmem:mm_page_free_batched ./hackbench 10
  Time: 0.890
  Time: 0.895
  Time: 0.915
  Time: 1.001
  Time: 0.899

   Performance counter stats for './hackbench 10' (5 runs):

          16630  kmem:mm_page_alloc         ( +-   3.542% )
          11486  kmem:mm_page_free	    ( +-   4.771% )
           4730  kmem:mm_page_free_batched  ( +-   2.325% )

    0.982653002  seconds time elapsed   ( +-   1.448% )

In the event that some higher-level event is required that depends on some
aggregation of discrete events, then a script would need to be developed.

Using --repeat, it is also possible to view how events are fluctuating over
time on a system-wide basis using -a and sleep.
::

  $ perf stat -e kmem:mm_page_alloc -e kmem:mm_page_free \
		-e kmem:mm_page_free_batched \
		-a --repeat 10 \
		sleep 1
  Performance counter stats for 'sleep 1' (10 runs):

           1066  kmem:mm_page_alloc         ( +-  26.148% )
            182  kmem:mm_page_free          ( +-   5.464% )
            890  kmem:mm_page_free_batched  ( +-  30.079% )

    1.002251757  seconds time elapsed   ( +-   0.005% )

6. Higher-Level Analysis with Helper Scripts
============================================

When events are enabled the events that are triggering can be read from
/sys/kernel/debug/tracing/trace_pipe in human-readable format although binary
options exist as well. By post-processing the output, further information can
be gathered on-line as appropriate. Examples of post-processing might include

  - Reading information from /proc for the PID that triggered the event
  - Deriving a higher-level event from a series of lower-level events.
  - Calculating latencies between two events

Documentation/trace/postprocess/trace-pagealloc-postprocess.pl is an example
script that can read trace_pipe from STDIN or a copy of a trace. When used
on-line, it can be interrupted once to generate a report without exiting
and twice to exit.

Simplistically, the script just reads STDIN and counts up events but it
also can do more such as

  - Derive high-level events from many low-level events. If a number of pages
    are freed to the main allocator from the per-CPU lists, it recognises
    that as one per-CPU drain even though there is no specific tracepoint
    for that event
  - It can aggregate based on PID or individual process number
  - In the event memory is getting externally fragmented, it reports
    on whether the fragmentation event was severe or moderate.
  - When receiving an event about a PID, it can record who the parent was so
    that if large numbers of events are coming from very short-lived
    processes, the parent process responsible for creating all the helpers
    can be identified

7. Lower-Level Analysis with PCL
================================

There may also be a requirement to identify what functions within a program
were generating events within the kernel. To begin this sort of analysis, the
data must be recorded. At the time of writing, this required root:
::

  $ perf record -c 1 \
	-e kmem:mm_page_alloc -e kmem:mm_page_free \
	-e kmem:mm_page_free_batched \
	./hackbench 10
  Time: 0.894
  [ perf record: Captured and wrote 0.733 MB perf.data (~32010 samples) ]

Note the use of '-c 1' to set the event period to sample. The default sample
period is quite high to minimise overhead but the information collected can be
very coarse as a result.

This record outputted a file called perf.data which can be analysed using
perf report.
::

  $ perf report
  # Samples: 30922
  #
  # Overhead    Command                     Shared Object
  # ........  .........  ................................
  #
      87.27%  hackbench  [vdso]
       6.85%  hackbench  /lib/i686/cmov/libc-2.9.so
       2.62%  hackbench  /lib/ld-2.9.so
       1.52%       perf  [vdso]
       1.22%  hackbench  ./hackbench
       0.48%  hackbench  [kernel]
       0.02%       perf  /lib/i686/cmov/libc-2.9.so
       0.01%       perf  /usr/bin/perf
       0.01%       perf  /lib/ld-2.9.so
       0.00%  hackbench  /lib/i686/cmov/libpthread-2.9.so
  #
  # (For more details, try: perf report --sort comm,dso,symbol)
  #

According to this, the vast majority of events triggered on events
within the VDSO. With simple binaries, this will often be the case so let's
take a slightly different example. In the course of writing this, it was
noticed that X was generating an insane amount of page allocations so let's look
at it:
::

  $ perf record -c 1 -f \
		-e kmem:mm_page_alloc -e kmem:mm_page_free \
		-e kmem:mm_page_free_batched \
		-p `pidof X`

This was interrupted after a few seconds and
::

  $ perf report
  # Samples: 27666
  #
  # Overhead  Command                            Shared Object
  # ........  .......  .......................................
  #
      51.95%     Xorg  [vdso]
      47.95%     Xorg  /opt/gfx-test/lib/libpixman-1.so.0.13.1
       0.09%     Xorg  /lib/i686/cmov/libc-2.9.so
       0.01%     Xorg  [kernel]
  #
  # (For more details, try: perf report --sort comm,dso,symbol)
  #

So, almost half of the events are occurring in a library. To get an idea which
symbol:
::

  $ perf report --sort comm,dso,symbol
  # Samples: 27666
  #
  # Overhead  Command                            Shared Object  Symbol
  # ........  .......  .......................................  ......
  #
      51.95%     Xorg  [vdso]                                   [.] 0x000000ffffe424
      47.93%     Xorg  /opt/gfx-test/lib/libpixman-1.so.0.13.1  [.] pixmanFillsse2
       0.09%     Xorg  /lib/i686/cmov/libc-2.9.so               [.] _int_malloc
       0.01%     Xorg  /opt/gfx-test/lib/libpixman-1.so.0.13.1  [.] pixman_region32_copy_f
       0.01%     Xorg  [kernel]                                 [k] read_hpet
       0.01%     Xorg  /opt/gfx-test/lib/libpixman-1.so.0.13.1  [.] get_fast_path
       0.00%     Xorg  [kernel]                                 [k] ftrace_trace_userstack

To see where within the function pixmanFillsse2 things are going wrong:
::

  $ perf annotate pixmanFillsse2
  [ ... ]
    0.00 :         34eeb:       0f 18 08                prefetcht0 (%eax)
         :      }
         :
         :      extern __inline void __attribute__((__gnu_inline__, __always_inline__, _
         :      _mm_store_si128 (__m128i *__P, __m128i __B) :      {
         :        *__P = __B;
   12.40 :         34eee:       66 0f 7f 80 40 ff ff    movdqa %xmm0,-0xc0(%eax)
    0.00 :         34ef5:       ff
   12.40 :         34ef6:       66 0f 7f 80 50 ff ff    movdqa %xmm0,-0xb0(%eax)
    0.00 :         34efd:       ff
   12.39 :         34efe:       66 0f 7f 80 60 ff ff    movdqa %xmm0,-0xa0(%eax)
    0.00 :         34f05:       ff
   12.67 :         34f06:       66 0f 7f 80 70 ff ff    movdqa %xmm0,-0x90(%eax)
    0.00 :         34f0d:       ff
   12.58 :         34f0e:       66 0f 7f 40 80          movdqa %xmm0,-0x80(%eax)
   12.31 :         34f13:       66 0f 7f 40 90          movdqa %xmm0,-0x70(%eax)
   12.40 :         34f18:       66 0f 7f 40 a0          movdqa %xmm0,-0x60(%eax)
   12.31 :         34f1d:       66 0f 7f 40 b0          movdqa %xmm0,-0x50(%eax)

At a glance, it looks like the time is being spent copying pixmaps to
the card.  Further investigation would be needed to determine why pixmaps
are being copied around so much but a starting point would be to take an
ancient build of libpixmap out of the library path where it was totally
forgotten about from months ago!

repo_name: angery/linux


code:
==================================
Using the Linux Kernel Tracepoints
==================================

:Author: Mathieu Desnoyers

This document introduces Linux Kernel Tracepoints and their use. It
provides examples of how to insert tracepoints in the kernel and
connect probe functions to them and provides some examples of probe
functions.

Purpose of tracepoints
----------------------
A tracepoint placed in code provides a hook to call a function (probe)
that you can provide at runtime. A tracepoint can be "on" (a probe is
connected to it) or "off" (no probe is attached). When a tracepoint is
"off" it has no effect, except for adding a tiny time penalty
(checking a condition for a branch) and space penalty (adding a few
bytes for the function call at the end of the instrumented function
and adds a data structure in a separate section).  When a tracepoint
is "on", the function you provide is called each time the tracepoint
is executed, in the execution context of the caller. When the function
provided ends its execution, it returns to the caller (continuing from
the tracepoint site).

You can put tracepoints at important locations in the code. They are
lightweight hooks that can pass an arbitrary number of parameters,
which prototypes are described in a tracepoint declaration placed in a
header file.

They can be used for tracing and performance accounting.

Usage
-----
Two elements are required for tracepoints :

- A tracepoint definition, placed in a header file.
- The tracepoint statement, in C code.

In order to use tracepoints, you should include linux/tracepoint.h.

In include/trace/events/subsys.h::

	#undef TRACE_SYSTEM
	#define TRACE_SYSTEM subsys

	#if !defined(_TRACE_SUBSYS_H) || defined(TRACE_HEADER_MULTI_READ)
	#define _TRACE_SUBSYS_H

	#include <linux/tracepoint.h>

	DECLARE_TRACE(subsys_eventname,
		TP_PROTO(int firstarg, struct task_struct *p),
		TP_ARGS(firstarg, p));

	#endif /* _TRACE_SUBSYS_H */

	/* This part must be outside protection */
	#include <trace/define_trace.h>

In subsys/file.c (where the tracing statement must be added)::

	#include <trace/events/subsys.h>

	#define CREATE_TRACE_POINTS
	DEFINE_TRACE(subsys_eventname);

	void somefct(void)
	{
		...
		trace_subsys_eventname(arg, task);
		...
	}

Where :
  - subsys_eventname is an identifier unique to your event

    - subsys is the name of your subsystem.
    - eventname is the name of the event to trace.

  - `TP_PROTO(int firstarg, struct task_struct *p)` is the prototype of the
    function called by this tracepoint.

  - `TP_ARGS(firstarg, p)` are the parameters names, same as found in the
    prototype.

  - if you use the header in multiple source files, `#define CREATE_TRACE_POINTS`
    should appear only in one source file.

Connecting a function (probe) to a tracepoint is done by providing a
probe (function to call) for the specific tracepoint through
register_trace_subsys_eventname().  Removing a probe is done through
unregister_trace_subsys_eventname(); it will remove the probe.

tracepoint_synchronize_unregister() must be called before the end of
the module exit function to make sure there is no caller left using
the probe. This, and the fact that preemption is disabled around the
probe call, make sure that probe removal and module unload are safe.

The tracepoint mechanism supports inserting multiple instances of the
same tracepoint, but a single definition must be made of a given
tracepoint name over all the kernel to make sure no type conflict will
occur. Name mangling of the tracepoints is done using the prototypes
to make sure typing is correct. Verification of probe type correctness
is done at the registration site by the compiler. Tracepoints can be
put in inline functions, inlined static functions, and unrolled loops
as well as regular functions.

The naming scheme "subsys_event" is suggested here as a convention
intended to limit collisions. Tracepoint names are global to the
kernel: they are considered as being the same whether they are in the
core kernel image or in modules.

If the tracepoint has to be used in kernel modules, an
EXPORT_TRACEPOINT_SYMBOL_GPL() or EXPORT_TRACEPOINT_SYMBOL() can be
used to export the defined tracepoints.

If you need to do a bit of work for a tracepoint parameter, and
that work is only used for the tracepoint, that work can be encapsulated
within an if statement with the following::

	if (trace_foo_bar_enabled()) {
		int i;
		int tot = 0;

		for (i = 0; i < count; i++)
			tot += calculate_nuggets();

		trace_foo_bar(tot);
	}

All trace_<tracepoint>() calls have a matching trace_<tracepoint>_enabled()
function defined that returns true if the tracepoint is enabled and
false otherwise. The trace_<tracepoint>() should always be within the
block of the if (trace_<tracepoint>_enabled()) to prevent races between
the tracepoint being enabled and the check being seen.

The advantage of using the trace_<tracepoint>_enabled() is that it uses
the static_key of the tracepoint to allow the if statement to be implemented
with jump labels and avoid conditional branches.

.. note:: The convenience macro TRACE_EVENT provides an alternative way to
      define tracepoints. Check http://lwn.net/Articles/379903,
      http://lwn.net/Articles/381064 and http://lwn.net/Articles/383362
      for a series of articles with more details.

If you require calling a tracepoint from a header file, it is not
recommended to call one directly or to use the trace_<tracepoint>_enabled()
function call, as tracepoints in header files can have side effects if a
header is included from a file that has CREATE_TRACE_POINTS set, as
well as the trace_<tracepoint>() is not that small of an inline
and can bloat the kernel if used by other inlined functions. Instead,
include tracepoint-defs.h and use tracepoint_enabled().

In a C file::

	void do_trace_foo_bar_wrapper(args)
	{
		trace_foo_bar(args);
	}

In the header file::

	DECLARE_TRACEPOINT(foo_bar);

	static inline void some_inline_function()
	{
		[..]
		if (tracepoint_enabled(foo_bar))
			do_trace_foo_bar_wrapper(args);
		[..]
	}


code:
=========================================
Uprobe-tracer: Uprobe-based Event Tracing
=========================================

:Author: Srikar Dronamraju

Overview
--------
Uprobe based trace events are similar to kprobe based trace events.
To enable this feature, build your kernel with CONFIG_UPROBE_EVENTS=y.

Similar to the kprobe-event tracer, this doesn't need to be activated via
current_tracer. Instead of that, add probe points via
/sys/kernel/debug/tracing/uprobe_events, and enable it via
/sys/kernel/debug/tracing/events/uprobes/<EVENT>/enable.

However unlike kprobe-event tracer, the uprobe event interface expects the
user to calculate the offset of the probepoint in the object.

You can also use /sys/kernel/debug/tracing/dynamic_events instead of
uprobe_events. That interface will provide unified access to other
dynamic events too.

Synopsis of uprobe_tracer
-------------------------
::

  p[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a uprobe
  r[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe)
  p[:[GRP/][EVENT]] PATH:OFFSET%return [FETCHARGS] : Set a return uprobe (uretprobe)
  -:[GRP/][EVENT]                           : 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.
  OFFSET%return : Offset where the return probe is inserted.

  FETCHARGS     : Arguments. Each probe can have up to 128 args.
   %REG         : Fetch register REG
   @ADDR	: Fetch memory at ADDR (ADDR should be in userspace)
   @+OFFSET	: Fetch memory at OFFSET (OFFSET from same file as PATH)
   $stackN	: Fetch Nth entry of stack (N >= 0)
   $stack	: Fetch stack address.
   $retval	: Fetch return value.(\*1)
   $comm	: Fetch current task comm.
   +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*2)(\*3)
   \IMM		: Store an immediate value to the argument.
   NAME=FETCHARG     : Set NAME as the argument name of FETCHARG.
   FETCHARG:TYPE     : Set TYPE as the type of FETCHARG. Currently, basic types
		       (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
		       (x8/x16/x32/x64), "string" and bitfield are supported.

  (\*1) only for return probe.
  (\*2) this is useful for fetching a field of data structures.
  (\*3) Unlike kprobe event, "u" prefix will just be ignored, becuse uprobe
        events can access only user-space memory.

Types
-----
Several types are supported for fetch-args. Uprobe tracer will access memory
by given type. Prefix 's' and 'u' means those types are signed and unsigned
respectively. 'x' prefix implies it is unsigned. Traced arguments are shown
in decimal ('s' and 'u') or hexadecimal ('x'). Without type casting, 'x32'
or 'x64' is used depends on the architecture (e.g. x86-32 uses x32, and
x86-64 uses x64).
String type is a special type, which fetches a "null-terminated" string from
user space.
Bitfield is another special type, which takes 3 parameters, bit-width, bit-
offset, and container-size (usually 32). The syntax is::

 b<bit-width>@<bit-offset>/<container-size>

For $comm, the default type is "string"; any other type is invalid.

Event Profiling
---------------
You can check the total number of probe hits per event via
/sys/kernel/debug/tracing/uprobe_profile. The first column is the filename,
the second is the event name, the third is the number of probe hits.

Usage examples
--------------
 * Add a probe as a new uprobe event, write a new definition to uprobe_events
   as below (sets a uprobe at an offset of 0x4245c0 in the executable /bin/bash)::

    echo 'p /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events

 * Add a probe as a new uretprobe event::

    echo 'r /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events

 * Unset registered event::

    echo '-:p_bash_0x4245c0' >> /sys/kernel/debug/tracing/uprobe_events

 * Print out the events that are registered::

    cat /sys/kernel/debug/tracing/uprobe_events

 * Clear all events::

    echo > /sys/kernel/debug/tracing/uprobe_events

Following example shows how to dump the instruction pointer and %ax register
at the probed text address. Probe zfree function in /bin/zsh::

    # cd /sys/kernel/debug/tracing/
    # cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
    00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
    # objdump -T /bin/zsh | grep -w zfree
    0000000000446420 g    DF .text  0000000000000012  Base        zfree

0x46420 is the offset of zfree in object /bin/zsh that is loaded at
0x00400000. Hence the command to uprobe would be::

    # echo 'p:zfree_entry /bin/zsh:0x46420 %ip %ax' > uprobe_events

And the same for the uretprobe would be::

    # echo 'r:zfree_exit /bin/zsh:0x46420 %ip %ax' >> uprobe_events

.. note:: User has to explicitly calculate the offset of the probe-point
	in the object.

We can see the events that are registered by looking at the uprobe_events file.
::

    # cat uprobe_events
    p:uprobes/zfree_entry /bin/zsh:0x00046420 arg1=%ip arg2=%ax
    r:uprobes/zfree_exit /bin/zsh:0x00046420 arg1=%ip arg2=%ax

Format of events can be seen by viewing the file events/uprobes/zfree_entry/format.
::

    # cat events/uprobes/zfree_entry/format
    name: zfree_entry
    ID: 922
    format:
         field:unsigned short common_type;         offset:0;  size:2; signed:0;
         field:unsigned char common_flags;         offset:2;  size:1; signed:0;
         field:unsigned char common_preempt_count; offset:3;  size:1; signed:0;
         field:int common_pid;                     offset:4;  size:4; signed:1;
         field:int common_padding;                 offset:8;  size:4; signed:1;

         field:unsigned long __probe_ip;           offset:12; size:4; signed:0;
         field:u32 arg1;                           offset:16; size:4; signed:0;
         field:u32 arg2;                           offset:20; size:4; signed:0;

    print fmt: "(%lx) arg1=%lx arg2=%lx", REC->__probe_ip, REC->arg1, REC->arg2

Right after definition, each event is disabled by default. For tracing these
events, you need to enable it by::

    # echo 1 > events/uprobes/enable

Lets start tracing, sleep for some time and stop tracing.
::

    # echo 1 > tracing_on
    # sleep 20
    # echo 0 > tracing_on

Also, you can disable the event by::

    # echo 0 > events/uprobes/enable

And you can see the traced information via /sys/kernel/debug/tracing/trace.
::

    # cat trace
    # tracer: nop
    #
    #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
    #              | |       |          |         |
                 zsh-24842 [006] 258544.995456: zfree_entry: (0x446420) arg1=446420 arg2=79
                 zsh-24842 [007] 258545.000270: zfree_exit:  (0x446540 <- 0x446420) arg1=446540 arg2=0
                 zsh-24842 [002] 258545.043929: zfree_entry: (0x446420) arg1=446420 arg2=79
                 zsh-24842 [004] 258547.046129: zfree_exit:  (0x446540 <- 0x446420) arg1=446540 arg2=0

Output shows us uprobe was triggered for a pid 24842 with ip being 0x446420
and contents of ax register being 79. And uretprobe was triggered with ip at
0x446540 with counterpart function entry at 0x446420.


code:
=========================================
user_events: User-based Event Tracing
=========================================

:Author: Beau Belgrave

Overview
--------
User based trace events allow user processes to create events and trace data
that can be viewed via existing tools, such as ftrace and perf.
To enable this feature, build your kernel with CONFIG_USER_EVENTS=y.

Programs can view status of the events via
/sys/kernel/debug/tracing/user_events_status and can both register and write
data out via /sys/kernel/debug/tracing/user_events_data.

Programs can also use /sys/kernel/debug/tracing/dynamic_events to register and
delete user based events via the u: prefix. The format of the command to
dynamic_events is the same as the ioctl with the u: prefix applied.

Typically programs will register a set of events that they wish to expose to
tools that can read trace_events (such as ftrace and perf). The registration
process gives back two ints to the program for each event. The first int is
the status bit. This describes which bit in little-endian format in the
/sys/kernel/debug/tracing/user_events_status file represents this event. The
second int is the write index which describes the data when a write() or
writev() is called on the /sys/kernel/debug/tracing/user_events_data file.

The structures referenced in this document are contained within the
/include/uapi/linux/user_events.h file in the source tree.

**NOTE:** *Both user_events_status and user_events_data are under the tracefs
filesystem and may be mounted at different paths than above.*

Registering
-----------
Registering within a user process is done via ioctl() out to the
/sys/kernel/debug/tracing/user_events_data file. The command to issue is
DIAG_IOCSREG.

This command takes a packed struct user_reg as an argument::

  struct user_reg {
        u32 size;
        u64 name_args;
        u32 status_bit;
        u32 write_index;
  };

The struct user_reg requires two inputs, the first is the size of the structure
to ensure forward and backward compatibility. The second is the command string
to issue for registering. Upon success two outputs are set, the status bit
and the write index.

User based events show up under tracefs like any other event under the
subsystem named "user_events". This means tools that wish to attach to the
events need to use /sys/kernel/debug/tracing/events/user_events/[name]/enable
or perf record -e user_events:[name] when attaching/recording.

**NOTE:** *The write_index returned is only valid for the FD that was used*

Command Format
^^^^^^^^^^^^^^
The command string format is as follows::

  name[:FLAG1[,FLAG2...]] [Field1[;Field2...]]

Supported Flags
^^^^^^^^^^^^^^^
None yet

Field Format
^^^^^^^^^^^^
::

  type name [size]

Basic types are supported (__data_loc, u32, u64, int, char, char[20], etc).
User programs are encouraged to use clearly sized types like u32.

**NOTE:** *Long is not supported since size can vary between user and kernel.*

The size is only valid for types that start with a struct prefix.
This allows user programs to describe custom structs out to tools, if required.

For example, a struct in C that looks like this::

  struct mytype {
    char data[20];
  };

Would be represented by the following field::

  struct mytype myname 20

Deleting
-----------
Deleting an event from within a user process is done via ioctl() out to the
/sys/kernel/debug/tracing/user_events_data file. The command to issue is
DIAG_IOCSDEL.

This command only requires a single string specifying the event to delete by
its name. Delete will only succeed if there are no references left to the
event (in both user and kernel space). User programs should use a separate file
to request deletes than the one used for registration due to this.

Status
------
When tools attach/record user based events the status of the event is updated
in realtime. This allows user programs to only incur the cost of the write() or
writev() calls when something is actively attached to the event.

User programs call mmap() on /sys/kernel/debug/tracing/user_events_status to
check the status for each event that is registered. The bit to check in the
file is given back after the register ioctl() via user_reg.status_bit. The bit
is always in little-endian format. Programs can check if the bit is set either
using a byte-wise index with a mask or a long-wise index with a little-endian
mask.

Currently the size of user_events_status is a single page, however, custom
kernel configurations can change this size to allow more user based events. In
all cases the size of the file is a multiple of a page size.

For example, if the register ioctl() gives back a status_bit of 3 you would
check byte 0 (3 / 8) of the returned mmap data and then AND the result with 8
(1 << (3 % 8)) to see if anything is attached to that event.

A byte-wise index check is performed as follows::

  int index, mask;
  char *status_page;

  index = status_bit / 8;
  mask = 1 << (status_bit % 8);

  ...

  if (status_page[index] & mask) {
        /* Enabled */
  }

A long-wise index check is performed as follows::

  #include <asm/bitsperlong.h>
  #include <endian.h>

  #if __BITS_PER_LONG == 64
  #define endian_swap(x) htole64(x)
  #else
  #define endian_swap(x) htole32(x)
  #endif

  long index, mask, *status_page;

  index = status_bit / __BITS_PER_LONG;
  mask = 1L << (status_bit % __BITS_PER_LONG);
  mask = endian_swap(mask);

  ...

  if (status_page[index] & mask) {
        /* Enabled */
  }

Administrators can easily check the status of all registered events by reading
the user_events_status file directly via a terminal. The output is as follows::

  Byte:Name [# Comments]
  ...

  Active: ActiveCount
  Busy: BusyCount
  Max: MaxCount

For example, on a system that has a single event the output looks like this::

  1:test

  Active: 1
  Busy: 0
  Max: 32768

If a user enables the user event via ftrace, the output would change to this::

  1:test # Used by ftrace

  Active: 1
  Busy: 1
  Max: 32768

**NOTE:** *A status bit of 0 will never be returned. This allows user programs
to have a bit that can be used on error cases.*

Writing Data
------------
After registering an event the same fd that was used to register can be used
to write an entry for that event. The write_index returned must be at the start
of the data, then the remaining data is treated as the payload of the event.

For example, if write_index returned was 1 and I wanted to write out an int
payload of the event. Then the data would have to be 8 bytes (2 ints) in size,
with the first 4 bytes being equal to 1 and the last 4 bytes being equal to the
value I want as the payload.

In memory this would look like this::

  int index;
  int payload;

User programs might have well known structs that they wish to use to emit out
as payloads. In those cases writev() can be used, with the first vector being
the index and the following vector(s) being the actual event payload.

For example, if I have a struct like this::

  struct payload {
        int src;
        int dst;
        int flags;
  };

It's advised for user programs to do the following::

  struct iovec io[2];
  struct payload e;

  io[0].iov_base = &write_index;
  io[0].iov_len = sizeof(write_index);
  io[1].iov_base = &e;
  io[1].iov_len = sizeof(e);

  writev(fd, (const struct iovec*)io, 2);

**NOTE:** *The write_index is not emitted out into the trace being recorded.*

Example Code
------------
See sample code in samples/user_events.


code:
.. _translations:

============
Translations
============

.. toctree::
   :maxdepth: 1

   zh_CN/index
   zh_TW/index
   it_IT/index
   ko_KR/index
   ja_JP/index
   sp_SP/index

.. _translations_disclaimer:

Disclaimer
----------

.. raw:: latex

	\kerneldocCJKoff

Translation's purpose is to ease reading and understanding in languages other
than English. Its aim is to help people who do not understand English or have
doubts about its interpretation. Additionally, some people prefer to read
documentation in their native language, but please bear in mind that the
*only* official documentation is the English one: :ref:`linux_doc`.

It is very unlikely that an update to :ref:`linux_doc` will be propagated
immediately to all translations.  Translations' maintainers - and
contributors - follow the evolution of the official documentation and they
maintain translations aligned as much as they can.  For this reason there is
no guarantee that a translation is up to date.  If what you read in a
translation does not sound right compared to what you read in the code, please
inform the translation maintainer and - if you can - check also the English
documentation.

A translation is not a fork of the official documentation, therefore
translations' users should not find information that differs from the official
English documentation.  Any content addition, removal or update, must be
applied to the English documents first.  Afterwards and when possible, the
same change should be applied to translations.  Translations' maintainers
accept only contributions that are merely translation related (e.g. new
translations, updates, fixes).

Translations try to be as accurate as possible but it is not possible to map
one language directly to all other languages. Each language has its own
grammar and culture, so the translation of an English statement may need to be
adapted to fit a different language.  For this reason, when viewing
translations, you may find slight differences that carry the same message but
in a different form.

If you need to communicate with the Linux community but you do not feel
comfortable writing in English, you can ask the translation's maintainers
for help.


code:
.. include:: ../disclaimer-ita.rst

:Original: :ref:`Documentation/admin-guide/README.rst <readme>`

.. _it_readme:

Rilascio del kernel Linux  5.x <http://kernel.org/>
===================================================

.. warning::

    TODO ancora da tradurre


code:
.. include:: ../disclaimer-ita.rst

:Original: :ref:`Documentation/admin-guide/kernel-parameters.rst <kernelparameters>`

.. _it_kernelparameters:

I parametri da linea di comando del kernel
==========================================

.. warning::

    TODO ancora da tradurre


code:
.. include:: ../disclaimer-ita.rst

:Original: :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`

.. _it_securitybugs:

Bachi di sicurezza
==================

.. warning::

    TODO ancora da tradurre


code:
===============================
Documentazione dell'API di base
===============================

Utilità di base
===============

.. toctree::
   :maxdepth: 1

   symbol-namespaces

.. only:: subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
.. include:: ../disclaimer-ita.rst

:Original: :ref:`Documentation/core-api/memory-allocation.rst <memory_allocation>`

.. _it_memory_allocation:

================================
Guida all'allocazione di memoria
================================

.. warning::

    TODO ancora da tradurre


code:
.. include:: ../disclaimer-ita.rst

:Original: :doc:`../../../core-api/symbol-namespaces`
:Translator: Federico Vaga <federico.vaga@vaga.pv.it>

===========================
Spazio dei nomi dei simboli
===========================

Questo documento descrive come usare lo spazio dei nomi dei simboli
per strutturare quello che viene esportato internamente al kernel
grazie alle macro della famiglia EXPORT_SYMBOL().

1. Introduzione
===============

Lo spazio dei nomi dei simboli è stato introdotto come mezzo per strutturare
l'API esposta internamente al kernel. Permette ai manutentori di un
sottosistema di organizzare i simboli esportati in diversi spazi di
nomi. Questo meccanismo è utile per la documentazione (pensate ad
esempio allo spazio dei nomi SUBSYSTEM_DEBUG) così come per limitare
la disponibilità di un gruppo di simboli in altre parti del kernel. Ad
oggi, i moduli che usano simboli esportati da uno spazio di nomi
devono prima importare detto spazio. Altrimenti il kernel, a seconda
della configurazione, potrebbe rifiutare di caricare il modulo o
avvisare l'utente di un'importazione mancante.

2. Come definire uno spazio dei nomi dei simboli
================================================

I simboli possono essere esportati in spazi dei nomi usando diversi
meccanismi.  Tutti questi meccanismi cambiano il modo in cui
EXPORT_SYMBOL e simili vengono guidati verso la creazione di voci in ksymtab.

2.1 Usare le macro EXPORT_SYMBOL
================================

In aggiunta alle macro EXPORT_SYMBOL() e EXPORT_SYMBOL_GPL(), che permettono
di esportare simboli del kernel nella rispettiva tabella, ci sono
varianti che permettono di esportare simboli all'interno di uno spazio dei
nomi: EXPORT_SYMBOL_NS() ed EXPORT_SYMBOL_NS_GPL(). Queste macro richiedono un
argomento aggiuntivo: lo spazio dei nomi.
Tenete presente che per via dell'espansione delle macro questo argomento deve
essere un simbolo di preprocessore. Per esempio per esportare il
simbolo ``usb_stor_suspend`` nello spazio dei nomi ``USB_STORAGE`` usate::

	EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE);

Di conseguenza, nella tabella dei simboli del kernel ci sarà una voce
rappresentata dalla struttura ``kernel_symbol`` che avrà il campo
``namespace`` (spazio dei nomi) impostato. Un simbolo esportato senza uno spazio
dei nomi avrà questo campo impostato a ``NULL``. Non esiste uno spazio dei nomi
di base. Il programma ``modpost`` e il codice in kernel/module/main.c usano lo
spazio dei nomi, rispettivamente, durante la compilazione e durante il
caricamento di un modulo.

2.2 Usare il simbolo di preprocessore DEFAULT_SYMBOL_NAMESPACE
==============================================================

Definire lo spazio dei nomi per tutti i simboli di un sottosistema può essere
logorante e di difficile manutenzione. Perciò è stato fornito un simbolo
di preprocessore di base (DEFAULT_SYMBOL_NAMESPACE), che, se impostato,
diventa lo spazio dei simboli di base per tutti gli usi di EXPORT_SYMBOL()
ed EXPORT_SYMBOL_GPL() che non specificano esplicitamente uno spazio dei nomi.

Ci sono molti modi per specificare questo simbolo di preprocessore e il loro
uso dipende dalle preferenze del manutentore di un sottosistema. La prima
possibilità è quella di definire il simbolo nel ``Makefile`` del sottosistema.
Per esempio per esportare tutti i simboli definiti in usb-common nello spazio
dei nomi USB_COMMON, si può aggiungere la seguente linea in
drivers/usb/common/Makefile::

	ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON

Questo cambierà tutte le macro EXPORT_SYMBOL() ed EXPORT_SYMBOL_GPL(). Invece,
un simbolo esportato con EXPORT_SYMBOL_NS() non verrà cambiato e il simbolo
verrà esportato nello spazio dei nomi indicato.

Una seconda possibilità è quella di definire il simbolo di preprocessore
direttamente nei file da compilare. L'esempio precedente diventerebbe::

	#undef  DEFAULT_SYMBOL_NAMESPACE
	#define DEFAULT_SYMBOL_NAMESPACE USB_COMMON

Questo va messo prima di un qualsiasi uso di EXPORT_SYMBOL.

3. Come usare i simboli esportati attraverso uno spazio dei nomi
================================================================

Per usare i simboli esportati da uno spazio dei nomi, i moduli del
kernel devono esplicitamente importare il relativo spazio dei nomi; altrimenti
il kernel potrebbe rifiutarsi di caricare il modulo. Il codice del
modulo deve usare la macro MODULE_IMPORT_NS per importare lo spazio
dei nomi che contiene i simboli desiderati. Per esempio un modulo che
usa il simbolo usb_stor_suspend deve importare lo spazio dei nomi
USB_STORAGE usando la seguente dichiarazione::

	MODULE_IMPORT_NS(USB_STORAGE);

Questo creerà un'etichetta ``modinfo`` per ogni spazio dei nomi
importato. Un risvolto di questo fatto è che gli spazi dei
nomi importati da un modulo possono essere ispezionati tramite
modinfo::

	$ modinfo drivers/usb/storage/ums-karma.ko
	[...]
	import_ns:      USB_STORAGE
	[...]

Si consiglia di posizionare la dichiarazione MODULE_IMPORT_NS() vicino
ai metadati del modulo come MODULE_AUTHOR() o MODULE_LICENSE(). Fate
riferimento alla sezione 5. per creare automaticamente le importazioni
mancanti.

4. Caricare moduli che usano simboli provenienti da spazi dei nomi
==================================================================

Quando un modulo viene caricato (per esempio usando ``insmod``), il kernel
verificherà la disponibilità di ogni simbolo usato e se lo spazio dei nomi
che potrebbe contenerli è stato importato. Il comportamento di base del kernel
è di rifiutarsi di caricare quei moduli che non importano tutti gli spazi dei
nomi necessari. L'errore verrà annotato e il caricamento fallirà con l'errore
EINVAL. Per caricare i moduli che non soddisfano questo requisito esiste
un'opzione di configurazione: impostare
MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y caricherà i moduli comunque ma
emetterà un avviso.

5. Creare automaticamente la dichiarazione MODULE_IMPORT_NS
===========================================================

La mancanza di un'importazione può essere individuata facilmente al momento
della compilazione. Infatti, modpost emetterà un avviso se il modulo usa
un simbolo da uno spazio dei nomi che non è stato importato.
La dichiarazione MODULE_IMPORT_NS() viene solitamente aggiunta in un posto
ben definito (assieme agli altri metadati del modulo). Per facilitare
la vita di chi scrive moduli (e i manutentori di sottosistemi), esistono uno
script e un target make per correggere le importazioni mancanti. Questo può
essere fatto con::

	$ make nsdeps

Lo scenario tipico di chi scrive un modulo potrebbe essere::

	- scrivere codice che dipende da un simbolo appartenente ad uno spazio
	  dei nomi non importato
	- eseguire ``make``
	- aver notato un avviso da modpost che parla di un'importazione
	  mancante
	- eseguire ``make nsdeps`` per aggiungere import nel posto giusto

Per i manutentori di sottosistemi che vogliono aggiungere uno spazio dei nomi,
l'approccio è simile. Di nuovo, eseguendo ``make nsdeps`` aggiungerà le
importazioni mancanti nei moduli inclusi nel kernel::

	- spostare o aggiungere simboli ad uno spazio dei nomi (per esempio
	  usando EXPORT_SYMBOL_NS())
	- eseguire ``make`` (preferibilmente con allmodconfig per coprire tutti
	  i moduli del kernel)
	- aver notato un avviso da modpost che parla di un'importazione
	  mancante
	- eseguire ``make nsdeps`` per aggiungere import nel posto giusto

Potete anche eseguire nsdeps per moduli esterni. Solitamente si usa così::

       $ make -C <path_to_kernel_src> M=$PWD nsdeps


code:
.. SPDX-License-Identifier: GPL-2.0

.. include:: ../../disclaimer-ita.rst

:Original: Documentation/devicetree/bindings/submitting-patches.rst

================================================
Sottomettere patch per devicetree (DT) *binding*
================================================

.. note:: to be translated


code:
:orphan:

.. warning::
   In caso di dubbi sulla correttezza del contenuto di questa traduzione,
   l'unico riferimento valido è la documentazione ufficiale in inglese.
   Per maggiori informazioni consultate le :ref:`avvertenze <it_disclaimer>`.


code:
.. 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
   kernel-doc
   parse-headers

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
.. 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 function_name.
   *
   * 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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Nei documenti reStructuredText non serve alcuna sintassi speciale per
fare riferimento a funzioni e tipi definiti nei commenti
kernel-doc. Sarà sufficiente terminare i nomi di funzione con ``()``,
e scrivere ``struct``, ``union``, ``enum``, o ``typedef`` prima di un
tipo. Per esempio::

  See foo()
  See struct foo.
  See union bar.
  See enum baz.
  See typedef meh.

Tuttavia, la personalizzazione dei collegamenti è possibile solo con
la seguente sintassi::

  See :c:func:`my custom link text for function foo <foo>`.
  See :c:type:`my custom link text for struct bar <bar>`.

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:

identifiers: *[ function/type ...]*
  Include la documentazione per ogni *function* e *type*  in *source*.
  Se non vengono esplicitamente specificate le funzioni da includere, allora
  verranno incluse tutte quelle disponibili in *source*.

  Esempi::

    .. kernel-doc:: lib/bitmap.c
       :identifiers: bitmap_parselist bitmap_parselist_user

    .. kernel-doc:: lib/idr.c
       :identifiers:

functions: *[ function ...]*
  Questo è uno pseudonimo, deprecato, per la direttiva 'identifiers'.

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

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


code:
.. 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/userspace-api/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.


code:
.. include:: ../disclaimer-ita.rst

.. note:: Per leggere la documentazione originale in inglese:
	  :ref:`Documentation/doc-guide/index.rst <doc_guide>`

.. _it_sphinxdoc:

=============================================
Usare Sphinx per la documentazione del kernel
=============================================

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.7 o superiore.

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::

   #) 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 2.4.4 di Sphinx dovete eseguire::

       $ virtualenv sphinx_2.4.4
       $ . sphinx_2.4.4/bin/activate
       (sphinx_2.4.4) $ pip install -r Documentation/sphinx/requirements.txt

Dopo aver eseguito ``. sphinx_2.4.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 2.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_2.4.4
		. sphinx_2.4.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 anche personalizzare l'ouptut html passando un livello aggiuntivo
DOCS_CSS usando la rispettiva variabile d'ambiente ``DOCS_CSS``.

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 più lunghi che
  beneficeranno della sintassi evidenziata. Per un breve pezzo di codice da
  inserire nel testo, usate \`\`.

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``.

Notate che per una funzione non c'è bisogno di usare ``c:func:`` per generarne
i riferimenti nella documentazione. Grazie a qualche magica estensione a
Sphinx, il sistema di generazione della documentazione trasformerà
automaticamente un riferimento ad una ``funzione()`` in un riferimento
incrociato quando questa ha una voce nell'indice.  Se trovate degli usi di
``c:func:`` nella documentazione del kernel, sentitevi liberi di rimuoverli.

Tabelle a liste
---------------

Il formato ``list-table`` può essere utile per tutte quelle tabelle che non
possono essere facilmente scritte usando il formato ASCII-art di Sphinx. Però,
questo genere di tabelle sono illeggibili per chi legge direttamente i file di
testo. Dunque, questo formato dovrebbe essere evitato senza forti argomenti che
ne giustifichino l'uso.

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

      * - row 1
        - field 1.1
        - field 1.2 with autospan

      * - row 2
        - field 2.1
        - :rspan:`1` :cspan:`1` field 2.2 - 3.3

      * .. _`it last row`:

        - row 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

      * - row 1
        - field 1.1
        - field 1.2 with autospan

      * - row 2
        - field 2.1
        - :rspan:`1` :cspan:`1` field 2.2 - 3.3

      * .. _`it last row`:

        - row 3

Riferimenti incrociati
----------------------

Aggiungere un riferimento incrociato da una pagina della
documentazione ad un'altra può essere fatto scrivendo il percorso al
file corrispondende, non serve alcuna sintassi speciale. Si possono
usare sia percorsi assoluti che relativi. Quelli assoluti iniziano con
"documentation/". Per esempio, potete fare riferimento a questo
documento in uno dei seguenti modi (da notare che l'estensione
``.rst`` è necessaria)::

    Vedere Documentation/doc-guide/sphinx.rst. Questo funziona sempre
    Guardate pshinx.rst, che si trova nella stessa cartella.
    Leggete ../sphinx.rst, che si trova nella cartella precedente.

Se volete che il collegamento abbia un testo diverso rispetto al
titolo del documento, allora dovrete usare la direttiva Sphinx
``doc``. Per esempio::

    Vedere :doc:`il mio testo per il collegamento <sphinx>`.

Nella maggioranza dei casi si consiglia il primo metodo perché è più
pulito ed adatto a chi legge dai sorgenti. Se incontrare un ``:doc:``
che non da alcun valore, sentitevi liberi di convertirlo in un
percorso al documento.

Per informazioni riguardo ai riferimenti incrociati ai commenti
kernel-doc per funzioni o tipi, consultate

.. _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 (:ref:`it_svg_image_example`)::

    .. 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>