Skip to content

Commit cda9445

Browse files
Mike SnitzerAnna Schumaker
authored andcommitted
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 <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent c817248 commit cda9445

File tree

5 files changed

+90
-13
lines changed

5 files changed

+90
-13
lines changed

fs/nfs/internal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,16 @@ extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
456456

457457
#if IS_ENABLED(CONFIG_NFS_LOCALIO)
458458
/* 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+
459469
extern void nfs_local_probe_async(struct nfs_client *);
460470
extern void nfs_local_probe_async_work(struct work_struct *);
461471
extern struct nfsd_file *nfs_local_open_fh(struct nfs_client *,

fs/nfs/localio.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -322,16 +322,6 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr,
322322
return iocb;
323323
}
324324

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-
335325
static bool
336326
nfs_is_local_dio_possible(struct nfs_local_kiocb *iocb, int rw,
337327
size_t len, struct nfs_local_dio *local_dio)
@@ -367,6 +357,10 @@ nfs_is_local_dio_possible(struct nfs_local_kiocb *iocb, int rw,
367357
local_dio->middle_len = middle_end - start_end;
368358
local_dio->end_len = orig_end - middle_end;
369359

360+
if (rw == ITER_DEST)
361+
trace_nfs_local_dio_read(hdr->inode, offset, len, local_dio);
362+
else
363+
trace_nfs_local_dio_write(hdr->inode, offset, len, local_dio);
370364
return true;
371365
}
372366

@@ -446,8 +440,11 @@ nfs_local_iters_setup_dio(struct nfs_local_kiocb *iocb, int rw,
446440
nfs_iov_iter_aligned_bvec(&iters[n_iters],
447441
local_dio->mem_align-1, local_dio->offset_align-1);
448442

449-
if (unlikely(!iocb->iter_is_dio_aligned[n_iters]))
443+
if (unlikely(!iocb->iter_is_dio_aligned[n_iters])) {
444+
trace_nfs_local_dio_misaligned(iocb->hdr->inode,
445+
iocb->hdr->args.offset, len, local_dio);
450446
return 0; /* no DIO-aligned IO possible */
447+
}
451448
++n_iters;
452449

453450
iocb->n_iters = n_iters;

fs/nfs/nfs2xdr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
#include <linux/nfs2.h>
2424
#include <linux/nfs_fs.h>
2525
#include <linux/nfs_common.h>
26-
#include "nfstrace.h"
2726
#include "internal.h"
27+
#include "nfstrace.h"
2828

2929
#define NFSDBG_FACILITY NFSDBG_XDR
3030

fs/nfs/nfs3xdr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
#include <linux/nfsacl.h>
2424
#include <linux/nfs_common.h>
2525

26-
#include "nfstrace.h"
2726
#include "internal.h"
27+
#include "nfstrace.h"
2828

2929
#define NFSDBG_FACILITY NFSDBG_XDR
3030

fs/nfs/nfstrace.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,6 +1732,76 @@ DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_write_completion);
17321732
DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_write_schedule_iovec);
17331733
DEFINE_NFS_DIRECT_REQ_EVENT(nfs_direct_write_reschedule_io);
17341734

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+
17351805
TRACE_EVENT(nfs_fh_to_dentry,
17361806
TP_PROTO(
17371807
const struct super_block *sb,

0 commit comments

Comments
 (0)