From 2ade659eb4f836931f10b69477657a054d743894 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 14 May 2020 20:45:16 -0700 Subject: [PATCH] Fix abd_enter/exit_critical wrappers Commit fc551d7 introduced the wrappers abd_enter_critical() and abd_exit_critical() to mark critical sections. On Linux these are implemented with the local_irq_save() and local_irq_restore() macros which set the 'flags' argument when saving. By wrapping them with a function the local variable is no longer set by the macro and is no longer properly restored. Convert abd_enter_critical() and abd_exit_critical() to macros to resolve this issue and ensure the flags are properly restored. Reviewed-by: Matthew Ahrens Reviewed-by: Brian Atkinson Signed-off-by: Brian Behlendorf Closes #10332 --- include/sys/abd_impl.h | 15 +++++++++++++-- module/os/freebsd/zfs/abd_os.c | 12 ------------ module/os/linux/zfs/abd_os.c | 12 ------------ module/zfs/abd.c | 4 ++-- 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/include/sys/abd_impl.h b/include/sys/abd_impl.h index 6027678af1..5aee772b1e 100644 --- a/include/sys/abd_impl.h +++ b/include/sys/abd_impl.h @@ -98,8 +98,6 @@ void abd_update_scatter_stats(abd_t *, abd_stats_op_t); void abd_update_linear_stats(abd_t *, abd_stats_op_t); void abd_verify_scatter(abd_t *); void abd_free_linear_page(abd_t *); -void abd_enter_critical(unsigned long); -void abd_exit_critical(unsigned long); /* OS specific abd_iter functions */ void abd_iter_init(struct abd_iter *, abd_t *); boolean_t abd_iter_at_end(struct abd_iter *); @@ -119,6 +117,19 @@ void abd_iter_unmap(struct abd_iter *); #define ABD_SCATTER(abd) (abd->abd_u.abd_scatter) #define ABD_LINEAR_BUF(abd) (abd->abd_u.abd_linear.abd_buf) +#if defined(_KERNEL) +#if defined(__FreeBSD__) +#define abd_enter_critical(flags) critical_enter() +#define abd_exit_critical(flags) critical_exit() +#else +#define abd_enter_critical(flags) local_irq_save(flags) +#define abd_exit_critical(flags) local_irq_restore(flags) +#endif +#else /* !_KERNEL */ +#define abd_enter_critical(flags) ((void)0) +#define abd_exit_critical(flags) ((void)0) +#endif + #ifdef __cplusplus } #endif diff --git a/module/os/freebsd/zfs/abd_os.c b/module/os/freebsd/zfs/abd_os.c index f438841cd4..6b967bc070 100644 --- a/module/os/freebsd/zfs/abd_os.c +++ b/module/os/freebsd/zfs/abd_os.c @@ -419,15 +419,3 @@ abd_iter_unmap(struct abd_iter *aiter) aiter->iter_mapaddr = NULL; aiter->iter_mapsize = 0; } - -void -abd_enter_critical(unsigned long flags) -{ - critical_enter(); -} - -void -abd_exit_critical(unsigned long flags) -{ - critical_exit(); -} diff --git a/module/os/linux/zfs/abd_os.c b/module/os/linux/zfs/abd_os.c index 57e415ef31..a8e8f404dd 100644 --- a/module/os/linux/zfs/abd_os.c +++ b/module/os/linux/zfs/abd_os.c @@ -803,18 +803,6 @@ abd_iter_unmap(struct abd_iter *aiter) aiter->iter_mapsize = 0; } -void -abd_enter_critical(unsigned long flags) -{ - local_irq_save(flags); -} - -void -abd_exit_critical(unsigned long flags) -{ - local_irq_restore(flags); -} - #if defined(_KERNEL) /* * bio_nr_pages for ABD. diff --git a/module/zfs/abd.c b/module/zfs/abd.c index 2e4554da7a..abb5d5f2ed 100644 --- a/module/zfs/abd.c +++ b/module/zfs/abd.c @@ -703,7 +703,7 @@ abd_raidz_gen_iterate(abd_t **cabds, abd_t *dabd, struct abd_iter caiters[3]; struct abd_iter daiter = {0}; void *caddrs[3]; - unsigned long flags = 0; + unsigned long flags __maybe_unused = 0; ASSERT3U(parity, <=, 3); @@ -800,7 +800,7 @@ abd_raidz_rec_iterate(abd_t **cabds, abd_t **tabds, struct abd_iter citers[3]; struct abd_iter xiters[3]; void *caddrs[3], *xaddrs[3]; - unsigned long flags = 0; + unsigned long flags __maybe_unused = 0; ASSERT3U(parity, <=, 3);