mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 10:29:37 +00:00
![Greg Kroah-Hartman](/assets/img/avatar_default.png)
Many source files in the tree are missing licensing information, which makes it harder for compliance tools to determine the correct license. By default all files without license information are under the default license of the kernel, which is GPL version 2. Update the files which contain no license information with the 'GPL-2.0' SPDX license identifier. The SPDX identifier is a legally binding shorthand, which can be used instead of the full boiler plate text. This patch is based on work done by Thomas Gleixner and Kate Stewart and Philippe Ombredanne. How this work was done: Patches were generated and checked against linux-4.14-rc6 for a subset of the use cases: - file had no licensing information it it. - file was a */uapi/* one with no licensing information in it, - file was a */uapi/* one with existing licensing information, Further patches will be generated in subsequent months to fix up cases where non-standard license headers were used, and references to license had to be inferred by heuristics based on keywords. The analysis to determine which SPDX License Identifier to be applied to a file was done in a spreadsheet of side by side results from of the output of two independent scanners (ScanCode & Windriver) producing SPDX tag:value files created by Philippe Ombredanne. Philippe prepared the base worksheet, and did an initial spot review of a few 1000 files. The 4.13 kernel was the starting point of the analysis with 60,537 files assessed. Kate Stewart did a file by file comparison of the scanner results in the spreadsheet to determine which SPDX license identifier(s) to be applied to the file. She confirmed any determination that was not immediately clear with lawyers working with the Linux Foundation. Criteria used to select files for SPDX license identifier tagging was: - Files considered eligible had to be source code files. - Make and config files were included as candidates if they contained >5 lines of source - File already had some variant of a license header in it (even if <5 lines). All documentation files were explicitly excluded. The following heuristics were used to determine which SPDX license identifiers to apply. - when both scanners couldn't find any license traces, file was considered to have no license information in it, and the top level COPYING file license applied. For non */uapi/* files that summary was: SPDX license identifier # files ---------------------------------------------------|------- GPL-2.0 11139 and resulted in the first patch in this series. If that file was a */uapi/* path one, it was "GPL-2.0 WITH Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was: SPDX license identifier # files ---------------------------------------------------|------- GPL-2.0 WITH Linux-syscall-note 930 and resulted in the second patch in this series. - if a file had some form of licensing information in it, and was one of the */uapi/* ones, it was denoted with the Linux-syscall-note if any GPL family license was found in the file or had no licensing in it (per prior point). Results summary: SPDX license identifier # files ---------------------------------------------------|------ GPL-2.0 WITH Linux-syscall-note 270 GPL-2.0+ WITH Linux-syscall-note 169 ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21 ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17 LGPL-2.1+ WITH Linux-syscall-note 15 GPL-1.0+ WITH Linux-syscall-note 14 ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5 LGPL-2.0+ WITH Linux-syscall-note 4 LGPL-2.1 WITH Linux-syscall-note 3 ((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3 ((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1 and that resulted in the third patch in this series. - when the two scanners agreed on the detected license(s), that became the concluded license(s). - when there was disagreement between the two scanners (one detected a license but the other didn't, or they both detected different licenses) a manual inspection of the file occurred. - In most cases a manual inspection of the information in the file resulted in a clear resolution of the license that should apply (and which scanner probably needed to revisit its heuristics). - When it was not immediately clear, the license identifier was confirmed with lawyers working with the Linux Foundation. - If there was any question as to the appropriate license identifier, the file was flagged for further research and to be revisited later in time. In total, over 70 hours of logged manual review was done on the spreadsheet to determine the SPDX license identifiers to apply to the source files by Kate, Philippe, Thomas and, in some cases, confirmation by lawyers working with the Linux Foundation. Kate also obtained a third independent scan of the 4.13 code base from FOSSology, and compared selected files where the other two scanners disagreed against that SPDX file, to see if there was new insights. The Windriver scanner is based on an older version of FOSSology in part, so they are related. Thomas did random spot checks in about 500 files from the spreadsheets for the uapi headers and agreed with SPDX license identifier in the files he inspected. For the non-uapi files Thomas did random spot checks in about 15000 files. In initial set of patches against 4.14-rc6, 3 files were found to have copy/paste license identifier errors, and have been fixed to reflect the correct identifier. Additionally Philippe spent 10 hours this week doing a detailed manual inspection and review of the 12,461 patched files from the initial patch version early this week with: - a full scancode scan run, collecting the matched texts, detected license ids and scores - reviewing anything where there was a license detected (about 500+ files) to ensure that the applied SPDX license was correct - reviewing anything where there was no detection but the patch license was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied SPDX license was correct This produced a worksheet with 20 files needing minor correction. This worksheet was then exported into 3 different .csv files for the different types of files to be modified. These .csv files were then reviewed by Greg. Thomas wrote a script to parse the csv files and add the proper SPDX tag to the file, in the format that the file expected. This script was further refined by Greg based on the output to detect more types of files automatically and to distinguish between header and source .c files (which need different comment types.) Finally Greg ran the script using the .csv files to generate the patches. Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
642 lines
17 KiB
C
642 lines
17 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM block
|
|
|
|
#if !defined(_TRACE_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ)
|
|
#define _TRACE_BLOCK_H
|
|
|
|
#include <linux/blktrace_api.h>
|
|
#include <linux/blkdev.h>
|
|
#include <linux/buffer_head.h>
|
|
#include <linux/tracepoint.h>
|
|
|
|
#define RWBS_LEN 8
|
|
|
|
DECLARE_EVENT_CLASS(block_buffer,
|
|
|
|
TP_PROTO(struct buffer_head *bh),
|
|
|
|
TP_ARGS(bh),
|
|
|
|
TP_STRUCT__entry (
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( size_t, size )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = bh->b_bdev->bd_dev;
|
|
__entry->sector = bh->b_blocknr;
|
|
__entry->size = bh->b_size;
|
|
),
|
|
|
|
TP_printk("%d,%d sector=%llu size=%zu",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev),
|
|
(unsigned long long)__entry->sector, __entry->size
|
|
)
|
|
);
|
|
|
|
/**
|
|
* block_touch_buffer - mark a buffer accessed
|
|
* @bh: buffer_head being touched
|
|
*
|
|
* Called from touch_buffer().
|
|
*/
|
|
DEFINE_EVENT(block_buffer, block_touch_buffer,
|
|
|
|
TP_PROTO(struct buffer_head *bh),
|
|
|
|
TP_ARGS(bh)
|
|
);
|
|
|
|
/**
|
|
* block_dirty_buffer - mark a buffer dirty
|
|
* @bh: buffer_head being dirtied
|
|
*
|
|
* Called from mark_buffer_dirty().
|
|
*/
|
|
DEFINE_EVENT(block_buffer, block_dirty_buffer,
|
|
|
|
TP_PROTO(struct buffer_head *bh),
|
|
|
|
TP_ARGS(bh)
|
|
);
|
|
|
|
/**
|
|
* block_rq_requeue - place block IO request back on a queue
|
|
* @q: queue holding operation
|
|
* @rq: block IO operation request
|
|
*
|
|
* The block operation request @rq is being placed back into queue
|
|
* @q. For some reason the request was not completed and needs to be
|
|
* put back in the queue.
|
|
*/
|
|
TRACE_EVENT(block_rq_requeue,
|
|
|
|
TP_PROTO(struct request_queue *q, struct request *rq),
|
|
|
|
TP_ARGS(q, rq),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned int, nr_sector )
|
|
__array( char, rwbs, RWBS_LEN )
|
|
__dynamic_array( char, cmd, 1 )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
|
|
__entry->sector = blk_rq_trace_sector(rq);
|
|
__entry->nr_sector = blk_rq_trace_nr_sectors(rq);
|
|
|
|
blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
|
|
__get_str(cmd)[0] = '\0';
|
|
),
|
|
|
|
TP_printk("%d,%d %s (%s) %llu + %u [%d]",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev),
|
|
__entry->rwbs, __get_str(cmd),
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector, 0)
|
|
);
|
|
|
|
/**
|
|
* block_rq_complete - block IO operation completed by device driver
|
|
* @rq: block operations request
|
|
* @error: status code
|
|
* @nr_bytes: number of completed bytes
|
|
*
|
|
* The block_rq_complete tracepoint event indicates that some portion
|
|
* of operation request has been completed by the device driver. If
|
|
* the @rq->bio is %NULL, then there is absolutely no additional work to
|
|
* do for the request. If @rq->bio is non-NULL then there is
|
|
* additional work required to complete the request.
|
|
*/
|
|
TRACE_EVENT(block_rq_complete,
|
|
|
|
TP_PROTO(struct request *rq, int error, unsigned int nr_bytes),
|
|
|
|
TP_ARGS(rq, error, nr_bytes),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned int, nr_sector )
|
|
__field( int, error )
|
|
__array( char, rwbs, RWBS_LEN )
|
|
__dynamic_array( char, cmd, 1 )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
|
|
__entry->sector = blk_rq_pos(rq);
|
|
__entry->nr_sector = nr_bytes >> 9;
|
|
__entry->error = error;
|
|
|
|
blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, nr_bytes);
|
|
__get_str(cmd)[0] = '\0';
|
|
),
|
|
|
|
TP_printk("%d,%d %s (%s) %llu + %u [%d]",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev),
|
|
__entry->rwbs, __get_str(cmd),
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector, __entry->error)
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(block_rq,
|
|
|
|
TP_PROTO(struct request_queue *q, struct request *rq),
|
|
|
|
TP_ARGS(q, rq),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned int, nr_sector )
|
|
__field( unsigned int, bytes )
|
|
__array( char, rwbs, RWBS_LEN )
|
|
__array( char, comm, TASK_COMM_LEN )
|
|
__dynamic_array( char, cmd, 1 )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
|
|
__entry->sector = blk_rq_trace_sector(rq);
|
|
__entry->nr_sector = blk_rq_trace_nr_sectors(rq);
|
|
__entry->bytes = blk_rq_bytes(rq);
|
|
|
|
blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
|
|
__get_str(cmd)[0] = '\0';
|
|
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
|
|
),
|
|
|
|
TP_printk("%d,%d %s %u (%s) %llu + %u [%s]",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev),
|
|
__entry->rwbs, __entry->bytes, __get_str(cmd),
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector, __entry->comm)
|
|
);
|
|
|
|
/**
|
|
* block_rq_insert - insert block operation request into queue
|
|
* @q: target queue
|
|
* @rq: block IO operation request
|
|
*
|
|
* Called immediately before block operation request @rq is inserted
|
|
* into queue @q. The fields in the operation request @rq struct can
|
|
* be examined to determine which device and sectors the pending
|
|
* operation would access.
|
|
*/
|
|
DEFINE_EVENT(block_rq, block_rq_insert,
|
|
|
|
TP_PROTO(struct request_queue *q, struct request *rq),
|
|
|
|
TP_ARGS(q, rq)
|
|
);
|
|
|
|
/**
|
|
* block_rq_issue - issue pending block IO request operation to device driver
|
|
* @q: queue holding operation
|
|
* @rq: block IO operation operation request
|
|
*
|
|
* Called when block operation request @rq from queue @q is sent to a
|
|
* device driver for processing.
|
|
*/
|
|
DEFINE_EVENT(block_rq, block_rq_issue,
|
|
|
|
TP_PROTO(struct request_queue *q, struct request *rq),
|
|
|
|
TP_ARGS(q, rq)
|
|
);
|
|
|
|
/**
|
|
* block_bio_bounce - used bounce buffer when processing block operation
|
|
* @q: queue holding the block operation
|
|
* @bio: block operation
|
|
*
|
|
* A bounce buffer was used to handle the block operation @bio in @q.
|
|
* This occurs when hardware limitations prevent a direct transfer of
|
|
* data between the @bio data memory area and the IO device. Use of a
|
|
* bounce buffer requires extra copying of data and decreases
|
|
* performance.
|
|
*/
|
|
TRACE_EVENT(block_bio_bounce,
|
|
|
|
TP_PROTO(struct request_queue *q, struct bio *bio),
|
|
|
|
TP_ARGS(q, bio),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned int, nr_sector )
|
|
__array( char, rwbs, RWBS_LEN )
|
|
__array( char, comm, TASK_COMM_LEN )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = bio_dev(bio);
|
|
__entry->sector = bio->bi_iter.bi_sector;
|
|
__entry->nr_sector = bio_sectors(bio);
|
|
blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size);
|
|
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
|
|
),
|
|
|
|
TP_printk("%d,%d %s %llu + %u [%s]",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector, __entry->comm)
|
|
);
|
|
|
|
/**
|
|
* block_bio_complete - completed all work on the block operation
|
|
* @q: queue holding the block operation
|
|
* @bio: block operation completed
|
|
* @error: io error value
|
|
*
|
|
* This tracepoint indicates there is no further work to do on this
|
|
* block IO operation @bio.
|
|
*/
|
|
TRACE_EVENT(block_bio_complete,
|
|
|
|
TP_PROTO(struct request_queue *q, struct bio *bio, int error),
|
|
|
|
TP_ARGS(q, bio, error),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned, nr_sector )
|
|
__field( int, error )
|
|
__array( char, rwbs, RWBS_LEN)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = bio_dev(bio);
|
|
__entry->sector = bio->bi_iter.bi_sector;
|
|
__entry->nr_sector = bio_sectors(bio);
|
|
__entry->error = error;
|
|
blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size);
|
|
),
|
|
|
|
TP_printk("%d,%d %s %llu + %u [%d]",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector, __entry->error)
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(block_bio_merge,
|
|
|
|
TP_PROTO(struct request_queue *q, struct request *rq, struct bio *bio),
|
|
|
|
TP_ARGS(q, rq, bio),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned int, nr_sector )
|
|
__array( char, rwbs, RWBS_LEN )
|
|
__array( char, comm, TASK_COMM_LEN )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = bio_dev(bio);
|
|
__entry->sector = bio->bi_iter.bi_sector;
|
|
__entry->nr_sector = bio_sectors(bio);
|
|
blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size);
|
|
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
|
|
),
|
|
|
|
TP_printk("%d,%d %s %llu + %u [%s]",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector, __entry->comm)
|
|
);
|
|
|
|
/**
|
|
* block_bio_backmerge - merging block operation to the end of an existing operation
|
|
* @q: queue holding operation
|
|
* @rq: request bio is being merged into
|
|
* @bio: new block operation to merge
|
|
*
|
|
* Merging block request @bio to the end of an existing block request
|
|
* in queue @q.
|
|
*/
|
|
DEFINE_EVENT(block_bio_merge, block_bio_backmerge,
|
|
|
|
TP_PROTO(struct request_queue *q, struct request *rq, struct bio *bio),
|
|
|
|
TP_ARGS(q, rq, bio)
|
|
);
|
|
|
|
/**
|
|
* block_bio_frontmerge - merging block operation to the beginning of an existing operation
|
|
* @q: queue holding operation
|
|
* @rq: request bio is being merged into
|
|
* @bio: new block operation to merge
|
|
*
|
|
* Merging block IO operation @bio to the beginning of an existing block
|
|
* operation in queue @q.
|
|
*/
|
|
DEFINE_EVENT(block_bio_merge, block_bio_frontmerge,
|
|
|
|
TP_PROTO(struct request_queue *q, struct request *rq, struct bio *bio),
|
|
|
|
TP_ARGS(q, rq, bio)
|
|
);
|
|
|
|
/**
|
|
* block_bio_queue - putting new block IO operation in queue
|
|
* @q: queue holding operation
|
|
* @bio: new block operation
|
|
*
|
|
* About to place the block IO operation @bio into queue @q.
|
|
*/
|
|
TRACE_EVENT(block_bio_queue,
|
|
|
|
TP_PROTO(struct request_queue *q, struct bio *bio),
|
|
|
|
TP_ARGS(q, bio),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned int, nr_sector )
|
|
__array( char, rwbs, RWBS_LEN )
|
|
__array( char, comm, TASK_COMM_LEN )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = bio_dev(bio);
|
|
__entry->sector = bio->bi_iter.bi_sector;
|
|
__entry->nr_sector = bio_sectors(bio);
|
|
blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size);
|
|
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
|
|
),
|
|
|
|
TP_printk("%d,%d %s %llu + %u [%s]",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector, __entry->comm)
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(block_get_rq,
|
|
|
|
TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
|
|
|
|
TP_ARGS(q, bio, rw),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned int, nr_sector )
|
|
__array( char, rwbs, RWBS_LEN )
|
|
__array( char, comm, TASK_COMM_LEN )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = bio ? bio_dev(bio) : 0;
|
|
__entry->sector = bio ? bio->bi_iter.bi_sector : 0;
|
|
__entry->nr_sector = bio ? bio_sectors(bio) : 0;
|
|
blk_fill_rwbs(__entry->rwbs,
|
|
bio ? bio->bi_opf : 0, __entry->nr_sector);
|
|
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
|
|
),
|
|
|
|
TP_printk("%d,%d %s %llu + %u [%s]",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector, __entry->comm)
|
|
);
|
|
|
|
/**
|
|
* block_getrq - get a free request entry in queue for block IO operations
|
|
* @q: queue for operations
|
|
* @bio: pending block IO operation (can be %NULL)
|
|
* @rw: low bit indicates a read (%0) or a write (%1)
|
|
*
|
|
* A request struct for queue @q has been allocated to handle the
|
|
* block IO operation @bio.
|
|
*/
|
|
DEFINE_EVENT(block_get_rq, block_getrq,
|
|
|
|
TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
|
|
|
|
TP_ARGS(q, bio, rw)
|
|
);
|
|
|
|
/**
|
|
* block_sleeprq - waiting to get a free request entry in queue for block IO operation
|
|
* @q: queue for operation
|
|
* @bio: pending block IO operation (can be %NULL)
|
|
* @rw: low bit indicates a read (%0) or a write (%1)
|
|
*
|
|
* In the case where a request struct cannot be provided for queue @q
|
|
* the process needs to wait for an request struct to become
|
|
* available. This tracepoint event is generated each time the
|
|
* process goes to sleep waiting for request struct become available.
|
|
*/
|
|
DEFINE_EVENT(block_get_rq, block_sleeprq,
|
|
|
|
TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
|
|
|
|
TP_ARGS(q, bio, rw)
|
|
);
|
|
|
|
/**
|
|
* block_plug - keep operations requests in request queue
|
|
* @q: request queue to plug
|
|
*
|
|
* Plug the request queue @q. Do not allow block operation requests
|
|
* to be sent to the device driver. Instead, accumulate requests in
|
|
* the queue to improve throughput performance of the block device.
|
|
*/
|
|
TRACE_EVENT(block_plug,
|
|
|
|
TP_PROTO(struct request_queue *q),
|
|
|
|
TP_ARGS(q),
|
|
|
|
TP_STRUCT__entry(
|
|
__array( char, comm, TASK_COMM_LEN )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
|
|
),
|
|
|
|
TP_printk("[%s]", __entry->comm)
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(block_unplug,
|
|
|
|
TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit),
|
|
|
|
TP_ARGS(q, depth, explicit),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( int, nr_rq )
|
|
__array( char, comm, TASK_COMM_LEN )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->nr_rq = depth;
|
|
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
|
|
),
|
|
|
|
TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
|
|
);
|
|
|
|
/**
|
|
* block_unplug - release of operations requests in request queue
|
|
* @q: request queue to unplug
|
|
* @depth: number of requests just added to the queue
|
|
* @explicit: whether this was an explicit unplug, or one from schedule()
|
|
*
|
|
* Unplug request queue @q because device driver is scheduled to work
|
|
* on elements in the request queue.
|
|
*/
|
|
DEFINE_EVENT(block_unplug, block_unplug,
|
|
|
|
TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit),
|
|
|
|
TP_ARGS(q, depth, explicit)
|
|
);
|
|
|
|
/**
|
|
* block_split - split a single bio struct into two bio structs
|
|
* @q: queue containing the bio
|
|
* @bio: block operation being split
|
|
* @new_sector: The starting sector for the new bio
|
|
*
|
|
* The bio request @bio in request queue @q needs to be split into two
|
|
* bio requests. The newly created @bio request starts at
|
|
* @new_sector. This split may be required due to hardware limitation
|
|
* such as operation crossing device boundaries in a RAID system.
|
|
*/
|
|
TRACE_EVENT(block_split,
|
|
|
|
TP_PROTO(struct request_queue *q, struct bio *bio,
|
|
unsigned int new_sector),
|
|
|
|
TP_ARGS(q, bio, new_sector),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( sector_t, new_sector )
|
|
__array( char, rwbs, RWBS_LEN )
|
|
__array( char, comm, TASK_COMM_LEN )
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = bio_dev(bio);
|
|
__entry->sector = bio->bi_iter.bi_sector;
|
|
__entry->new_sector = new_sector;
|
|
blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size);
|
|
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
|
|
),
|
|
|
|
TP_printk("%d,%d %s %llu / %llu [%s]",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
|
|
(unsigned long long)__entry->sector,
|
|
(unsigned long long)__entry->new_sector,
|
|
__entry->comm)
|
|
);
|
|
|
|
/**
|
|
* block_bio_remap - map request for a logical device to the raw device
|
|
* @q: queue holding the operation
|
|
* @bio: revised operation
|
|
* @dev: device for the operation
|
|
* @from: original sector for the operation
|
|
*
|
|
* An operation for a logical device has been mapped to the
|
|
* raw block device.
|
|
*/
|
|
TRACE_EVENT(block_bio_remap,
|
|
|
|
TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
|
|
sector_t from),
|
|
|
|
TP_ARGS(q, bio, dev, from),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned int, nr_sector )
|
|
__field( dev_t, old_dev )
|
|
__field( sector_t, old_sector )
|
|
__array( char, rwbs, RWBS_LEN)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = bio_dev(bio);
|
|
__entry->sector = bio->bi_iter.bi_sector;
|
|
__entry->nr_sector = bio_sectors(bio);
|
|
__entry->old_dev = dev;
|
|
__entry->old_sector = from;
|
|
blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size);
|
|
),
|
|
|
|
TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector,
|
|
MAJOR(__entry->old_dev), MINOR(__entry->old_dev),
|
|
(unsigned long long)__entry->old_sector)
|
|
);
|
|
|
|
/**
|
|
* block_rq_remap - map request for a block operation request
|
|
* @q: queue holding the operation
|
|
* @rq: block IO operation request
|
|
* @dev: device for the operation
|
|
* @from: original sector for the operation
|
|
*
|
|
* The block operation request @rq in @q has been remapped. The block
|
|
* operation request @rq holds the current information and @from hold
|
|
* the original sector.
|
|
*/
|
|
TRACE_EVENT(block_rq_remap,
|
|
|
|
TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev,
|
|
sector_t from),
|
|
|
|
TP_ARGS(q, rq, dev, from),
|
|
|
|
TP_STRUCT__entry(
|
|
__field( dev_t, dev )
|
|
__field( sector_t, sector )
|
|
__field( unsigned int, nr_sector )
|
|
__field( dev_t, old_dev )
|
|
__field( sector_t, old_sector )
|
|
__field( unsigned int, nr_bios )
|
|
__array( char, rwbs, RWBS_LEN)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->dev = disk_devt(rq->rq_disk);
|
|
__entry->sector = blk_rq_pos(rq);
|
|
__entry->nr_sector = blk_rq_sectors(rq);
|
|
__entry->old_dev = dev;
|
|
__entry->old_sector = from;
|
|
__entry->nr_bios = blk_rq_count_bios(rq);
|
|
blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
|
|
),
|
|
|
|
TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu %u",
|
|
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
|
|
(unsigned long long)__entry->sector,
|
|
__entry->nr_sector,
|
|
MAJOR(__entry->old_dev), MINOR(__entry->old_dev),
|
|
(unsigned long long)__entry->old_sector, __entry->nr_bios)
|
|
);
|
|
|
|
#endif /* _TRACE_BLOCK_H */
|
|
|
|
/* This part must be outside protection */
|
|
#include <trace/define_trace.h>
|
|
|