Add a bitmap to check if the entry is valid or not. This keeps a record of
which entries have been updated and which have not.

Signed-off-by: Goldwyn Rodrigues <rgold...@suse.de>
---
 drivers/infiniband/core/cache.c |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 9353992..c9c9530 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -44,11 +44,13 @@
 
 struct ib_pkey_cache {
        int             table_len;
+       unsigned long   *valid_bm;
        u16             table[0];
 };
 
 struct ib_gid_cache {
        int             table_len;
+       unsigned long   *valid_bm;
        union ib_gid    table[0];
 };
 
@@ -85,13 +87,18 @@ int ib_get_cached_gid(struct ib_device *device,
 
        cache = device->cache.gid_cache[port_num - start_port(device)];
 
+       if (!test_bit(index, cache->valid_bm)) {
+               ret = -ENOENT;
+               goto out;
+       }
+
        if (index < 0 || index >= cache->table_len)
                ret = -EINVAL;
        else
                *gid = cache->table[index];
 
+out:
        read_unlock_irqrestore(&device->cache.lock, flags);
-
        return ret;
 }
 EXPORT_SYMBOL(ib_get_cached_gid);
@@ -146,6 +153,10 @@ int ib_get_cached_pkey(struct ib_device *device,
        read_lock_irqsave(&device->cache.lock, flags);
 
        cache = device->cache.pkey_cache[port_num - start_port(device)];
+       if (!test_bit(index, cache->valid_bm)) {
+               ret = -ENOENT;
+               goto out;
+       }
 
        if (index < 0 || index >= cache->table_len)
                ret = -EINVAL;
@@ -153,7 +164,7 @@ int ib_get_cached_pkey(struct ib_device *device,
                *pkey = cache->table[index];
 
        read_unlock_irqrestore(&device->cache.lock, flags);
-
+out:
        return ret;
 }
 EXPORT_SYMBOL(ib_get_cached_pkey);
@@ -234,6 +245,11 @@ static void ib_cache_update(struct ib_device *device,
                goto err;
 
        pkey_cache->table_len = tprops->pkey_tbl_len;
+       pkey_cache->valid_bm = kzalloc(BITS_TO_LONGS(pkey_cache->table_len),
+               GFP_KERNEL);
+       if (!pkey_cache->valid_bm)
+               goto err;
+
 
        gid_cache = kmalloc(sizeof *gid_cache + tprops->gid_tbl_len *
                            sizeof *gid_cache->table, GFP_KERNEL);
@@ -241,6 +257,10 @@ static void ib_cache_update(struct ib_device *device,
                goto err;
 
        gid_cache->table_len = tprops->gid_tbl_len;
+       gid_cache->valid_bm = kzalloc(BITS_TO_LONGS(gid_cache->table_len),
+               GFP_KERNEL);
+       if (!gid_cache->valid_bm)
+               goto err;
 
        for (i = 0; i < pkey_cache->table_len; ++i) {
                ret = ib_query_pkey(device, port, i, pkey_cache->table + i);
@@ -249,6 +269,7 @@ static void ib_cache_update(struct ib_device *device,
                               ret, device->name, i);
                        goto err;
                }
+               set_bit(i, pkey_cache->valid_bm);
        }
 
        for (i = 0; i < gid_cache->table_len; ++i) {
@@ -258,6 +279,7 @@ static void ib_cache_update(struct ib_device *device,
                               ret, device->name, i);
                        goto err;
                }
+               set_bit(i, gid_cache->valid_bm);
        }
 
        write_lock_irq(&device->cache.lock);
-- 
1.7.6


-- 
Goldwyn
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to