gpu: nvgpu: posix: fix GPL dependencies in bitmap

Fix up GPL issues in posix version of bitops.

Bug 2919200

Change-Id: I57fdb035b811f47e119cca2278431d3701717d89
Signed-off-by: Peter Daifuku <pdaifuku@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2340983
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Peter Daifuku
2020-05-07 19:39:31 -07:00
committed by Alex Waterman
parent 681077d578
commit f0f126d7cc
5 changed files with 97 additions and 136 deletions

View File

@@ -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 */

View File

@@ -28,8 +28,18 @@
#include <nvgpu/posix/bitops.h>
#include <nvgpu/posix/atomic.h>
#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 bitmap_find_next_zero_area(unsigned long *map,
unsigned long size,
unsigned long start,
unsigned int nr,
unsigned long align_mask,
unsigned long align_offset)
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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}