Update documentation for ioctl_sniffer and nvidia_driver_differ tools.

PiperOrigin-RevId: 663537632
This commit is contained in:
Anthony Cui
2024-08-15 18:55:16 -07:00
committed by gVisor bot
parent 9cead45d4a
commit 930c3d7a22
3 changed files with 83 additions and 11 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ Once we have the binary, we can hook into any GPU workload by passing the
corresponding command to run it to `run_sniffer`, like so:
```
./run_sniffer nvidia-smi
bin/run_sniffer nvidia-smi
```
This should run the workload as normal and provide an output of all the
+59
View File
@@ -0,0 +1,59 @@
# NVIDIA Driver Differ
This tool is intended to help adoption of new NVIDIA driver versions. It
compares two driver versions (one currently supported by `nvproxy` and one that
is not) and reports any changes to `ioctl` structs that exists between the two
versions. However, it only does this for `ioctl` structs that are currently
supported by `nvproxy`, giving a targeted but comprehensive understanding of
what changes need to be reflected in `nvproxy` to support the newer driver
version.
To do this, the tool needs to parse the NVIDIA driver source code. This is done
using
[Clang's AST Matcher API](https://clang.llvm.org/docs/LibASTMatchersReference.html)
to generate an AST of the NVIDIA driver, which the tool then searches and
traverses to get a comprehensive definition of every struct `nvproxy` relies on.
## Usage
Everything is packaged for convenience inside `run_differ`. The differ accepts
two version numbers as arguments: a `base` version which is currently supported
in `nvproxy`, and a `next` version that is compared against `base`. For example,
comparing versions `550.90.07` and `560.31.02` can be done like so:
```bash
make run TARGETS=//tools/nvidia_driver_differ:run_differ ARGS="--base 550.90.07 --next 560.31.02"
```
This will fetch the corresponding source code from Github, parse it using Clang,
and then compare the definitions that were found. Any differences will be
printed to standard output. These differences can be additions of new fields to
structs, or changes to the name or type of existing fields. For example:
```
struct NEW_FIELD_EXAMPLE
[]parser.RecordField{
... // 10 identical elements
+ s"bool newField1"
+ s"int newField2"
}
struct MODIFIED_FIELD_EXAMPLE
[]parser.RecordField{
... // 10 identical elements
{
- Name: "oldName",
+ Name: "newName",
Type: "int",
Offset: 36
},
{
Name: "arrayField",
- Type: "int[10]",
+ Type: "int[12]",
Offset: 40
},
}
```
[A deeper dive into how this tool works can be found here.](https://github.com/google/gvisor/blob/master/g3doc/proposals/nvidia_driver_differ.md)
+23 -10
View File
@@ -16,26 +16,39 @@
#define TOOLS_NVIDIA_DRIVER_DIFFER_DRIVER_AST_PARSER_H_
const char ToolHelpDescription[] =
R"a(This tool parses a given C++ source file and outputs the struct definitions
for a list of provided struct names. To parse structs defined in multiple files,
it is easier to create a C++ file that includes all the files to be parsed. You
will also need a compile_commands.json file that contains a compile command with
the relevant include directories.
R"a(This tool parses a given C++ source file and outputs relevant definitions
for a list of provided struct names. It finds the definitions for each struct
given by the names provided, as well as any nested structs or types that they
depend on.
This tool is intended to be used to parse the NVIDIA driver source code; as
such, there are some assumptions made about how structs are defined and what
types are used.
To parse structs defined in multiple files, it is easier to create a C++ file
that includes all the files to be parsed. You will also need a
compile_commands.json file that contains a compile command with the relevant
include directories.
The struct names should be specified in a JSON file containing a JSON object,
which has a "structs" key that maps to a list of strings. The tool will search
for the struct definition in the given source files, and output the struct
definition to the specified output file.
This output file will contain a JSON object with a "structs" field mapping each
struct name to its struct definition. Each struct definition will be a JSON
array of fields, where each field is a JSON object with a "name" and a "type"
key. The fields will be ordered in the same order as they appear in the struct
This output file will contain a JSON object with a "records" (structs or unions)
field mapping each name to its definition, as well as an "aliases" field for
any aliases that were found. A variety of information is outputted:
- For records, the fields are given as a JSON array of objects with "name",
"type", and "offset" keys. The record also has a "size" key indicating the
size of the struct in bytes, an "is_union" key indicating whether it is a
union or not, and a "source" key containing the file name and line number
where it was defined.
- For aliases, the type is given as a JSON object with a "type" and "size" key
Example usage:
driver_ast_parser --structs=structs.json -o=output.json driver_source_files.h
The structs.json file should contain an array of struct names to parse:
structs.json:
{
"structs": [
"TestStruct",