[ewg] [PATCH] [RFC] IB/cache: Add ib_cache report for cache in process

Moni Levy myopenib at gmail.com
Thu Mar 29 07:36:51 PDT 2007


We discovered a race between calls of ib_get_cached_pkey & ib_find_cached_pkey triggered by a PKEY_CHANGE event and the update of the cache they read from.

The new return code (-ESTALE) informs the callers to ib_get_cached_pkey and ib_find_cached_pkey that the ib_cache is in process of updating itself and that the call should be retried if an up to date information is needed. 

Signed-off-by: Moni Levy <monil at voltaire.com>
---
 drivers/infiniband/core/cache.c |   11 +++++++++++
 include/rdma/ib_verbs.h         |    1 +
 2 files changed, 12 insertions(+)

Index: b/include/rdma/ib_verbs.h
===================================================================
--- a/include/rdma/ib_verbs.h	2007-03-29 08:11:37.544251082 +0200
+++ b/include/rdma/ib_verbs.h	2007-03-29 08:11:58.606496898 +0200
@@ -849,6 +849,7 @@ struct ib_cache {
 	struct ib_pkey_cache  **pkey_cache;
 	struct ib_gid_cache   **gid_cache;
 	u8                     *lmc_cache;
+	atomic_t		coherent;
 };
 
 struct ib_dma_mapping_ops {
Index: b/drivers/infiniband/core/cache.c
===================================================================
--- a/drivers/infiniband/core/cache.c	2007-03-29 08:11:37.583244132 +0200
+++ b/drivers/infiniband/core/cache.c	2007-03-29 11:32:38.915910966 +0200
@@ -38,6 +38,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
+#include <asm/atomic.h>
 
 #include <rdma/ib_cache.h>
 
@@ -141,6 +142,9 @@ int ib_get_cached_pkey(struct ib_device 
 	unsigned long flags;
 	int ret = 0;
 
+	if (!atomic_read(&device->cache.coherent))
+		return -ESTALE;
+
 	if (port_num < start_port(device) || port_num > end_port(device))
 		return -EINVAL;
 
@@ -169,6 +173,9 @@ int ib_find_cached_pkey(struct ib_device
 	int i;
 	int ret = -ENOENT;
 
+	if (!atomic_read(&device->cache.coherent))
+		return -ESTALE;
+
 	if (port_num < start_port(device) || port_num > end_port(device))
 		return -EINVAL;
 
@@ -273,6 +280,8 @@ static void ib_cache_update(struct ib_de
 
 	write_unlock_irq(&device->cache.lock);
 
+	atomic_set(&device->cache.coherent, 1);
+
 	kfree(old_pkey_cache);
 	kfree(old_gid_cache);
 	kfree(tprops);
@@ -306,6 +315,7 @@ static void ib_cache_event(struct ib_eve
 	    event->event == IB_EVENT_CLIENT_REREGISTER) {
 		work = kmalloc(sizeof *work, GFP_ATOMIC);
 		if (work) {
+			atomic_set(&work->device->cache.coherent, 0);
 			INIT_WORK(&work->work, ib_cache_task);
 			work->device   = event->device;
 			work->port_num = event->element.port_num;
@@ -319,6 +329,7 @@ static void ib_cache_setup_one(struct ib
 	int p;
 
 	rwlock_init(&device->cache.lock);
+	atomic_set(&device->cache.coherent, 0);
 
 	device->cache.pkey_cache =
 		kmalloc(sizeof *device->cache.pkey_cache *



More information about the ewg mailing list