From d7b5b25620f76754a7c02075d04a24d12b6bec83 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 1 Jun 2018 19:07:28 +0200 Subject: [PATCH] 4.14-stable patches added patches: pci-hv-fix-2-hang-issues-in-hv_compose_msi_msg.patch xfs-convert-xfs_agfl_size-to-a-helper-function.patch xfs-detect-agfl-count-corruption-and-reset-agfl.patch --- ...-2-hang-issues-in-hv_compose_msi_msg.patch | 142 +++++++++++ queue-4.14/series | 3 + ...t-xfs_agfl_size-to-a-helper-function.patch | 150 ++++++++++++ ...agfl-count-corruption-and-reset-agfl.patch | 230 ++++++++++++++++++ 4 files changed, 525 insertions(+) create mode 100644 queue-4.14/pci-hv-fix-2-hang-issues-in-hv_compose_msi_msg.patch create mode 100644 queue-4.14/xfs-convert-xfs_agfl_size-to-a-helper-function.patch create mode 100644 queue-4.14/xfs-detect-agfl-count-corruption-and-reset-agfl.patch diff --git a/queue-4.14/pci-hv-fix-2-hang-issues-in-hv_compose_msi_msg.patch b/queue-4.14/pci-hv-fix-2-hang-issues-in-hv_compose_msi_msg.patch new file mode 100644 index 00000000000..8520ce392ed --- /dev/null +++ b/queue-4.14/pci-hv-fix-2-hang-issues-in-hv_compose_msi_msg.patch @@ -0,0 +1,142 @@ +From de0aa7b2f97d348ba7d1e17a00744c989baa0cb6 Mon Sep 17 00:00:00 2001 +From: Dexuan Cui +Date: Thu, 15 Mar 2018 14:21:08 +0000 +Subject: PCI: hv: Fix 2 hang issues in hv_compose_msi_msg() + +From: Dexuan Cui + +commit de0aa7b2f97d348ba7d1e17a00744c989baa0cb6 upstream. + +1. With the patch "x86/vector/msi: Switch to global reservation mode", +the recent v4.15 and newer kernels always hang for 1-vCPU Hyper-V VM +with SR-IOV. This is because when we reach hv_compose_msi_msg() by +request_irq() -> request_threaded_irq() ->__setup_irq()->irq_startup() +-> __irq_startup() -> irq_domain_activate_irq() -> ... -> +msi_domain_activate() -> ... -> hv_compose_msi_msg(), local irq is +disabled in __setup_irq(). + +Note: when we reach hv_compose_msi_msg() by another code path: +pci_enable_msix_range() -> ... -> irq_domain_activate_irq() -> ... -> +hv_compose_msi_msg(), local irq is not disabled. + +hv_compose_msi_msg() depends on an interrupt from the host. +With interrupts disabled, a UP VM always hangs in the busy loop in +the function, because the interrupt callback hv_pci_onchannelcallback() +can not be called. + +We can do nothing but work it around by polling the channel. This +is ugly, but we don't have any other choice. + +2. If the host is ejecting the VF device before we reach +hv_compose_msi_msg(), in a UP VM, we can hang in hv_compose_msi_msg() +forever, because at this time the host doesn't respond to the +CREATE_INTERRUPT request. This issue exists the first day the +pci-hyperv driver appears in the kernel. + +Luckily, this can also by worked around by polling the channel +for the PCI_EJECT message and hpdev->state, and by checking the +PCI vendor ID. + +Note: actually the above 2 issues also happen to a SMP VM, if +"hbus->hdev->channel->target_cpu == smp_processor_id()" is true. + +Fixes: 4900be83602b ("x86/vector/msi: Switch to global reservation mode") +Tested-by: Adrian Suhov +Tested-by: Chris Valean +Signed-off-by: Dexuan Cui +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Michael Kelley +Acked-by: Haiyang Zhang +Cc: +Cc: Stephen Hemminger +Cc: K. Y. Srinivasan +Cc: Vitaly Kuznetsov +Cc: Jack Morgenstein +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/host/pci-hyperv.c | 58 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 57 insertions(+), 1 deletion(-) + +--- a/drivers/pci/host/pci-hyperv.c ++++ b/drivers/pci/host/pci-hyperv.c +@@ -531,6 +531,8 @@ struct hv_pci_compl { + s32 completion_status; + }; + ++static void hv_pci_onchannelcallback(void *context); ++ + /** + * hv_pci_generic_compl() - Invoked for a completion packet + * @context: Set up by the sender of the packet. +@@ -675,6 +677,31 @@ static void _hv_pcifront_read_config(str + } + } + ++static u16 hv_pcifront_get_vendor_id(struct hv_pci_dev *hpdev) ++{ ++ u16 ret; ++ unsigned long flags; ++ void __iomem *addr = hpdev->hbus->cfg_addr + CFG_PAGE_OFFSET + ++ PCI_VENDOR_ID; ++ ++ spin_lock_irqsave(&hpdev->hbus->config_lock, flags); ++ ++ /* Choose the function to be read. (See comment above) */ ++ writel(hpdev->desc.win_slot.slot, hpdev->hbus->cfg_addr); ++ /* Make sure the function was chosen before we start reading. */ ++ mb(); ++ /* Read from that function's config space. */ ++ ret = readw(addr); ++ /* ++ * mb() is not required here, because the spin_unlock_irqrestore() ++ * is a barrier. ++ */ ++ ++ spin_unlock_irqrestore(&hpdev->hbus->config_lock, flags); ++ ++ return ret; ++} ++ + /** + * _hv_pcifront_write_config() - Internal PCI config write + * @hpdev: The PCI driver's representation of the device +@@ -1121,8 +1148,37 @@ static void hv_compose_msi_msg(struct ir + * Since this function is called with IRQ locks held, can't + * do normal wait for completion; instead poll. + */ +- while (!try_wait_for_completion(&comp.comp_pkt.host_event)) ++ while (!try_wait_for_completion(&comp.comp_pkt.host_event)) { ++ /* 0xFFFF means an invalid PCI VENDOR ID. */ ++ if (hv_pcifront_get_vendor_id(hpdev) == 0xFFFF) { ++ dev_err_once(&hbus->hdev->device, ++ "the device has gone\n"); ++ goto free_int_desc; ++ } ++ ++ /* ++ * When the higher level interrupt code calls us with ++ * interrupt disabled, we must poll the channel by calling ++ * the channel callback directly when channel->target_cpu is ++ * the current CPU. When the higher level interrupt code ++ * calls us with interrupt enabled, let's add the ++ * local_bh_disable()/enable() to avoid race. ++ */ ++ local_bh_disable(); ++ ++ if (hbus->hdev->channel->target_cpu == smp_processor_id()) ++ hv_pci_onchannelcallback(hbus); ++ ++ local_bh_enable(); ++ ++ if (hpdev->state == hv_pcichild_ejecting) { ++ dev_err_once(&hbus->hdev->device, ++ "the device is being ejected\n"); ++ goto free_int_desc; ++ } ++ + udelay(100); ++ } + + if (comp.comp_pkt.completion_status < 0) { + dev_err(&hbus->hdev->device, diff --git a/queue-4.14/series b/queue-4.14/series index ea2296a4a2c..5230e3bcb9f 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -6,3 +6,6 @@ objtool-fix-noreturn-detection-for-recursive-sibling-calls.patch x86-mce-amd-carve-out-smca-get_block_address-code.patch x86-mce-amd-cache-smca-misc-block-addresses.patch revert-pinctrl-msm-use-dynamic-gpio-numbering.patch +pci-hv-fix-2-hang-issues-in-hv_compose_msi_msg.patch +xfs-convert-xfs_agfl_size-to-a-helper-function.patch +xfs-detect-agfl-count-corruption-and-reset-agfl.patch diff --git a/queue-4.14/xfs-convert-xfs_agfl_size-to-a-helper-function.patch b/queue-4.14/xfs-convert-xfs_agfl_size-to-a-helper-function.patch new file mode 100644 index 00000000000..491cc0a85cb --- /dev/null +++ b/queue-4.14/xfs-convert-xfs_agfl_size-to-a-helper-function.patch @@ -0,0 +1,150 @@ +From a78ee256c325ecfaec13cafc41b315bd4e1dd518 Mon Sep 17 00:00:00 2001 +From: Dave Chinner +Date: Tue, 6 Mar 2018 17:08:32 -0800 +Subject: xfs: convert XFS_AGFL_SIZE to a helper function + +From: Dave Chinner + +commit a78ee256c325ecfaec13cafc41b315bd4e1dd518 upstream. + +The AGFL size calculation is about to get more complex, so lets turn +the macro into a function first and remove the macro. + +Signed-off-by: Dave Chinner +[darrick: forward port to newer kernel, simplify the helper] +Signed-off-by: Darrick J. Wong +Reviewed-by: Brian Foster +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/libxfs/xfs_alloc.c | 31 ++++++++++++++++++++++++------- + fs/xfs/libxfs/xfs_alloc.h | 2 ++ + fs/xfs/libxfs/xfs_format.h | 13 +------------ + fs/xfs/xfs_fsops.c | 2 +- + 4 files changed, 28 insertions(+), 20 deletions(-) + +--- a/fs/xfs/libxfs/xfs_alloc.c ++++ b/fs/xfs/libxfs/xfs_alloc.c +@@ -52,6 +52,23 @@ STATIC int xfs_alloc_ag_vextent_size(xfs + STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, + xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); + ++/* ++ * Size of the AGFL. For CRC-enabled filesystes we steal a couple of slots in ++ * the beginning of the block for a proper header with the location information ++ * and CRC. ++ */ ++unsigned int ++xfs_agfl_size( ++ struct xfs_mount *mp) ++{ ++ unsigned int size = mp->m_sb.sb_sectsize; ++ ++ if (xfs_sb_version_hascrc(&mp->m_sb)) ++ size -= sizeof(struct xfs_agfl); ++ ++ return size / sizeof(xfs_agblock_t); ++} ++ + unsigned int + xfs_refc_block( + struct xfs_mount *mp) +@@ -540,7 +557,7 @@ xfs_agfl_verify( + if (bp->b_pag && be32_to_cpu(agfl->agfl_seqno) != bp->b_pag->pag_agno) + return false; + +- for (i = 0; i < XFS_AGFL_SIZE(mp); i++) { ++ for (i = 0; i < xfs_agfl_size(mp); i++) { + if (be32_to_cpu(agfl->agfl_bno[i]) != NULLAGBLOCK && + be32_to_cpu(agfl->agfl_bno[i]) >= mp->m_sb.sb_agblocks) + return false; +@@ -2252,7 +2269,7 @@ xfs_alloc_get_freelist( + bno = be32_to_cpu(agfl_bno[be32_to_cpu(agf->agf_flfirst)]); + be32_add_cpu(&agf->agf_flfirst, 1); + xfs_trans_brelse(tp, agflbp); +- if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) ++ if (be32_to_cpu(agf->agf_flfirst) == xfs_agfl_size(mp)) + agf->agf_flfirst = 0; + + pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); +@@ -2363,7 +2380,7 @@ xfs_alloc_put_freelist( + be32_to_cpu(agf->agf_seqno), &agflbp))) + return error; + be32_add_cpu(&agf->agf_fllast, 1); +- if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp)) ++ if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp)) + agf->agf_fllast = 0; + + pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); +@@ -2381,7 +2398,7 @@ xfs_alloc_put_freelist( + + xfs_alloc_log_agf(tp, agbp, logflags); + +- ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); ++ ASSERT(be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp)); + + agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp); + blockp = &agfl_bno[be32_to_cpu(agf->agf_fllast)]; +@@ -2414,9 +2431,9 @@ xfs_agf_verify( + if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) && + XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && + be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && +- be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && +- be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) && +- be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp))) ++ be32_to_cpu(agf->agf_flfirst) < xfs_agfl_size(mp) && ++ be32_to_cpu(agf->agf_fllast) < xfs_agfl_size(mp) && ++ be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp))) + return false; + + if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 || +--- a/fs/xfs/libxfs/xfs_alloc.h ++++ b/fs/xfs/libxfs/xfs_alloc.h +@@ -26,6 +26,8 @@ struct xfs_trans; + + extern struct workqueue_struct *xfs_alloc_wq; + ++unsigned int xfs_agfl_size(struct xfs_mount *mp); ++ + /* + * Freespace allocation types. Argument to xfs_alloc_[v]extent. + */ +--- a/fs/xfs/libxfs/xfs_format.h ++++ b/fs/xfs/libxfs/xfs_format.h +@@ -798,24 +798,13 @@ typedef struct xfs_agi { + &(XFS_BUF_TO_AGFL(bp)->agfl_bno[0]) : \ + (__be32 *)(bp)->b_addr) + +-/* +- * Size of the AGFL. For CRC-enabled filesystes we steal a couple of +- * slots in the beginning of the block for a proper header with the +- * location information and CRC. +- */ +-#define XFS_AGFL_SIZE(mp) \ +- (((mp)->m_sb.sb_sectsize - \ +- (xfs_sb_version_hascrc(&((mp)->m_sb)) ? \ +- sizeof(struct xfs_agfl) : 0)) / \ +- sizeof(xfs_agblock_t)) +- + typedef struct xfs_agfl { + __be32 agfl_magicnum; + __be32 agfl_seqno; + uuid_t agfl_uuid; + __be64 agfl_lsn; + __be32 agfl_crc; +- __be32 agfl_bno[]; /* actually XFS_AGFL_SIZE(mp) */ ++ __be32 agfl_bno[]; /* actually xfs_agfl_size(mp) */ + } __attribute__((packed)) xfs_agfl_t; + + #define XFS_AGFL_CRC_OFF offsetof(struct xfs_agfl, agfl_crc) +--- a/fs/xfs/xfs_fsops.c ++++ b/fs/xfs/xfs_fsops.c +@@ -294,7 +294,7 @@ xfs_growfs_data_private( + } + + agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, bp); +- for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++) ++ for (bucket = 0; bucket < xfs_agfl_size(mp); bucket++) + agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK); + + error = xfs_bwrite(bp); diff --git a/queue-4.14/xfs-detect-agfl-count-corruption-and-reset-agfl.patch b/queue-4.14/xfs-detect-agfl-count-corruption-and-reset-agfl.patch new file mode 100644 index 00000000000..a772de6c2d9 --- /dev/null +++ b/queue-4.14/xfs-detect-agfl-count-corruption-and-reset-agfl.patch @@ -0,0 +1,230 @@ +From a27ba2607e60312554cbcd43fc660b2c7f29dc9c Mon Sep 17 00:00:00 2001 +From: Brian Foster +Date: Thu, 15 Mar 2018 10:51:58 -0700 +Subject: xfs: detect agfl count corruption and reset agfl + +From: Brian Foster + +commit a27ba2607e60312554cbcd43fc660b2c7f29dc9c upstream. + +The struct xfs_agfl v5 header was originally introduced with +unexpected padding that caused the AGFL to operate with one less +slot than intended. The header has since been packed, but the fix +left an incompatibility for users who upgrade from an old kernel +with the unpacked header to a newer kernel with the packed header +while the AGFL happens to wrap around the end. The newer kernel +recognizes one extra slot at the physical end of the AGFL that the +previous kernel did not. The new kernel will eventually attempt to +allocate a block from that slot, which contains invalid data, and +cause a crash. + +This condition can be detected by comparing the active range of the +AGFL to the count. While this detects a padding mismatch, it can +also trigger false positives for unrelated flcount corruption. Since +we cannot distinguish a size mismatch due to padding from unrelated +corruption, we can't trust the AGFL enough to simply repopulate the +empty slot. + +Instead, avoid unnecessarily complex detection logic and and use a +solution that can handle any form of flcount corruption that slips +through read verifiers: distrust the entire AGFL and reset it to an +empty state. Any valid blocks within the AGFL are intentionally +leaked. This requires xfs_repair to rectify (which was already +necessary based on the state the AGFL was found in). The reset +mitigates the side effect of the padding mismatch problem from a +filesystem crash to a free space accounting inconsistency. The +generic approach also means that this patch can be safely backported +to kernels with or without a packed struct xfs_agfl. + +Check the AGF for an invalid freelist count on initial read from +disk. If detected, set a flag on the xfs_perag to indicate that a +reset is required before the AGFL can be used. In the first +transaction that attempts to use a flagged AGFL, reset it to empty, +warn the user about the inconsistency and allow the freelist fixup +code to repopulate the AGFL with new blocks. The xfs_perag flag is +cleared to eliminate the need for repeated checks on each block +allocation operation. + +This allows kernels that include the packing fix commit 96f859d52bcb +("libxfs: pack the agfl header structure so XFS_AGFL_SIZE is correct") +to handle older unpacked AGFL formats without a filesystem crash. + +Suggested-by: Dave Chinner +Signed-off-by: Brian Foster +Reviewed-by: Darrick J. Wong +Reviewed-by Dave Chiluk +Signed-off-by: Darrick J. Wong +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/libxfs/xfs_alloc.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++ + fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_trace.h | 9 +++- + 3 files changed, 103 insertions(+), 1 deletion(-) + +--- a/fs/xfs/libxfs/xfs_alloc.c ++++ b/fs/xfs/libxfs/xfs_alloc.c +@@ -2057,6 +2057,93 @@ xfs_alloc_space_available( + } + + /* ++ * Check the agfl fields of the agf for inconsistency or corruption. The purpose ++ * is to detect an agfl header padding mismatch between current and early v5 ++ * kernels. This problem manifests as a 1-slot size difference between the ++ * on-disk flcount and the active [first, last] range of a wrapped agfl. This ++ * may also catch variants of agfl count corruption unrelated to padding. Either ++ * way, we'll reset the agfl and warn the user. ++ * ++ * Return true if a reset is required before the agfl can be used, false ++ * otherwise. ++ */ ++static bool ++xfs_agfl_needs_reset( ++ struct xfs_mount *mp, ++ struct xfs_agf *agf) ++{ ++ uint32_t f = be32_to_cpu(agf->agf_flfirst); ++ uint32_t l = be32_to_cpu(agf->agf_fllast); ++ uint32_t c = be32_to_cpu(agf->agf_flcount); ++ int agfl_size = xfs_agfl_size(mp); ++ int active; ++ ++ /* no agfl header on v4 supers */ ++ if (!xfs_sb_version_hascrc(&mp->m_sb)) ++ return false; ++ ++ /* ++ * The agf read verifier catches severe corruption of these fields. ++ * Repeat some sanity checks to cover a packed -> unpacked mismatch if ++ * the verifier allows it. ++ */ ++ if (f >= agfl_size || l >= agfl_size) ++ return true; ++ if (c > agfl_size) ++ return true; ++ ++ /* ++ * Check consistency between the on-disk count and the active range. An ++ * agfl padding mismatch manifests as an inconsistent flcount. ++ */ ++ if (c && l >= f) ++ active = l - f + 1; ++ else if (c) ++ active = agfl_size - f + l + 1; ++ else ++ active = 0; ++ ++ return active != c; ++} ++ ++/* ++ * Reset the agfl to an empty state. Ignore/drop any existing blocks since the ++ * agfl content cannot be trusted. Warn the user that a repair is required to ++ * recover leaked blocks. ++ * ++ * The purpose of this mechanism is to handle filesystems affected by the agfl ++ * header padding mismatch problem. A reset keeps the filesystem online with a ++ * relatively minor free space accounting inconsistency rather than suffer the ++ * inevitable crash from use of an invalid agfl block. ++ */ ++static void ++xfs_agfl_reset( ++ struct xfs_trans *tp, ++ struct xfs_buf *agbp, ++ struct xfs_perag *pag) ++{ ++ struct xfs_mount *mp = tp->t_mountp; ++ struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); ++ ++ ASSERT(pag->pagf_agflreset); ++ trace_xfs_agfl_reset(mp, agf, 0, _RET_IP_); ++ ++ xfs_warn(mp, ++ "WARNING: Reset corrupted AGFL on AG %u. %d blocks leaked. " ++ "Please unmount and run xfs_repair.", ++ pag->pag_agno, pag->pagf_flcount); ++ ++ agf->agf_flfirst = 0; ++ agf->agf_fllast = cpu_to_be32(xfs_agfl_size(mp) - 1); ++ agf->agf_flcount = 0; ++ xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLLAST | ++ XFS_AGF_FLCOUNT); ++ ++ pag->pagf_flcount = 0; ++ pag->pagf_agflreset = false; ++} ++ ++/* + * Decide whether to use this allocation group for this allocation. + * If so, fix up the btree freelist's size. + */ +@@ -2117,6 +2204,10 @@ xfs_alloc_fix_freelist( + } + } + ++ /* reset a padding mismatched agfl before final free space check */ ++ if (pag->pagf_agflreset) ++ xfs_agfl_reset(tp, agbp, pag); ++ + /* If there isn't enough total space or single-extent, reject it. */ + need = xfs_alloc_min_freelist(mp, pag); + if (!xfs_alloc_space_available(args, need, flags)) +@@ -2273,6 +2364,7 @@ xfs_alloc_get_freelist( + agf->agf_flfirst = 0; + + pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); ++ ASSERT(!pag->pagf_agflreset); + be32_add_cpu(&agf->agf_flcount, -1); + xfs_trans_agflist_delta(tp, -1); + pag->pagf_flcount--; +@@ -2384,6 +2476,7 @@ xfs_alloc_put_freelist( + agf->agf_fllast = 0; + + pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno)); ++ ASSERT(!pag->pagf_agflreset); + be32_add_cpu(&agf->agf_flcount, 1); + xfs_trans_agflist_delta(tp, 1); + pag->pagf_flcount++; +@@ -2589,6 +2682,7 @@ xfs_alloc_read_agf( + pag->pagb_count = 0; + pag->pagb_tree = RB_ROOT; + pag->pagf_init = 1; ++ pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf); + } + #ifdef DEBUG + else if (!XFS_FORCED_SHUTDOWN(mp)) { +--- a/fs/xfs/xfs_mount.h ++++ b/fs/xfs/xfs_mount.h +@@ -353,6 +353,7 @@ typedef struct xfs_perag { + char pagi_inodeok; /* The agi is ok for inodes */ + uint8_t pagf_levels[XFS_BTNUM_AGF]; + /* # of levels in bno & cnt btree */ ++ bool pagf_agflreset; /* agfl requires reset before use */ + uint32_t pagf_flcount; /* count of blocks in freelist */ + xfs_extlen_t pagf_freeblks; /* total free blocks */ + xfs_extlen_t pagf_longest; /* longest free space */ +--- a/fs/xfs/xfs_trace.h ++++ b/fs/xfs/xfs_trace.h +@@ -1513,7 +1513,7 @@ TRACE_EVENT(xfs_extent_busy_trim, + __entry->tlen) + ); + +-TRACE_EVENT(xfs_agf, ++DECLARE_EVENT_CLASS(xfs_agf_class, + TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags, + unsigned long caller_ip), + TP_ARGS(mp, agf, flags, caller_ip), +@@ -1569,6 +1569,13 @@ TRACE_EVENT(xfs_agf, + __entry->longest, + (void *)__entry->caller_ip) + ); ++#define DEFINE_AGF_EVENT(name) \ ++DEFINE_EVENT(xfs_agf_class, name, \ ++ TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags, \ ++ unsigned long caller_ip), \ ++ TP_ARGS(mp, agf, flags, caller_ip)) ++DEFINE_AGF_EVENT(xfs_agf); ++DEFINE_AGF_EVENT(xfs_agfl_reset); + + TRACE_EVENT(xfs_free_extent, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno, -- 2.47.3