Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nfs/localio: add tracepoints for misaligned DIO READ and WRITE support

Add nfs_local_dio_class and use it to create nfs_local_dio_read,
nfs_local_dio_write and nfs_local_dio_misaligned trace events.

These trace events show how NFS LOCALIO splits a given misaligned
IO into a mix of misaligned head and/or tail extents and a DIO-aligned
middle extent. The misaligned head and/or tail extents are issued
using buffered IO and the DIO-aligned middle is issued using O_DIRECT.

This combination of trace events is useful for LOCALIO DIO READs:

echo 1 > /sys/kernel/tracing/events/nfs/nfs_local_dio_read/enable
echo 1 > /sys/kernel/tracing/events/nfs/nfs_local_dio_misaligned/enable
echo 1 > /sys/kernel/tracing/events/nfs/nfs_initiate_read/enable
echo 1 > /sys/kernel/tracing/events/nfs/nfs_readpage_done/enable
echo 1 > /sys/kernel/tracing/events/xfs/xfs_file_direct_read/enable

This combination of trace events is useful for LOCALIO DIO WRITEs:

echo 1 > /sys/kernel/tracing/events/nfs/nfs_local_dio_write/enable
echo 1 > /sys/kernel/tracing/events/nfs/nfs_local_dio_misaligned/enable
echo 1 > /sys/kernel/tracing/events/nfs/nfs_initiate_write/enable
echo 1 > /sys/kernel/tracing/events/nfs/nfs_writeback_done/enable
echo 1 > /sys/kernel/tracing/events/xfs/xfs_file_direct_write/enable

Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>

authored by

Mike Snitzer and committed by
Anna Schumaker
cda94457 c817248f

+90 -13
+10
fs/nfs/internal.h
··· 456 456 457 457 #if IS_ENABLED(CONFIG_NFS_LOCALIO) 458 458 /* localio.c */ 459 + struct nfs_local_dio { 460 + u32 mem_align; 461 + u32 offset_align; 462 + loff_t middle_offset; 463 + loff_t end_offset; 464 + ssize_t start_len; /* Length for misaligned first extent */ 465 + ssize_t middle_len; /* Length for DIO-aligned middle extent */ 466 + ssize_t end_len; /* Length for misaligned last extent */ 467 + }; 468 + 459 469 extern void nfs_local_probe_async(struct nfs_client *); 460 470 extern void nfs_local_probe_async_work(struct work_struct *); 461 471 extern struct nfsd_file *nfs_local_open_fh(struct nfs_client *,
+8 -11
fs/nfs/localio.c
··· 322 322 return iocb; 323 323 } 324 324 325 - struct nfs_local_dio { 326 - u32 mem_align; 327 - u32 offset_align; 328 - loff_t middle_offset; 329 - loff_t end_offset; 330 - ssize_t start_len; /* Length for misaligned first extent */ 331 - ssize_t middle_len; /* Length for DIO-aligned middle extent */ 332 - ssize_t end_len; /* Length for misaligned last extent */ 333 - }; 334 - 335 325 static bool 336 326 nfs_is_local_dio_possible(struct nfs_local_kiocb *iocb, int rw, 337 327 size_t len, struct nfs_local_dio *local_dio) ··· 357 367 local_dio->middle_len = middle_end - start_end; 358 368 local_dio->end_len = orig_end - middle_end; 359 369 370 + if (rw == ITER_DEST) 371 + trace_nfs_local_dio_read(hdr->inode, offset, len, local_dio); 372 + else 373 + trace_nfs_local_dio_write(hdr->inode, offset, len, local_dio); 360 374 return true; 361 375 } 362 376 ··· 440 446 nfs_iov_iter_aligned_bvec(&iters[n_iters], 441 447 local_dio->mem_align-1, local_dio->offset_align-1); 442 448 443 - if (unlikely(!iocb->iter_is_dio_aligned[n_iters])) 449 + if (unlikely(!iocb->iter_is_dio_aligned[n_iters])) { 450 + trace_nfs_local_dio_misaligned(iocb->hdr->inode, 451 + iocb->hdr->args.offset, len, local_dio); 444 452 return 0; /* no DIO-aligned IO possible */ 453 + } 445 454 ++n_iters; 446 455 447 456 iocb->n_iters = n_iters;
+1 -1
fs/nfs/nfs2xdr.c
··· 23 23 #include <linux/nfs2.h> 24 24 #include <linux/nfs_fs.h> 25 25 #include <linux/nfs_common.h> 26 - #include "nfstrace.h" 27 26 #include "internal.h" 27 + #include "nfstrace.h" 28 28 29 29 #define NFSDBG_FACILITY NFSDBG_XDR 30 30
+1 -1
fs/nfs/nfs3xdr.c
··· 23 23 #include <linux/nfsacl.h> 24 24 #include <linux/nfs_common.h> 25 25 26 - #include "nfstrace.h" 27 26 #include "internal.h" 27 + #include "nfstrace.h" 28 28 29 29 #define NFSDBG_FACILITY NFSDBG_XDR 30 30
+70
fs/nfs/nfstrace.h
··· 1732 1732 DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_write_schedule_iovec); 1733 1733 DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_write_reschedule_io); 1734 1734 1735 + #if IS_ENABLED(CONFIG_NFS_LOCALIO) 1736 + 1737 + DECLARE_EVENT_CLASS(nfs_local_dio_class, 1738 + TP_PROTO( 1739 + const struct inode *inode, 1740 + loff_t offset, 1741 + ssize_t count, 1742 + const struct nfs_local_dio *local_dio 1743 + ), 1744 + TP_ARGS(inode, offset, count, local_dio), 1745 + TP_STRUCT__entry( 1746 + __field(dev_t, dev) 1747 + __field(u64, fileid) 1748 + __field(u32, fhandle) 1749 + __field(loff_t, offset) 1750 + __field(ssize_t, count) 1751 + __field(u32, mem_align) 1752 + __field(u32, offset_align) 1753 + __field(loff_t, start) 1754 + __field(ssize_t, start_len) 1755 + __field(loff_t, middle) 1756 + __field(ssize_t, middle_len) 1757 + __field(loff_t, end) 1758 + __field(ssize_t, end_len) 1759 + ), 1760 + TP_fast_assign( 1761 + const struct nfs_inode *nfsi = NFS_I(inode); 1762 + const struct nfs_fh *fh = &nfsi->fh; 1763 + 1764 + __entry->dev = inode->i_sb->s_dev; 1765 + __entry->fileid = nfsi->fileid; 1766 + __entry->fhandle = nfs_fhandle_hash(fh); 1767 + __entry->offset = offset; 1768 + __entry->count = count; 1769 + __entry->mem_align = local_dio->mem_align; 1770 + __entry->offset_align = local_dio->offset_align; 1771 + __entry->start = offset; 1772 + __entry->start_len = local_dio->start_len; 1773 + __entry->middle = local_dio->middle_offset; 1774 + __entry->middle_len = local_dio->middle_len; 1775 + __entry->end = local_dio->end_offset; 1776 + __entry->end_len = local_dio->end_len; 1777 + ), 1778 + TP_printk("fileid=%02x:%02x:%llu fhandle=0x%08x " 1779 + "offset=%lld count=%zd " 1780 + "mem_align=%u offset_align=%u " 1781 + "start=%llu+%zd middle=%llu+%zd end=%llu+%zd", 1782 + MAJOR(__entry->dev), MINOR(__entry->dev), 1783 + (unsigned long long)__entry->fileid, 1784 + __entry->fhandle, __entry->offset, __entry->count, 1785 + __entry->mem_align, __entry->offset_align, 1786 + __entry->start, __entry->start_len, 1787 + __entry->middle, __entry->middle_len, 1788 + __entry->end, __entry->end_len) 1789 + ) 1790 + 1791 + #define DEFINE_NFS_LOCAL_DIO_EVENT(name) \ 1792 + DEFINE_EVENT(nfs_local_dio_class, nfs_local_dio_##name, \ 1793 + TP_PROTO(const struct inode *inode, \ 1794 + loff_t offset, \ 1795 + ssize_t count, \ 1796 + const struct nfs_local_dio *local_dio),\ 1797 + TP_ARGS(inode, offset, count, local_dio)) 1798 + 1799 + DEFINE_NFS_LOCAL_DIO_EVENT(read); 1800 + DEFINE_NFS_LOCAL_DIO_EVENT(write); 1801 + DEFINE_NFS_LOCAL_DIO_EVENT(misaligned); 1802 + 1803 + #endif /* CONFIG_NFS_LOCALIO */ 1804 + 1735 1805 TRACE_EVENT(nfs_fh_to_dentry, 1736 1806 TP_PROTO( 1737 1807 const struct super_block *sb,