Date: Fri, 9 Nov 2007 18:56:37 GMT From: Steve Wise <swise@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 128871 for review Message-ID: <200711091856.lA9IubEA004958@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=128871 Change 128871 by swise@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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200711091856.lA9IubEA004958>