diff --git a/drivers/gpu/nvgpu/include/nvgpu/barrier.h b/drivers/gpu/nvgpu/include/nvgpu/barrier.h index bd0d820e6..8387a97dc 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/barrier.h +++ b/drivers/gpu/nvgpu/include/nvgpu/barrier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -44,8 +44,30 @@ #define nvgpu_smp_rmb() nvgpu_smp_rmb_impl() #define nvgpu_smp_wmb() nvgpu_smp_wmb_impl() -#define NV_READ_ONCE(x) NV_READ_ONCE_IMPL((x)) -#define NV_WRITE_ONCE(x, y) NV_WRITE_ONCE_IMPL((x), (y)) +/** + * @brief Compilers can do optimizations assuming there is a single thread + * executing the code. For example, a variable read in a loop from one thread + * may not see the update from another thread because compiler has assumed that + * it's value cannot change from the one initialized before the loop. There are + * other possibilities like multiple references to a variable when the code + * assumes that it should see a constant value. In general, this macro should + * never be used by nvgpu driver code, and many of the current uses in driver + * are likely wrong. + * For more info see: URL = lwn.net/Articles/508991/ + * + * @param x [in] variable that needs to turn into a volatile type temporarily. + */ +#define NV_READ_ONCE(x) (*((volatile typeof(x) *)&x)) + +/** + * @brief Ensure ordered writes. + * + * @param x Variable to be updated. + * @param y Value to be written. + * + * Prevent compiler optimizations from mangling writes. + */ +#define NV_WRITE_ONCE(x, y) (*((volatile typeof(x) *)(&(x))) = (y)) /* * Sometimes we want to prevent speculation. diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/barrier.h b/drivers/gpu/nvgpu/include/nvgpu/linux/barrier.h index 2864b241d..6c35a1d5c 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/linux/barrier.h +++ b/drivers/gpu/nvgpu/include/nvgpu/linux/barrier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -27,9 +27,6 @@ #define nvgpu_smp_rmb_impl() smp_rmb() #define nvgpu_smp_wmb_impl() smp_wmb() -#define NV_READ_ONCE_IMPL(x) READ_ONCE(x) -#define NV_WRITE_ONCE_IMPL(x, y) WRITE_ONCE(x, y) - #ifdef speculation_barrier #define nvgpu_speculation_barrier_impl() speculation_barrier() #else diff --git a/drivers/gpu/nvgpu/include/nvgpu/posix/barrier.h b/drivers/gpu/nvgpu/include/nvgpu/posix/barrier.h index 3f5c8c658..00743d229 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/posix/barrier.h +++ b/drivers/gpu/nvgpu/include/nvgpu/posix/barrier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -25,8 +25,6 @@ #include -#define READ_ONCE(x) (*(volatile __typeof__(x) *)&x) - /* * TODO: implement all these! */ @@ -38,7 +36,4 @@ #define nvgpu_smp_rmb_impl() #define nvgpu_smp_wmb_impl() -#define NV_READ_ONCE_IMPL(x) READ_ONCE(x) -#define NV_WRITE_ONCE_IMPL(x, y) WRITE_ONCE(x, y) - #endif /* NVGPU_POSIX_BARRIER_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/posix/utils.h b/drivers/gpu/nvgpu/include/nvgpu/posix/utils.h index c6a2dab52..6030d1718 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/posix/utils.h +++ b/drivers/gpu/nvgpu/include/nvgpu/posix/utils.h @@ -496,22 +496,6 @@ static inline unsigned int nvgpu_posix_hweight64(uint64_t x) /** Defined to match kernel macro names. */ #define likely(x) (x) -/* - * Prevent compiler optimizations from mangling writes. But likely most uses of - * this in nvgpu are incorrect (i.e unnecessary). - */ -/** - * @brief Ensure ordered writes. - * - * @param p Variable to be updated. - * @param v Value to be written. - */ -#define WRITE_ONCE(p, v) \ - ({ \ - volatile typeof(p) *__p__ = &(p); \ - *__p__ = (v); \ - }) - /** * @brief Get the container which holds the member. * diff --git a/userspace/units/posix/utils/posix-utils.c b/userspace/units/posix/utils/posix-utils.c index 39ef0205c..785e38c76 100644 --- a/userspace/units/posix/utils/posix-utils.c +++ b/userspace/units/posix/utils/posix-utils.c @@ -27,6 +27,7 @@ #include #include +#include #include "posix-utils.h" @@ -487,10 +488,10 @@ int test_write_once(struct unit_module *m, test1 = 20; for (i = 0 ; i < 10; i++) { test1 += 1; - WRITE_ONCE(result, test1); + NV_WRITE_ONCE(result, test1); if (result != test1) { unit_return_fail(m, - "WRITE_ONCE failure %d\n", result); + "NV_WRITE_ONCE failure %d\n", result); } }