xfs: add kmem allocation trace points
authorDave Chinner <dchinner@redhat.com>
Mon, 26 Aug 2019 19:08:10 +0000 (12:08 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Tue, 27 Aug 2019 00:43:14 +0000 (17:43 -0700)
When trying to correlate XFS kernel allocations to memory reclaim
behaviour, it is useful to know what allocations XFS is actually
attempting. This information is not directly available from
tracepoints in the generic memory allocation and reclaim
tracepoints, so these new trace points provide a high level
indication of what the XFS memory demand actually is.

There is no per-filesystem context in this code, so we just trace
the type of allocation, the size and the allocation constraints.
The kmem code also doesn't include much of the common XFS headers,
so there are a few definitions that need to be added to the trace
headers and a couple of types that need to be made common to avoid
needing to include the whole world in the kmem code.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/kmem.c
fs/xfs/libxfs/xfs_types.h
fs/xfs/xfs_mount.h
fs/xfs/xfs_trace.h

index 7cd315ad937e0435d44f3d928682a58c3d199ab9..9f32af534ce4f05c57d05a9d7d3a599aababa7f4 100644 (file)
@@ -3,10 +3,10 @@
  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
-#include <linux/sched/mm.h>
+#include "xfs.h"
 #include <linux/backing-dev.h>
-#include "kmem.h"
 #include "xfs_message.h"
+#include "xfs_trace.h"
 
 void *
 kmem_alloc(size_t size, xfs_km_flags_t flags)
@@ -15,6 +15,8 @@ kmem_alloc(size_t size, xfs_km_flags_t flags)
        gfp_t   lflags = kmem_flags_convert(flags);
        void    *ptr;
 
+       trace_kmem_alloc(size, flags, _RET_IP_);
+
        do {
                ptr = kmalloc(size, lflags);
                if (ptr || (flags & KM_MAYFAIL))
@@ -35,6 +37,8 @@ kmem_alloc_large(size_t size, xfs_km_flags_t flags)
        void    *ptr;
        gfp_t   lflags;
 
+       trace_kmem_alloc_large(size, flags, _RET_IP_);
+
        ptr = kmem_alloc(size, flags | KM_MAYFAIL);
        if (ptr)
                return ptr;
@@ -65,6 +69,8 @@ kmem_realloc(const void *old, size_t newsize, xfs_km_flags_t flags)
        gfp_t   lflags = kmem_flags_convert(flags);
        void    *ptr;
 
+       trace_kmem_realloc(newsize, flags, _RET_IP_);
+
        do {
                ptr = krealloc(old, newsize, lflags);
                if (ptr || (flags & KM_MAYFAIL))
@@ -85,6 +91,7 @@ kmem_zone_alloc(kmem_zone_t *zone, xfs_km_flags_t flags)
        gfp_t   lflags = kmem_flags_convert(flags);
        void    *ptr;
 
+       trace_kmem_zone_alloc(kmem_cache_size(zone), flags, _RET_IP_);
        do {
                ptr = kmem_cache_alloc(zone, lflags);
                if (ptr || (flags & KM_MAYFAIL))
index 802b34cd10fe08fa8612274f46c7ab1007894762..300b3e91ca3ade672d1443badefd89b937b2400d 100644 (file)
@@ -169,6 +169,14 @@ typedef struct xfs_bmbt_irec
        xfs_exntst_t    br_state;       /* extent state */
 } xfs_bmbt_irec_t;
 
+/* per-AG block reservation types */
+enum xfs_ag_resv_type {
+       XFS_AG_RESV_NONE = 0,
+       XFS_AG_RESV_AGFL,
+       XFS_AG_RESV_METADATA,
+       XFS_AG_RESV_RMAPBT,
+};
+
 /*
  * Type verifier functions
  */
index 4adb6837439ac38fa600f0bd1f373634cef5bb78..fdb60e09a9c543eb65d4c233ea3f2b9243fa41d6 100644 (file)
@@ -327,13 +327,6 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
 }
 
 /* per-AG block reservation data structures*/
-enum xfs_ag_resv_type {
-       XFS_AG_RESV_NONE = 0,
-       XFS_AG_RESV_AGFL,
-       XFS_AG_RESV_METADATA,
-       XFS_AG_RESV_RMAPBT,
-};
-
 struct xfs_ag_resv {
        /* number of blocks originally reserved here */
        xfs_extlen_t                    ar_orig_reserved;
index 8094b1920eeff6413648c2af6251c4de1dcb4a0b..8bb8b4704a00de6ac0bff80587f3eaa36d3fa51c 100644 (file)
@@ -23,6 +23,7 @@ struct xlog;
 struct xlog_ticket;
 struct xlog_recover;
 struct xlog_recover_item;
+struct xlog_rec_header;
 struct xfs_buf_log_format;
 struct xfs_inode_log_format;
 struct xfs_bmbt_irec;
@@ -30,6 +31,10 @@ struct xfs_btree_cur;
 struct xfs_refcount_irec;
 struct xfs_fsmap;
 struct xfs_rmap_irec;
+struct xfs_icreate_log;
+struct xfs_owner_info;
+struct xfs_trans_res;
+struct xfs_inobt_rec_incore;
 
 DECLARE_EVENT_CLASS(xfs_attr_list_class,
        TP_PROTO(struct xfs_attr_list_context *ctx),
@@ -3575,6 +3580,34 @@ TRACE_EVENT(xfs_pwork_init,
                  __entry->nr_threads, __entry->pid)
 )
 
+DECLARE_EVENT_CLASS(xfs_kmem_class,
+       TP_PROTO(ssize_t size, int flags, unsigned long caller_ip),
+       TP_ARGS(size, flags, caller_ip),
+       TP_STRUCT__entry(
+               __field(ssize_t, size)
+               __field(int, flags)
+               __field(unsigned long, caller_ip)
+       ),
+       TP_fast_assign(
+               __entry->size = size;
+               __entry->flags = flags;
+               __entry->caller_ip = caller_ip;
+       ),
+       TP_printk("size %zd flags 0x%x caller %pS",
+                 __entry->size,
+                 __entry->flags,
+                 (char *)__entry->caller_ip)
+)
+
+#define DEFINE_KMEM_EVENT(name) \
+DEFINE_EVENT(xfs_kmem_class, name, \
+       TP_PROTO(ssize_t size, int flags, unsigned long caller_ip), \
+       TP_ARGS(size, flags, caller_ip))
+DEFINE_KMEM_EVENT(kmem_alloc);
+DEFINE_KMEM_EVENT(kmem_alloc_large);
+DEFINE_KMEM_EVENT(kmem_realloc);
+DEFINE_KMEM_EVENT(kmem_zone_alloc);
+
 #endif /* _TRACE_XFS_H */
 
 #undef TRACE_INCLUDE_PATH