PERFORCE change 128871 for review

Steve Wise swise at FreeBSD.org
Fri Nov 9 10:56:38 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=128871

Change 128871 by swise at swise:vic10:iwarp on 2007/11/09 18:55:42

	rmda_iwcm compiles.

Affected files ...

.. //depot/projects/iwarp/sys/contrib/rdma/rdma_cma.c#4 edit
.. //depot/projects/iwarp/sys/contrib/rdma/rdma_iwcm.c#2 edit
.. //depot/projects/iwarp/sys/sys/linux_compat.h#4 edit

Differences ...

==== //depot/projects/iwarp/sys/contrib/rdma/rdma_cma.c#4 (text+ko) ====

@@ -2931,4 +2931,6 @@
 };
 
 MODULE_VERSION(rdma_cma, 1);
+MODULE_DEPEND(rdma_cma, rdma_core, 1, 1, 1);
+MODULE_DEPEND(rdma_cma, rdma_addr, 1, 1, 1);
 DECLARE_MODULE(rdma_cma, mod_data, SI_SUB_EXEC, SI_ORDER_ANY);

==== //depot/projects/iwarp/sys/contrib/rdma/rdma_iwcm.c#2 (text+ko) ====

@@ -35,31 +35,68 @@
  * SOFTWARE.
  *
  */
-#include <linux/dma-mapping.h>
-#include <linux/err.h>
-#include <linux/idr.h>
-#include <linux/interrupt.h>
-#include <linux/rbtree.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/completion.h>
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/condvar.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/socket.h>
+#include <sys/module.h>
+#include <sys/linux_compat.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/rwlock.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/priv.h>
+#include <sys/syslog.h>
+#include <sys/linux_compat.h>
 
-#include <rdma/iw_cm.h>
-#include <rdma/ib_addr.h>
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
 
-#include "iwcm.h"
+#include <contrib/rdma/iw_cm.h>
 
 MODULE_AUTHOR("Tom Tucker");
 MODULE_DESCRIPTION("iWARP CM");
 MODULE_LICENSE("Dual BSD/GPL");
 
-static struct workqueue_struct *iwcm_wq;
+enum iw_cm_state {
+	IW_CM_STATE_IDLE,             /* unbound, inactive */
+	IW_CM_STATE_LISTEN,           /* listen waiting for connect */
+	IW_CM_STATE_CONN_RECV,        /* inbound waiting for user accept */
+	IW_CM_STATE_CONN_SENT,        /* outbound waiting for peer accept */
+	IW_CM_STATE_ESTABLISHED,      /* established */
+	IW_CM_STATE_CLOSING,	      /* disconnect */
+	IW_CM_STATE_DESTROYING        /* object being deleted */
+};
+
+struct iwcm_id_private {
+	struct iw_cm_id	id;
+	enum iw_cm_state state;
+	unsigned long flags;
+	struct ib_qp *qp;
+	struct cv destroy_comp;
+	struct cv connect_wait;
+	TAILQ_HEAD(, iwcm_work) work_list;
+	struct mtx lock;
+	atomic_t refcount;
+	TAILQ_HEAD(, iwcm_work) work_free_list;
+};
+
+#define IWCM_F_CALLBACK_DESTROY   1
+#define IWCM_F_CONNECT_WAIT       2
+
+static struct taskqueue *iwcm_wq;
 struct iwcm_work {
-	struct work_struct work;
+	struct task task;
 	struct iwcm_id_private *cm_id;
-	struct list_head list;
+	TAILQ_ENTRY(iwcm_work) list;
 	struct iw_cm_event event;
-	struct list_head free_list;
+	TAILQ_ENTRY(iwcm_work) free_list;
 };
 
 /*
@@ -90,40 +127,38 @@
 {
 	struct iwcm_work *work;
 
-	if (TAILQ_EMPTY((&cm_id_priv->work_free_list))
+	if (TAILQ_EMPTY(&cm_id_priv->work_free_list))
 		return NULL;
-	work = list_entry(cm_id_priv->work_free_list.next, struct iwcm_work,
-			  free_list);
-	list_del_init(&work->free_list);
+	work = TAILQ_FIRST(&cm_id_priv->work_free_list);
+	TAILQ_REMOVE(&cm_id_priv->work_free_list, work, free_list);
 	return work;
 }
 
 static void put_work(struct iwcm_work *work)
 {
-	list_add(&work->free_list, &work->cm_id->work_free_list);
+	TAILQ_INSERT_HEAD(&work->cm_id->work_free_list, work, free_list);
 }
 
 static void dealloc_work_entries(struct iwcm_id_private *cm_id_priv)
 {
-	struct list_head *e, *tmp;
+	struct iwcm_work *e, *tmp;
 
-	list_for_each_safe(e, tmp, &cm_id_priv->work_free_list)
-		kfree(list_entry(e, struct iwcm_work, free_list));
+	TAILQ_FOREACH_SAFE(e, &cm_id_priv->work_free_list, free_list, tmp)
+		free(e, M_DEVBUF);
 }
 
 static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count)
 {
 	struct iwcm_work *work;
 
-	BUG_ON(!TAILQ_EMPTY((&cm_id_priv->work_free_list));
+	BUG_ON(!TAILQ_EMPTY(&cm_id_priv->work_free_list));
 	while (count--) {
-		work = kmalloc(sizeof(struct iwcm_work), GFP_KERNEL);
+		work = malloc(sizeof(struct iwcm_work), M_DEVBUF, M_WAITOK);
 		if (!work) {
 			dealloc_work_entries(cm_id_priv);
 			return (ENOMEM);
 		}
 		work->cm_id = cm_id_priv;
-		INIT_LIST_HEAD(&work->list);
 		put_work(work);
 	}
 	return 0;
@@ -138,9 +173,10 @@
 {
 	void *p;
 
-	p = kmemdup(event->private_data, event->private_data_len, GFP_ATOMIC);
+	p = malloc(event->private_data_len, M_DEVBUF, M_NOWAIT);
 	if (!p)
 		return (ENOMEM);
+	bcopy(event->private_data, p, event->private_data_len);
 	event->private_data = p;
 	return 0;
 }
@@ -148,7 +184,7 @@
 static void free_cm_id(struct iwcm_id_private *cm_id_priv)
 {
 	dealloc_work_entries(cm_id_priv);
-	kfree(cm_id_priv);
+	free(cm_id_priv, M_DEVBUF);
 }
 
 /*
@@ -158,12 +194,15 @@
  */
 static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
 {
+	mtx_lock(&cm_id_priv->lock);
 	BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
 	if (atomic_dec_and_test(&cm_id_priv->refcount)) {
-		BUG_ON(!TAILQ_EMPTY((&cm_id_priv->work_list));
-		complete(&cm_id_priv->destroy_comp);
+		BUG_ON(!TAILQ_EMPTY(&cm_id_priv->work_list));
+		cv_broadcast(&cm_id_priv->destroy_comp);
+		mtx_unlock(&cm_id_priv->lock);
 		return 1;
 	}
+	mtx_unlock(&cm_id_priv->lock);
 
 	return 0;
 }
@@ -181,7 +220,7 @@
 	cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
 	if (iwcm_deref_id(cm_id_priv) &&
 	    test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
-		BUG_ON(!TAILQ_EMPTY((&cm_id_priv->work_list));
+		BUG_ON(!TAILQ_EMPTY(&cm_id_priv->work_list));
 		free_cm_id(cm_id_priv);
 	}
 }
@@ -194,9 +233,10 @@
 {
 	struct iwcm_id_private *cm_id_priv;
 
-	cm_id_priv = kzalloc(sizeof(*cm_id_priv), GFP_KERNEL);
+	cm_id_priv = malloc(sizeof(*cm_id_priv), M_DEVBUF, M_WAITOK);
 	if (!cm_id_priv)
 		return ERR_PTR(ENOMEM);
+	bzero(cm_id_priv, sizeof *cm_id_priv);
 
 	cm_id_priv->state = IW_CM_STATE_IDLE;
 	cm_id_priv->id.device = device;
@@ -205,10 +245,10 @@
 	cm_id_priv->id.event_handler = cm_event_handler;
 	cm_id_priv->id.add_ref = add_ref;
 	cm_id_priv->id.rem_ref = rem_ref;
-	mtx_init(&cm_id_priv->lock, "cm id priv", NULL, MTX_DUPOK|MTX_DEF);
+	mtx_init(&cm_id_priv->lock, "cm_id_priv", NULL, MTX_DUPOK|MTX_SPIN);
 	atomic_set(&cm_id_priv->refcount, 1);
-	cv_init(&cm_id_priv->connect_wait, "cm_id_priv connect wait");
-	init_completion(&cm_id_priv->destroy_comp);
+	cv_init(&cm_id_priv->connect_wait, "cm_id_priv connect_wait");
+	cv_init(&cm_id_priv->destroy_comp, "cm_id_priv destroy_comp");
 	TAILQ_INIT(&cm_id_priv->work_list);
 	TAILQ_INIT(&cm_id_priv->work_free_list);
 
@@ -261,11 +301,10 @@
 
 	cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
 	/* Wait if we're currently in a connect or accept downcall */
+	mtx_lock(&cm_id_priv->lock);
 	if (test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags))
-		wait_event(&cm_id_priv->connect_wait, &cm_id_priv->lock)
-		   
+		cv_wait(&cm_id_priv->connect_wait, &cm_id_priv->lock);
 
-	mtx_lock(&cm_id_priv->lock);
 	switch (cm_id_priv->state) {
 	case IW_CM_STATE_ESTABLISHED:
 		cm_id_priv->state = IW_CM_STATE_CLOSING;
@@ -330,10 +369,10 @@
 	 * Wait if we're currently in a connect or accept downcall. A
 	 * listening endpoint should never block here.
 	 */
+	mtx_lock(&cm_id_priv->lock);
 	if (test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags))
-		wait_event(&cm_id_priv->connect_wait, &cm_id_priv->lock);
+		cv_wait(&cm_id_priv->connect_wait, &cm_id_priv->lock);
 
-	mtx_lock(&cm_id_priv->lock);
 	switch (cm_id_priv->state) {
 	case IW_CM_STATE_LISTEN:
 		cm_id_priv->state = IW_CM_STATE_DESTROYING;
@@ -380,7 +419,7 @@
 /*
  * This function is only called by the application thread and cannot
  * be called by the event thread. The function will wait for all
- * references to be released on the cm_id and then kfree the cm_id
+ * references to be released on the cm_id and then free the cm_id
  * object.
  */
 void iw_destroy_cm_id(struct iw_cm_id *cm_id)
@@ -392,7 +431,8 @@
 
 	destroy_cm_id(cm_id);
 
-	wait_for_completion(&cm_id_priv->destroy_comp);
+	mtx_lock(&cm_id_priv->lock);
+	cv_wait(&cm_id_priv->destroy_comp, &cm_id_priv->lock);
 
 	free_cm_id(cm_id_priv);
 }
@@ -451,9 +491,9 @@
 
 	mtx_lock(&cm_id_priv->lock);
 	if (cm_id_priv->state != IW_CM_STATE_CONN_RECV) {
+		clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
+		cv_broadcast(&cm_id_priv->connect_wait);
 		mtx_unlock(&cm_id_priv->lock);
-		clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
-		wake_up_all(&cm_id_priv->connect_wait, &cm_id_priv->lock);
 		return (EINVAL);
 	}
 	cm_id_priv->state = IW_CM_STATE_IDLE;
@@ -462,8 +502,10 @@
 	ret = cm_id->device->iwcm->reject(cm_id, private_data,
 					  private_data_len);
 
+	mtx_lock(&cm_id_priv->lock);
 	clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
-	wake_up_all(&cm_id_priv->connect_wait, &cm_id_priv->lock);
+	cv_broadcast(&cm_id_priv->connect_wait);
+	mtx_unlock(&cm_id_priv->lock);
 
 	return ret;
 }
@@ -488,9 +530,9 @@
 
 	mtx_lock(&cm_id_priv->lock);
 	if (cm_id_priv->state != IW_CM_STATE_CONN_RECV) {
+		clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
+		cv_broadcast(&cm_id_priv->connect_wait);
 		mtx_unlock(&cm_id_priv->lock);
-		clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
-		wake_up_all(&cm_id_priv->connect_wait, &cm_id_priv->lock);
 		
 		return (EINVAL);
 	}
@@ -514,9 +556,9 @@
 			cm_id->device->iwcm->rem_ref(qp);
 			cm_id_priv->qp = NULL;
 		}
+		clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
+		cv_broadcast(&cm_id_priv->connect_wait);
 		mtx_unlock(&cm_id_priv->lock);
-		clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
-		wake_up_all(&cm_id_priv->connect_wait, &cm_id_priv->lock);
 	}
 
 	return ret;
@@ -546,9 +588,9 @@
 	mtx_lock(&cm_id_priv->lock);
 
 	if (cm_id_priv->state != IW_CM_STATE_IDLE) {
+		clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
+		cv_broadcast(&cm_id_priv->connect_wait);
 		mtx_unlock(&cm_id_priv->lock);
-		clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
-		wake_up_all(&cm_id_priv->connect_wait, &cm_id_priv->lock);
 		
 		return (EINVAL);
 	}
@@ -571,11 +613,11 @@
 			cm_id->device->iwcm->rem_ref(qp);
 			cm_id_priv->qp = NULL;
 		}
-		mtx_unlock(&cm_id_priv->lock);
 		BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT);
 		cm_id_priv->state = IW_CM_STATE_IDLE;
 		clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
-		wake_up_all(&cm_id_priv->connect_wait, &cm_id_priv->lock);
+		cv_broadcast(&cm_id_priv->connect_wait);
+		mtx_unlock(&cm_id_priv->lock);
 		
 	}
 
@@ -655,7 +697,7 @@
 
 out:
 	if (iw_event->private_data_len)
-		kfree(iw_event->private_data);
+		free(iw_event->private_data, M_DEVBUF);
 }
 
 /*
@@ -685,9 +727,9 @@
 	clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
 	BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_RECV);
 	cm_id_priv->state = IW_CM_STATE_ESTABLISHED;
+	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event);
+	cv_broadcast(&cm_id_priv->connect_wait);
 	mtx_unlock(&cm_id_priv->lock);
-	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event);
-	wake_up_all(&cm_id_priv->connect_wait, &cm_id_priv->lock);
 
 	return ret;
 }
@@ -724,11 +766,13 @@
 	mtx_unlock(&cm_id_priv->lock);
 	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event);
 
+	mtx_lock(&cm_id_priv->lock);
 	if (iw_event->private_data_len)
-		kfree(iw_event->private_data);
+		free(iw_event->private_data, M_DEVBUF);
 
 	/* Wake up waiters on connect complete */
-	wake_up_all(&cm_id_priv->connect_wait, &cm_id_priv->lock);
+	cv_broadcast(&cm_id_priv->connect_wait);
+	mtx_unlock(&cm_id_priv->lock);
 
 	return ret;
 }
@@ -824,20 +868,20 @@
  * thread asleep on the destroy_comp list vs. an object destroyed
  * here synchronously when the last reference is removed.
  */
-static void cm_work_handler(struct work_struct *_work)
+static void cm_work_handler(void *context, int pending)
 {
-	struct iwcm_work *work = container_of(_work, struct iwcm_work, work);
+	struct iwcm_work *work = context;
 	struct iw_cm_event levent;
 	struct iwcm_id_private *cm_id_priv = work->cm_id;
 	int empty;
 	int ret = 0;
 
 	mtx_lock(&cm_id_priv->lock);
-	empty = TAILQ_EMPTY((&cm_id_priv->work_list);
+	empty = TAILQ_EMPTY(&cm_id_priv->work_list);
 	while (!empty) {
 		work = TAILQ_FIRST(&cm_id_priv->work_list);
-		TAILQ_REMOVE(&cm_id_priv->work_list, work, entry);
-		empty = TAILQ_EMPTY((&cm_id_priv->work_list);
+		TAILQ_REMOVE(&cm_id_priv->work_list, work, list);
+		empty = TAILQ_EMPTY(&cm_id_priv->work_list);
 		levent = work->event;
 		put_work(work);
 		mtx_unlock(&cm_id_priv->lock);
@@ -851,7 +895,7 @@
 		if (iwcm_deref_id(cm_id_priv)) {
 			if (test_bit(IWCM_F_CALLBACK_DESTROY,
 				     &cm_id_priv->flags)) {
-				BUG_ON(!TAILQ_EMPTY((&cm_id_priv->work_list));
+				BUG_ON(!TAILQ_EMPTY(&cm_id_priv->work_list));
 				free_cm_id(cm_id_priv);
 			}
 			return;
@@ -892,7 +936,7 @@
 		goto out;
 	}
 
-	INIT_WORK(&work->work, cm_work_handler);
+        TASK_INIT(&work->task, 0, cm_work_handler, work);
 	work->cm_id = cm_id_priv;
 	work->event = *iw_event;
 
@@ -907,11 +951,11 @@
 	}
 
 	atomic_inc(&cm_id_priv->refcount);
-	if (TAILQ_EMPTY((&cm_id_priv->work_list)) {
-		list_add_tail(&work->list, &cm_id_priv->work_list);
-		taskqueue_enqueue(iwcm_wq, &work->work);
+	if (TAILQ_EMPTY(&cm_id_priv->work_list)) {
+		TAILQ_INSERT_TAIL(&cm_id_priv->work_list, work, list);
+		taskqueue_enqueue(iwcm_wq, &work->task);
 	} else
-		list_add_tail(&work->list, &cm_id_priv->work_list);
+		TAILQ_INSERT_TAIL(&cm_id_priv->work_list, work, list);
 out:
 	mtx_unlock(&cm_id_priv->lock);
 	return ret;
@@ -994,7 +1038,7 @@
 
 static int __init iw_cm_init(void)
 {
-	iwcm_wq = taskqueue_create("iw_cm_wq", M_NOWAIT, taskqueue_thread_enqueue, &iwcm_wq);
+	iwcm_wq = taskqueue_create("iw_cm_wq", M_WAITOK, taskqueue_thread_enqueue, &iwcm_wq);
 	if (!iwcm_wq)
 		return (ENOMEM);
 
@@ -1007,5 +1051,39 @@
 	taskqueue_free(iwcm_wq);
 }
 
-module_init(iw_cm_init);
-module_exit(iw_cm_cleanup);
+static int 
+iw_cm_load(module_t mod, int cmd, void *arg)
+{
+        int err = 0;
+
+        switch (cmd) {
+        case MOD_LOAD:
+                printf("Loading iwcm.\n");
+
+                iw_cm_init();
+                break;
+        case MOD_QUIESCE:
+                break;
+        case MOD_UNLOAD:
+                printf("Unloading iwcm.\n");
+		iw_cm_cleanup();
+                break;
+        case MOD_SHUTDOWN:
+                break;
+        default:
+                err = EOPNOTSUPP;
+                break;
+        }
+
+        return (err);
+}
+
+static moduledata_t mod_data = {
+	"rdma_iwcm",
+	iw_cm_load,
+	0
+};
+
+MODULE_VERSION(rdma_iwcm, 1);
+MODULE_DEPEND(rdma_iwcm, rdma_core, 1, 1, 1);
+DECLARE_MODULE(rdma_iwcm, mod_data, SI_SUB_EXEC, SI_ORDER_ANY);

==== //depot/projects/iwarp/sys/sys/linux_compat.h#4 (text+ko) ====

@@ -75,6 +75,13 @@
 }
 
 #define dst_mtu(rt) ((rt)->rt_rmx.rmx_mtu)
+
+static __inline void 
+BUG(void)
+{
+	panic("BUG: %s:%d", __FILE__, __LINE__);
+}
+
 #define BUG_ON(e) \
 	do { \
 		if (e) { \
@@ -153,6 +160,23 @@
 	}
 }
 
+static __inline void
+set_bit(int b, volatile void *p)
+{
+        atomic_set_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f));
+}
+
+static __inline int
+test_bit(int b, volatile void *p)
+{
+        return ((volatile int *)p)[b >> 5] & (1 << (b & 0x1f));
+}
+
+static __inline void
+clear_bit(int b, volatile void *p)
+{
+        atomic_clear_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f));
+}
 
 #define copy_from_user(a,b,c) copyin(b,a,c)
 #define copy_to_user(a,b,c) copyout(b,a,c)


More information about the p4-projects mailing list