diff --git a/drivers/gpu/nvgpu/include/nvgpu/posix/bitops.h b/drivers/gpu/nvgpu/include/nvgpu/posix/bitops.h index 1f7a61c7e..79cc21eed 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/posix/bitops.h +++ b/drivers/gpu/nvgpu/include/nvgpu/posix/bitops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, 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"), @@ -97,13 +97,13 @@ * @brief Loop for each set bit. * * @param bit [in] Each set bit, this is the loop index. - * @param addr [in] Starting of the bitmap. + * @param address [in] Starting of the bitmap. * @param size [in] Size of the bitmap. */ -#define for_each_set_bit(bit, addr, size) \ - for ((bit) = find_first_bit((addr), (size)); \ +#define for_each_set_bit(bit, address, size) \ + for ((bit) = find_first_bit((address), (size)); \ (bit) < (size); \ - (bit) = find_next_bit((addr), (size), (bit) + 1U)) + (bit) = find_next_bit((address), (size), (bit) + 1U)) /** * @brief Find first set bit. @@ -153,77 +153,79 @@ unsigned long nvgpu_posix_fls(unsigned long word); /** * @brief Find the first set bit. * - * @param addr [in] Input value to search for set bit. + * @param address [in] Input value to search for set bit. * @param size [in] Size of the input value in bits. * - * Finds the first set bit position in the input data \a addr. + * Finds the first set bit position in the input data \a address. * * @return Returns the position of first set bit. */ -unsigned long find_first_bit(const unsigned long *addr, unsigned long size); +unsigned long find_first_bit(const unsigned long *address, unsigned long size); /** * @brief Finds the next set bit. * - * @param addr [in] Input value to search for next set bit. + * @param address [in] Input value to search for next set bit. * @param size [in] Size of the input value in bits. * @param offset [in] Offset to start from the input data. * - * Finds the next set bit position in the input data \a addr. + * Finds the next set bit position in the input data \a address. * * @return Returns the position of next set bit. */ -unsigned long find_next_bit(const unsigned long *addr, unsigned long size, +unsigned long find_next_bit(const unsigned long *address, unsigned long size, unsigned long offset); /** * @brief Finds the first zero bit. * - * @param addr [in] Input value to search. + * @param address [in] Input value to search. * @param size [in] Size of the input value in bits. * - * Finds the first zero bit position in the input data \a addr. + * Finds the first zero bit position in the input data \a address. * * @return Returns the position of first zero bit. */ -unsigned long find_first_zero_bit(const unsigned long *addr, +unsigned long find_first_zero_bit(const unsigned long *address, unsigned long size); /** * @brief Test the bit value at given position. * - * @param nr [in] Bit position to check. - * @param addr [in] Input data stream. + * @param bit [in] Bit position to check. + * @param address [in] Input data stream. * - * Checks if the bit at position mentioned by \a nr in \a addr is set or not. + * Checks if the bit at position mentioned by \a bit in \a address is set + * or not. * - * @return Returns true if bit position \a nr is set, else returns false. + * @return Returns true if bit position \a bit is set, else returns false. */ -bool nvgpu_test_bit(unsigned int nr, const volatile unsigned long *addr); +bool nvgpu_test_bit(unsigned int bit, const volatile unsigned long *address); /** * @brief Test and set the bit at given position. * - * @param nr [in] Bit position to test and set. - * @param addr [in] Input data stream. + * @param bit [in] Bit position to test and set. + * @param address [in] Input data stream. * - * Tests and sets the bit at position \a nr in \a addr. + * Tests and sets the bit at position \a bit in \a address. * * @return Returns true if the bit position was already set, else returns false. */ -bool nvgpu_test_and_set_bit(unsigned int nr, volatile unsigned long *addr); +bool nvgpu_test_and_set_bit(unsigned int bit, volatile unsigned long *address); /** * @brief Test and clear the bit at given position. * - * @param nr [in] Bit position to test and clear. - * @param addr [in] Input data stream. + * @param bit [in] Bit position to test and clear. + * @param address [in] Input data stream. * - * Tests and clears the bit at position \a nr in \a addr. + * Tests and clears the bit at position \a bit in \a address. * * @return Returns true if the bit position was already set, else returns false. */ -bool nvgpu_test_and_clear_bit(unsigned int nr, volatile unsigned long *addr); +bool nvgpu_test_and_clear_bit(unsigned int bit, + volatile unsigned long *address); /* * These two are atomic. @@ -232,22 +234,22 @@ bool nvgpu_test_and_clear_bit(unsigned int nr, volatile unsigned long *addr); /** * @brief Sets the bit at given position. * - * @param nr [in] Bit position to set. - * @param addr [in] Input data stream. + * @param bit [in] Bit position to set. + * @param address [in] Input data stream. * - * Sets the bit atomically at bit position \a nr in \a addr. + * Sets the bit atomically at bit position \a bit in \a address. */ -void nvgpu_set_bit(unsigned int nr, volatile unsigned long *addr); +void nvgpu_set_bit(unsigned int bit, volatile unsigned long *address); /** * @brief Clears the bit at given position. * - * @param nr [in] Bit position to clear. - * @param addr [in] Input data stream. + * @param bit [in] Bit position to clear. + * @param address [in] Input data stream. * - * Clears the bit atomically at bit position \a nr in \a addr. + * Clears the bit atomically at bit position \a bit in \a address. */ -void nvgpu_clear_bit(unsigned int nr, volatile unsigned long *addr); +void nvgpu_clear_bit(unsigned int bit, volatile unsigned long *address); /** * @brief Sets a bitmap. @@ -274,37 +276,13 @@ void nvgpu_bitmap_set(unsigned long *map, unsigned int start, unsigned int len); void nvgpu_bitmap_clear(unsigned long *map, unsigned int start, unsigned int len); -/** - * @brief Find first bitmap space from an offset. - * - * @param map [in] Input data stream. - * @param size [in] Size of the input data. - * @param start [in] Start position in input. - * @param nr [in] Number of bits in bitmap. - * @param align_mask [in] Align mask for start. - * @param align_offset [in] Align offset from Input data. - * - * Finds the first space of contiguous zeros in input data stream which can - * accommodate a bitmap of length \a nr starting from position \a start. - * - * @return Returns the position at which the bitmap starts if enough free space - * is present in the input stream to accommodate the bitmap; otherwise, return - * the size of the input data. - */ -unsigned long bitmap_find_next_zero_area_off(unsigned long *map, - unsigned long size, - unsigned long start, - unsigned int nr, - unsigned long align_mask, - unsigned long align_offset); - /** * @brief Find first bitmap space. * * @param map [in] Input data stream. * @param size [in] Size of the input data. * @param start [in] Start position in input. - * @param nr [in] Number of bits in bitmap. + * @param bit [in] Number of bits in bitmap. * @param align_mask [in] Align mask for start. * * Searches a bitmap for the first space of contiguous zeros that is large @@ -317,7 +295,7 @@ unsigned long bitmap_find_next_zero_area_off(unsigned long *map, unsigned long bitmap_find_next_zero_area(unsigned long *map, unsigned long size, unsigned long start, - unsigned int nr, + unsigned int bit, unsigned long align_mask); #endif /* NVGPU_POSIX_BITOPS_H */ diff --git a/drivers/gpu/nvgpu/os/posix/bitmap.c b/drivers/gpu/nvgpu/os/posix/bitmap.c index 64f7cf045..2423b4a79 100644 --- a/drivers/gpu/nvgpu/os/posix/bitmap.c +++ b/drivers/gpu/nvgpu/os/posix/bitmap.c @@ -28,8 +28,18 @@ #include #include -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) -#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +static inline unsigned long get_mask(unsigned int bit) +{ + unsigned long lbit = bit; + lbit %= BITS_PER_LONG; + return (1UL << lbit); +} + +static inline unsigned int get_index(unsigned int bit) +{ + unsigned long bpl = BITS_PER_LONG; + return (bit / nvgpu_safe_cast_u64_to_u32(bpl)); +} unsigned long nvgpu_posix_ffs(unsigned long word) { @@ -67,7 +77,7 @@ unsigned long nvgpu_posix_fls(unsigned long word) return ret; } -static unsigned long nvgpu_posix_find_next_bit(const unsigned long *addr, +static unsigned long nvgpu_posix_find_next_bit(const unsigned long *address, unsigned long n, unsigned long start, bool invert) @@ -75,7 +85,7 @@ static unsigned long nvgpu_posix_find_next_bit(const unsigned long *addr, unsigned long idx, idx_max; unsigned long w; unsigned long start_mask; - const unsigned long *base_addr = (const unsigned long *)&addr[0]; + const unsigned long *base_addr = (const unsigned long *)&address[0]; /* * We make a mask we can XOR into the word so that we can invert the @@ -124,27 +134,27 @@ static unsigned long nvgpu_posix_find_next_bit(const unsigned long *addr, (nvgpu_safe_mult_u64(idx, BITS_PER_LONG))))); } -unsigned long find_first_bit(const unsigned long *addr, unsigned long size) +unsigned long find_first_bit(const unsigned long *address, unsigned long size) { - return nvgpu_posix_find_next_bit(addr, size, 0, false); + return nvgpu_posix_find_next_bit(address, size, 0, false); } -unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) +unsigned long find_first_zero_bit(const unsigned long *address, unsigned long size) { - return nvgpu_posix_find_next_bit(addr, size, 0, true); + return nvgpu_posix_find_next_bit(address, size, 0, true); } -unsigned long find_next_bit(const unsigned long *addr, unsigned long size, +unsigned long find_next_bit(const unsigned long *address, unsigned long size, unsigned long offset) { - return nvgpu_posix_find_next_bit(addr, size, offset, false); + return nvgpu_posix_find_next_bit(address, size, offset, false); } -static unsigned long find_next_zero_bit(const unsigned long *addr, +static unsigned long find_next_zero_bit(const unsigned long *address, unsigned long size, unsigned long offset) { - return nvgpu_posix_find_next_bit(addr, size, offset, true); + return nvgpu_posix_find_next_bit(address, size, offset, true); } void nvgpu_bitmap_set(unsigned long *map, unsigned int start, unsigned int len) @@ -175,33 +185,29 @@ void nvgpu_bitmap_clear(unsigned long *map, * That means that this is not a vary smart allocator. But it is fast relative * to an allocator that goes looking for an optimal location. */ -unsigned long bitmap_find_next_zero_area_off(unsigned long *map, - unsigned long size, - unsigned long start, - unsigned int nr, - unsigned long align_mask, - unsigned long align_offset) +unsigned long bitmap_find_next_zero_area(unsigned long *map, + unsigned long size, + unsigned long start, + unsigned int bit, + unsigned long align_mask) { unsigned long offs; - while ((nvgpu_safe_add_u64(start, (unsigned long)nr)) <= size) { + while ((nvgpu_safe_add_u64(start, (unsigned long)bit)) <= size) { start = find_next_zero_bit(map, size, start); - start = nvgpu_safe_sub_u64( - ALIGN_MASK(nvgpu_safe_add_u64(start, align_offset), - align_mask), - align_offset); + start = ALIGN_MASK(start, align_mask); /* * Not enough space left to satisfy the requested area. */ - if ((nvgpu_safe_add_u64(start, (unsigned long)nr)) > size) { + if ((nvgpu_safe_add_u64(start, (unsigned long)bit)) > size) { return size; } offs = find_next_bit(map, size, start); - if ((offs - start) >= nr) { + if ((offs - start) >= bit) { return start; } @@ -211,54 +217,44 @@ unsigned long bitmap_find_next_zero_area_off(unsigned long *map, return size; } -unsigned long bitmap_find_next_zero_area(unsigned long *map, - unsigned long size, - unsigned long start, - unsigned int nr, - unsigned long align_mask) +bool nvgpu_test_bit(unsigned int bit, const volatile unsigned long *address) { - return bitmap_find_next_zero_area_off(map, size, start, nr, - align_mask, 0); + return (1UL & (address[get_index(bit)] >> + (bit & (BITS_PER_LONG-1UL)))) != 0UL; } -bool nvgpu_test_bit(unsigned int nr, const volatile unsigned long *addr) +bool nvgpu_test_and_set_bit(unsigned int bit, volatile unsigned long *address) { - return (1UL & (addr[BIT_WORD(nr)] >> - (nr & (BITS_PER_LONG-1UL)))) != 0UL; -} - -bool nvgpu_test_and_set_bit(unsigned int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); + unsigned long mask = get_mask(bit); volatile unsigned _Atomic long *p = - (volatile unsigned _Atomic long *)addr + BIT_WORD(nr); + (volatile unsigned _Atomic long *)address + get_index(bit); return (atomic_fetch_or(p, mask) & mask) != 0ULL; } -bool nvgpu_test_and_clear_bit(unsigned int nr, volatile unsigned long *addr) +bool nvgpu_test_and_clear_bit(unsigned int bit, volatile unsigned long *address) { - unsigned long mask = BIT_MASK(nr); + unsigned long mask = get_mask(bit); volatile unsigned _Atomic long *p = - (volatile unsigned _Atomic long *)addr + BIT_WORD(nr); + (volatile unsigned _Atomic long *)address + get_index(bit); return (atomic_fetch_and(p, ~mask) & mask) != 0ULL; } -void nvgpu_set_bit(unsigned int nr, volatile unsigned long *addr) +void nvgpu_set_bit(unsigned int bit, volatile unsigned long *address) { - unsigned long mask = BIT_MASK(nr); + unsigned long mask = get_mask(bit); volatile unsigned _Atomic long *p = - (unsigned volatile _Atomic long *)addr + BIT_WORD(nr); + (unsigned volatile _Atomic long *)address + get_index(bit); (void)atomic_fetch_or(p, mask); } -void nvgpu_clear_bit(unsigned int nr, volatile unsigned long *addr) +void nvgpu_clear_bit(unsigned int bit, volatile unsigned long *address) { - unsigned long mask = BIT_MASK(nr); + unsigned long mask = get_mask(bit); volatile unsigned _Atomic long *p = - (volatile unsigned _Atomic long *)addr + BIT_WORD(nr); + (volatile unsigned _Atomic long *)address + get_index(bit); (void)atomic_fetch_and(p, ~mask); } diff --git a/libs/dgpu/libnvgpu-drv-dgpu_safe.export b/libs/dgpu/libnvgpu-drv-dgpu_safe.export index 55d5bbf26..fcfd0b749 100644 --- a/libs/dgpu/libnvgpu-drv-dgpu_safe.export +++ b/libs/dgpu/libnvgpu-drv-dgpu_safe.export @@ -1,6 +1,5 @@ # Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. -bitmap_find_next_zero_area_off bitmap_find_next_zero_area fb_gv11b_write_mmu_fault_buffer_get find_first_bit diff --git a/libs/igpu/libnvgpu-drv-igpu_safe.export b/libs/igpu/libnvgpu-drv-igpu_safe.export index 6542d134b..6a62754a3 100644 --- a/libs/igpu/libnvgpu-drv-igpu_safe.export +++ b/libs/igpu/libnvgpu-drv-igpu_safe.export @@ -1,6 +1,5 @@ # Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. -bitmap_find_next_zero_area_off bitmap_find_next_zero_area fb_gv11b_write_mmu_fault_buffer_get find_first_bit diff --git a/userspace/units/posix/bitops/posix-bitops.c b/userspace/units/posix/bitops/posix-bitops.c index 085acc990..281f36633 100644 --- a/userspace/units/posix/bitops/posix-bitops.c +++ b/userspace/units/posix/bitops/posix-bitops.c @@ -348,29 +348,29 @@ int test_find_zero_area(struct unit_module *m, struct gk20a *g, void *unused) } for (i = 0; i < TEST_BITMAP_SIZE; i++) { - result = bitmap_find_next_zero_area_off(bmap_all_zeros, + result = bitmap_find_next_zero_area(bmap_all_zeros, TEST_BITMAP_SIZE, i, TEST_BITMAP_SIZE - i, - 0, 0); + 0); if (result != i) unit_return_fail(m, FAIL_MSG, "all_zeros: alloc-to-end", i); - result = bitmap_find_next_zero_area_off(bmap_all_zeros, + result = bitmap_find_next_zero_area(bmap_all_zeros, TEST_BITMAP_SIZE, i, 1, - 0, 0); + 0); if (result != i) unit_return_fail(m, FAIL_MSG, "all_zeros: alloc-one-bit", i); - result = bitmap_find_next_zero_area_off(bmap_all_zeros, + result = bitmap_find_next_zero_area(bmap_all_zeros, TEST_BITMAP_SIZE, 0, TEST_BITMAP_SIZE - i, - 0, 0); + 0); if (result != 0) unit_return_fail(m, FAIL_MSG, "all_zeros: alloc-i-bits-at-0", i); @@ -382,11 +382,11 @@ int test_find_zero_area(struct unit_module *m, struct gk20a *g, void *unused) */ for (i = 0; i < TEST_BITMAP_SIZE; i++) { for (j = 0; j < (TEST_BITMAP_SIZE - i); j++) { - result = bitmap_find_next_zero_area_off(bmap_all_ones, + result = bitmap_find_next_zero_area(bmap_all_ones, TEST_BITMAP_SIZE, i, j, - 0, 0); + 0); if (result != TEST_BITMAP_SIZE) unit_return_fail(m, FAIL_MSG_EX, "all_ones: failed", i, j); @@ -402,11 +402,11 @@ int test_find_zero_area(struct unit_module *m, struct gk20a *g, void *unused) memset(words, 0x0f, sizeof(words)); for (i = 0; i < ((NUM_WORDS * BITS_PER_LONG) - 8); i++) { for (j = 0; j < ((NUM_WORDS * BITS_PER_LONG) - i - 8); j++) { - result = bitmap_find_next_zero_area_off(words, + result = bitmap_find_next_zero_area(words, NUM_WORDS * BITS_PER_LONG, i, j, - 0, 0); + 0); /* * Should only return a valid result when j < 4 (since @@ -422,27 +422,16 @@ int test_find_zero_area(struct unit_module *m, struct gk20a *g, void *unused) "alternating-nibbles: failed", i, j); - result = bitmap_find_next_zero_area_off(words, + result = bitmap_find_next_zero_area(words, NUM_WORDS * BITS_PER_LONG, i, (j % 4) + 1, - 0x3, 0); + 0x3); if (result % 8 != 4) unit_return_fail(m, FAIL_MSG_EX, "basic-align_mask: failed", i, j); - - result = bitmap_find_next_zero_area_off(words, - NUM_WORDS * BITS_PER_LONG, - i, - (j % 2) + 1, - 0x7, 2); - - if (result % 8 != 6) - unit_return_fail(m, FAIL_MSG_EX, - "basic-align_offset: failed", - i, j); } }