Commit 9fe66dfd authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband

parents 32983696 1b205c2d
...@@ -8,15 +8,26 @@ config INFINIBAND ...@@ -8,15 +8,26 @@ config INFINIBAND
any protocols you wish to use as well as drivers for your any protocols you wish to use as well as drivers for your
InfiniBand hardware. InfiniBand hardware.
config INFINIBAND_USER_VERBS config INFINIBAND_USER_MAD
tristate "InfiniBand userspace verbs support" tristate "InfiniBand userspace MAD support"
depends on INFINIBAND depends on INFINIBAND
---help--- ---help---
Userspace InfiniBand verbs support. This is the kernel side Userspace InfiniBand Management Datagram (MAD) support. This
of userspace verbs, which allows userspace processes to is the kernel side of the userspace MAD support, which allows
directly access InfiniBand hardware for fast-path userspace processes to send and receive MADs. You will also
operations. You will also need libibverbs and a hardware need libibumad from <http://www.openib.org>.
driver library from <http://www.openib.org>.
config INFINIBAND_USER_ACCESS
tristate "InfiniBand userspace access (verbs and CM)"
depends on INFINIBAND
---help---
Userspace InfiniBand access support. This enables the
kernel side of userspace verbs and the userspace
communication manager (CM). This allows userspace processes
to set up connections and directly access InfiniBand
hardware for fast-path operations. You will also need
libibverbs, libibcm and a hardware driver library from
<http://www.openib.org>.
source "drivers/infiniband/hw/mthca/Kconfig" source "drivers/infiniband/hw/mthca/Kconfig"
......
obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \ obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \
ib_cm.o ib_umad.o ib_ucm.o ib_cm.o
obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o
obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o
ib_core-y := packer.o ud_header.o verbs.o sysfs.o \ ib_core-y := packer.o ud_header.o verbs.o sysfs.o \
device.o fmr_pool.o cache.o device.o fmr_pool.o cache.o
......
...@@ -173,7 +173,8 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv, ...@@ -173,7 +173,8 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
if (IS_ERR(ah)) if (IS_ERR(ah))
return PTR_ERR(ah); return PTR_ERR(ah);
m = ib_create_send_mad(mad_agent, 1, cm_id_priv->av.pkey_index, m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn,
cm_id_priv->av.pkey_index,
ah, 0, sizeof(struct ib_mad_hdr), ah, 0, sizeof(struct ib_mad_hdr),
sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr), sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr),
GFP_ATOMIC); GFP_ATOMIC);
...@@ -536,6 +537,7 @@ struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler, ...@@ -536,6 +537,7 @@ struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
cm_id_priv->id.state = IB_CM_IDLE; cm_id_priv->id.state = IB_CM_IDLE;
cm_id_priv->id.cm_handler = cm_handler; cm_id_priv->id.cm_handler = cm_handler;
cm_id_priv->id.context = context; cm_id_priv->id.context = context;
cm_id_priv->id.remote_cm_qpn = 1;
ret = cm_alloc_id(cm_id_priv); ret = cm_alloc_id(cm_id_priv);
if (ret) if (ret)
goto error; goto error;
...@@ -1313,6 +1315,7 @@ error3: atomic_dec(&cm_id_priv->refcount); ...@@ -1313,6 +1315,7 @@ error3: atomic_dec(&cm_id_priv->refcount);
cm_deref_id(listen_cm_id_priv); cm_deref_id(listen_cm_id_priv);
cm_cleanup_timewait(cm_id_priv->timewait_info); cm_cleanup_timewait(cm_id_priv->timewait_info);
error2: kfree(cm_id_priv->timewait_info); error2: kfree(cm_id_priv->timewait_info);
cm_id_priv->timewait_info = NULL;
error1: ib_destroy_cm_id(&cm_id_priv->id); error1: ib_destroy_cm_id(&cm_id_priv->id);
return ret; return ret;
} }
......
...@@ -593,7 +593,8 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr) ...@@ -593,7 +593,8 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
rmpp_mad->rmpp_hdr.paylen_newwin = rmpp_mad->rmpp_hdr.paylen_newwin =
cpu_to_be32(mad_send_wr->total_seg * cpu_to_be32(mad_send_wr->total_seg *
(sizeof(struct ib_rmpp_mad) - (sizeof(struct ib_rmpp_mad) -
offsetof(struct ib_rmpp_mad, data))); offsetof(struct ib_rmpp_mad, data)) -
mad_send_wr->pad);
mad_send_wr->sg_list[0].length = sizeof(struct ib_rmpp_mad); mad_send_wr->sg_list[0].length = sizeof(struct ib_rmpp_mad);
} else { } else {
mad_send_wr->send_wr.num_sge = 2; mad_send_wr->send_wr.num_sge = 2;
...@@ -602,6 +603,7 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr) ...@@ -602,6 +603,7 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
mad_send_wr->sg_list[1].length = sizeof(struct ib_rmpp_mad) - mad_send_wr->sg_list[1].length = sizeof(struct ib_rmpp_mad) -
mad_send_wr->data_offset; mad_send_wr->data_offset;
mad_send_wr->sg_list[1].lkey = mad_send_wr->sg_list[0].lkey; mad_send_wr->sg_list[1].lkey = mad_send_wr->sg_list[0].lkey;
rmpp_mad->rmpp_hdr.paylen_newwin = 0;
} }
if (mad_send_wr->seg_num == mad_send_wr->total_seg) { if (mad_send_wr->seg_num == mad_send_wr->total_seg) {
......
...@@ -113,32 +113,6 @@ static DEFINE_IDR(query_idr); ...@@ -113,32 +113,6 @@ static DEFINE_IDR(query_idr);
static spinlock_t tid_lock; static spinlock_t tid_lock;
static u32 tid; static u32 tid;
enum {
IB_SA_ATTR_CLASS_PORTINFO = 0x01,
IB_SA_ATTR_NOTICE = 0x02,
IB_SA_ATTR_INFORM_INFO = 0x03,
IB_SA_ATTR_NODE_REC = 0x11,
IB_SA_ATTR_PORT_INFO_REC = 0x12,
IB_SA_ATTR_SL2VL_REC = 0x13,
IB_SA_ATTR_SWITCH_REC = 0x14,
IB_SA_ATTR_LINEAR_FDB_REC = 0x15,
IB_SA_ATTR_RANDOM_FDB_REC = 0x16,
IB_SA_ATTR_MCAST_FDB_REC = 0x17,
IB_SA_ATTR_SM_INFO_REC = 0x18,
IB_SA_ATTR_LINK_REC = 0x20,
IB_SA_ATTR_GUID_INFO_REC = 0x30,
IB_SA_ATTR_SERVICE_REC = 0x31,
IB_SA_ATTR_PARTITION_REC = 0x33,
IB_SA_ATTR_RANGE_REC = 0x34,
IB_SA_ATTR_PATH_REC = 0x35,
IB_SA_ATTR_VL_ARB_REC = 0x36,
IB_SA_ATTR_MC_GROUP_REC = 0x37,
IB_SA_ATTR_MC_MEMBER_REC = 0x38,
IB_SA_ATTR_TRACE_REC = 0x39,
IB_SA_ATTR_MULTI_PATH_REC = 0x3a,
IB_SA_ATTR_SERVICE_ASSOC_REC = 0x3b
};
#define PATH_REC_FIELD(field) \ #define PATH_REC_FIELD(field) \
.struct_offset_bytes = offsetof(struct ib_sa_path_rec, field), \ .struct_offset_bytes = offsetof(struct ib_sa_path_rec, field), \
.struct_size_bytes = sizeof ((struct ib_sa_path_rec *) 0)->field, \ .struct_size_bytes = sizeof ((struct ib_sa_path_rec *) 0)->field, \
...@@ -431,8 +405,8 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event ...@@ -431,8 +405,8 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event
event->event == IB_EVENT_LID_CHANGE || event->event == IB_EVENT_LID_CHANGE ||
event->event == IB_EVENT_PKEY_CHANGE || event->event == IB_EVENT_PKEY_CHANGE ||
event->event == IB_EVENT_SM_CHANGE) { event->event == IB_EVENT_SM_CHANGE) {
struct ib_sa_device *sa_dev = struct ib_sa_device *sa_dev;
ib_get_client_data(event->device, &sa_client); sa_dev = container_of(handler, typeof(*sa_dev), event_handler);
schedule_work(&sa_dev->port[event->element.port_num - schedule_work(&sa_dev->port[event->element.port_num -
sa_dev->start_port].update_task); sa_dev->start_port].update_task);
......
This diff is collapsed.
/* /*
* Copyright (c) 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Intel Corporation. All rights reserved.
* *
* This software is available to you under a choice of one of two * This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU * licenses. You may choose to be licensed under the terms of the GNU
...@@ -43,8 +44,6 @@ ...@@ -43,8 +44,6 @@
#include <rdma/ib_cm.h> #include <rdma/ib_cm.h>
#include <rdma/ib_user_cm.h> #include <rdma/ib_user_cm.h>
#define IB_UCM_CM_ID_INVALID 0xffffffff
struct ib_ucm_file { struct ib_ucm_file {
struct semaphore mutex; struct semaphore mutex;
struct file *filp; struct file *filp;
...@@ -58,9 +57,11 @@ struct ib_ucm_context { ...@@ -58,9 +57,11 @@ struct ib_ucm_context {
int id; int id;
wait_queue_head_t wait; wait_queue_head_t wait;
atomic_t ref; atomic_t ref;
int events_reported;
struct ib_ucm_file *file; struct ib_ucm_file *file;
struct ib_cm_id *cm_id; struct ib_cm_id *cm_id;
__u64 uid;
struct list_head events; /* list of pending events. */ struct list_head events; /* list of pending events. */
struct list_head file_list; /* member in file ctx list */ struct list_head file_list; /* member in file ctx list */
...@@ -71,16 +72,12 @@ struct ib_ucm_event { ...@@ -71,16 +72,12 @@ struct ib_ucm_event {
struct list_head file_list; /* member in file event list */ struct list_head file_list; /* member in file event list */
struct list_head ctx_list; /* member in ctx event list */ struct list_head ctx_list; /* member in ctx event list */
struct ib_cm_id *cm_id;
struct ib_ucm_event_resp resp; struct ib_ucm_event_resp resp;
void *data; void *data;
void *info; void *info;
int data_len; int data_len;
int info_len; int info_len;
/*
* new connection identifiers needs to be saved until
* userspace can get a handle on them.
*/
struct ib_cm_id *cm_id;
}; };
#endif /* UCM_H */ #endif /* UCM_H */
...@@ -76,20 +76,28 @@ struct ib_uverbs_file { ...@@ -76,20 +76,28 @@ struct ib_uverbs_file {
struct ib_uverbs_event_file comp_file[1]; struct ib_uverbs_event_file comp_file[1];
}; };
struct ib_uverbs_async_event { struct ib_uverbs_event {
struct ib_uverbs_async_event_desc desc; union {
struct ib_uverbs_async_event_desc async;
struct ib_uverbs_comp_event_desc comp;
} desc;
struct list_head list; struct list_head list;
struct list_head obj_list;
u32 *counter;
}; };
struct ib_uverbs_comp_event { struct ib_uevent_object {
struct ib_uverbs_comp_event_desc desc; struct ib_uobject uobject;
struct list_head list; struct list_head event_list;
u32 events_reported;
}; };
struct ib_uobject_mr { struct ib_ucq_object {
struct ib_uobject uobj; struct ib_uobject uobject;
struct page *page_list; struct list_head comp_list;
struct scatterlist *sg_list; struct list_head async_list;
u32 comp_events_reported;
u32 async_events_reported;
}; };
extern struct semaphore ib_uverbs_idr_mutex; extern struct semaphore ib_uverbs_idr_mutex;
......
This diff is collapsed.
...@@ -120,7 +120,7 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context) ...@@ -120,7 +120,7 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context)
idr_remove(&ib_uverbs_qp_idr, uobj->id); idr_remove(&ib_uverbs_qp_idr, uobj->id);
ib_destroy_qp(qp); ib_destroy_qp(qp);
list_del(&uobj->list); list_del(&uobj->list);
kfree(uobj); kfree(container_of(uobj, struct ib_uevent_object, uobject));
} }
list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) { list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) {
...@@ -128,7 +128,7 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context) ...@@ -128,7 +128,7 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context)
idr_remove(&ib_uverbs_cq_idr, uobj->id); idr_remove(&ib_uverbs_cq_idr, uobj->id);
ib_destroy_cq(cq); ib_destroy_cq(cq);
list_del(&uobj->list); list_del(&uobj->list);
kfree(uobj); kfree(container_of(uobj, struct ib_ucq_object, uobject));
} }
list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) { list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
...@@ -136,7 +136,7 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context) ...@@ -136,7 +136,7 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context)
idr_remove(&ib_uverbs_srq_idr, uobj->id); idr_remove(&ib_uverbs_srq_idr, uobj->id);
ib_destroy_srq(srq); ib_destroy_srq(srq);
list_del(&uobj->list); list_del(&uobj->list);
kfree(uobj); kfree(container_of(uobj, struct ib_uevent_object, uobject));
} }
/* XXX Free MWs */ /* XXX Free MWs */
...@@ -182,7 +182,7 @@ static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf, ...@@ -182,7 +182,7 @@ static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf,
size_t count, loff_t *pos) size_t count, loff_t *pos)
{ {
struct ib_uverbs_event_file *file = filp->private_data; struct ib_uverbs_event_file *file = filp->private_data;
void *event; struct ib_uverbs_event *event;
int eventsz; int eventsz;
int ret = 0; int ret = 0;
...@@ -207,21 +207,23 @@ static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf, ...@@ -207,21 +207,23 @@ static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf,
return -ENODEV; return -ENODEV;
} }
if (file->is_async) { event = list_entry(file->event_list.next, struct ib_uverbs_event, list);
event = list_entry(file->event_list.next,
struct ib_uverbs_async_event, list); if (file->is_async)
eventsz = sizeof (struct ib_uverbs_async_event_desc); eventsz = sizeof (struct ib_uverbs_async_event_desc);
} else { else
event = list_entry(file->event_list.next,
struct ib_uverbs_comp_event, list);
eventsz = sizeof (struct ib_uverbs_comp_event_desc); eventsz = sizeof (struct ib_uverbs_comp_event_desc);
}
if (eventsz > count) { if (eventsz > count) {
ret = -EINVAL; ret = -EINVAL;
event = NULL; event = NULL;
} else } else {
list_del(file->event_list.next); list_del(file->event_list.next);
if (event->counter) {
++(*event->counter);
list_del(&event->obj_list);
}
}
spin_unlock_irq(&file->lock); spin_unlock_irq(&file->lock);
...@@ -257,16 +259,13 @@ static unsigned int ib_uverbs_event_poll(struct file *filp, ...@@ -257,16 +259,13 @@ static unsigned int ib_uverbs_event_poll(struct file *filp,
static void ib_uverbs_event_release(struct ib_uverbs_event_file *file) static void ib_uverbs_event_release(struct ib_uverbs_event_file *file)
{ {
struct list_head *entry, *tmp; struct ib_uverbs_event *entry, *tmp;
spin_lock_irq(&file->lock); spin_lock_irq(&file->lock);
if (file->fd != -1) { if (file->fd != -1) {
file->fd = -1; file->fd = -1;
list_for_each_safe(entry, tmp, &file->event_list) list_for_each_entry_safe(entry, tmp, &file->event_list, list)
if (file->is_async) kfree(entry);
kfree(list_entry(entry, struct ib_uverbs_async_event, list));
else
kfree(list_entry(entry, struct ib_uverbs_comp_event, list));
} }
spin_unlock_irq(&file->lock); spin_unlock_irq(&file->lock);
} }
...@@ -304,18 +303,23 @@ static struct file_operations uverbs_event_fops = { ...@@ -304,18 +303,23 @@ static struct file_operations uverbs_event_fops = {
void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
{ {
struct ib_uverbs_file *file = cq_context; struct ib_uverbs_file *file = cq_context;
struct ib_uverbs_comp_event *entry; struct ib_ucq_object *uobj;
unsigned long flags; struct ib_uverbs_event *entry;
unsigned long flags;
entry = kmalloc(sizeof *entry, GFP_ATOMIC); entry = kmalloc(sizeof *entry, GFP_ATOMIC);
if (!entry) if (!entry)
return; return;
entry->desc.cq_handle = cq->uobject->user_handle; uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
entry->desc.comp.cq_handle = cq->uobject->user_handle;
entry->counter = &uobj->comp_events_reported;
spin_lock_irqsave(&file->comp_file[0].lock, flags); spin_lock_irqsave(&file->comp_file[0].lock, flags);
list_add_tail(&entry->list, &file->comp_file[0].event_list); list_add_tail(&entry->list, &file->comp_file[0].event_list);
list_add_tail(&entry->obj_list, &uobj->comp_list);
spin_unlock_irqrestore(&file->comp_file[0].lock, flags); spin_unlock_irqrestore(&file->comp_file[0].lock, flags);
wake_up_interruptible(&file->comp_file[0].poll_wait); wake_up_interruptible(&file->comp_file[0].poll_wait);
...@@ -323,20 +327,25 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) ...@@ -323,20 +327,25 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
} }
static void ib_uverbs_async_handler(struct ib_uverbs_file *file, static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
__u64 element, __u64 event) __u64 element, __u64 event,
struct list_head *obj_list,
u32 *counter)
{ {
struct ib_uverbs_async_event *entry; struct ib_uverbs_event *entry;
unsigned long flags; unsigned long flags;
entry = kmalloc(sizeof *entry, GFP_ATOMIC); entry = kmalloc(sizeof *entry, GFP_ATOMIC);
if (!entry) if (!entry)
return; return;
entry->desc.element = element; entry->desc.async.element = element;
entry->desc.event_type = event; entry->desc.async.event_type = event;
entry->counter = counter;
spin_lock_irqsave(&file->async_file.lock, flags); spin_lock_irqsave(&file->async_file.lock, flags);
list_add_tail(&entry->list, &file->async_file.event_list); list_add_tail(&entry->list, &file->async_file.event_list);
if (obj_list)
list_add_tail(&entry->obj_list, obj_list);
spin_unlock_irqrestore(&file->async_file.lock, flags); spin_unlock_irqrestore(&file->async_file.lock, flags);
wake_up_interruptible(&file->async_file.poll_wait); wake_up_interruptible(&file->async_file.poll_wait);
...@@ -345,23 +354,39 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file, ...@@ -345,23 +354,39 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
{ {
ib_uverbs_async_handler(context_ptr, struct ib_ucq_object *uobj;
event->element.cq->uobject->user_handle,
event->event); uobj = container_of(event->element.cq->uobject,
struct ib_ucq_object, uobject);
ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,
event->event, &uobj->async_list,
&uobj->async_events_reported);
} }
void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr) void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
{ {
ib_uverbs_async_handler(context_ptr, struct ib_uevent_object *uobj;
event->element.qp->uobject->user_handle,
event->event); uobj = container_of(event->element.qp->uobject,
struct ib_uevent_object, uobject);
ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,
event->event, &uobj->event_list,
&uobj->events_reported);
} }
void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr) void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr)
{ {
ib_uverbs_async_handler(context_ptr, struct ib_uevent_object *uobj;
event->element.srq->uobject->user_handle,
event->event); uobj = container_of(event->element.srq->uobject,
struct ib_uevent_object, uobject);
ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,
event->event, &uobj->event_list,
&uobj->events_reported);
} }
static void ib_uverbs_event_handler(struct ib_event_handler *handler, static void ib_uverbs_event_handler(struct ib_event_handler *handler,
...@@ -370,7 +395,8 @@ static void ib_uverbs_event_handler(struct ib_event_handler *handler, ...@@ -370,7 +395,8 @@ static void ib_uverbs_event_handler(struct ib_event_handler *handler,
struct ib_uverbs_file *file = struct ib_uverbs_file *file =
container_of(handler, struct ib_uverbs_file, event_handler); container_of(handler, struct ib_uverbs_file, event_handler);
ib_uverbs_async_handler(file, event->element.port_num, event->event); ib_uverbs_async_handler(file, event->element.port_num, event->event,
NULL, NULL);
} }
static int ib_uverbs_event_init(struct ib_uverbs_event_file *file, static int ib_uverbs_event_init(struct ib_uverbs_event_file *file,
......
...@@ -220,6 +220,16 @@ static void *get_send_wqe(struct mthca_qp *qp, int n) ...@@ -220,6 +220,16 @@ static void *get_send_wqe(struct mthca_qp *qp, int n)
(PAGE_SIZE - 1)); (PAGE_SIZE - 1));
} }
static void mthca_wq_init(struct mthca_wq *wq)
{
spin_lock_init(&wq->lock);
wq->next_ind = 0;
wq->last_comp = wq->max - 1;
wq->head = 0;
wq->tail = 0;
wq->last = NULL;
}
void mthca_qp_event(struct mthca_dev *dev, u32 qpn, void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
enum ib_event_type event_type) enum ib_event_type event_type)
{ {
...@@ -833,8 +843,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) ...@@ -833,8 +843,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
store_attrs(to_msqp(qp), attr, attr_mask); store_attrs(to_msqp(qp), attr, attr_mask);
/* /*
* If we are moving QP0 to RTR, bring the IB link up; if we * If we moved QP0 to RTR, bring the IB link up; if we moved
* are moving QP0 to RESET or ERROR, bring the link back down. * QP0 to RESET or ERROR, bring the link back down.
*/ */
if (is_qp0(dev, qp)) { if (is_qp0(dev, qp)) {
if (cur_state != IB_QPS_RTR && if (cur_state != IB_QPS_RTR &&
...@@ -848,6 +858,26 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) ...@@ -848,6 +858,26 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status); mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status);
} }
/*
* If we moved a kernel QP to RESET, clean up all old CQ
* entries and reinitialize the QP.
*/
if (!err && new_state == IB_QPS_RESET && !qp->ibqp.uobject) {
mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn,
qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn,
qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
mthca_wq_init(&qp->sq);
mthca_wq_init(&qp->rq);
if (mthca_is_memfree(dev)) {
*qp->sq.db = 0;
*qp->rq.db = 0;
}
}
return err; return err;
} }
...@@ -1003,16 +1033,6 @@ static void mthca_free_memfree(struct mthca_dev *dev, ...@@ -1003,16 +1033,6 @@ static void mthca_free_memfree(struct mthca_dev *dev,
} }
} }
static void mthca_wq_init(struct mthca_wq* wq)
{
spin_lock_init(&wq->lock);
wq->next_ind = 0;
wq->last_comp = wq->max - 1;
wq->head = 0;
wq->tail = 0;
wq->last = NULL;
}
static int mthca_alloc_qp_common(struct mthca_dev *dev, static int mthca_alloc_qp_common(struct mthca_dev *dev,
struct mthca_pd *pd, struct mthca_pd *pd,
struct mthca_cq *send_cq, struct mthca_cq *send_cq,
...@@ -1024,6 +1044,7 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, ...@@ -1024,6 +1044,7 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
int i; int i;
atomic_set(&qp->refcount, 1); atomic_set(&qp->refcount, 1);
init_waitqueue_head(&qp->wait);
qp->state = IB_QPS_RESET; qp->state = IB_QPS_RESET;
qp->atomic_rd_en = 0; qp->atomic_rd_en = 0;
qp->resp_depth = 0; qp->resp_depth = 0;
......
...@@ -1062,6 +1062,8 @@ static void ipoib_remove_one(struct ib_device *device) ...@@ -1062,6 +1062,8 @@ static void ipoib_remove_one(struct ib_device *device)
ipoib_dev_cleanup(priv->dev); ipoib_dev_cleanup(priv->dev);
free_netdev(priv->dev); free_netdev(priv->dev);
} }
kfree(dev_list);
} }
static int __init ipoib_init_module(void) static int __init ipoib_init_module(void)
......
...@@ -290,6 +290,7 @@ struct ib_cm_id { ...@@ -290,6 +290,7 @@ struct ib_cm_id {
enum ib_cm_lap_state lap_state; /* internal CM/debug use */ enum ib_cm_lap_state lap_state; /* internal CM/debug use */
__be32 local_id; __be32 local_id;
__be32 remote_id; __be32 remote_id;
u32 remote_cm_qpn; /* 1 unless redirected */
}; };
/** /**
......
...@@ -173,6 +173,27 @@ struct ib_vendor_mad { ...@@ -173,6 +173,27 @@ struct ib_vendor_mad {
u8 data[216]; u8 data[216];
}; };
struct ib_class_port_info
{
u8 base_version;
u8 class_version;
__be16 capability_mask;
u8 reserved[3];
u8 resp_time_value;
u8 redirect_gid[16];
__be32 redirect_tcslfl;
__be16 redirect_lid;
__be16 redirect_pkey;
__be32 redirect_qp;
__be32 redirect_qkey;
u8 trap_gid[16];
__be32 trap_tcslfl;
__be16 trap_lid;
__be16 trap_pkey;
__be32 trap_hlqp;
__be32 trap_qkey;
};
/** /**
* ib_mad_send_buf - MAD data buffer and work request for sends. * ib_mad_send_buf - MAD data buffer and work request for sends.
* @mad: References an allocated MAD data buffer. The size of the data * @mad: References an allocated MAD data buffer. The size of the data
......
...@@ -46,7 +46,36 @@ enum { ...@@ -46,7 +46,36 @@ enum {
IB_SA_METHOD_GET_TABLE = 0x12, IB_SA_METHOD_GET_TABLE = 0x12,
IB_SA_METHOD_GET_TABLE_RESP = 0x92, IB_SA_METHOD_GET_TABLE_RESP = 0x92,
IB_SA_METHOD_DELETE = 0x15 IB_SA_METHOD_DELETE = 0x15,
IB_SA_METHOD_DELETE_RESP = 0x95,
IB_SA_METHOD_GET_MULTI = 0x14,
IB_SA_METHOD_GET_MULTI_RESP = 0x94,
IB_SA_METHOD_GET_TRACE_TBL = 0x13
};
enum {
IB_SA_ATTR_CLASS_PORTINFO = 0x01,
IB_SA_ATTR_NOTICE = 0x02,
IB_SA_ATTR_INFORM_INFO = 0x03,
IB_SA_ATTR_NODE_REC = 0x11,
IB_SA_ATTR_PORT_INFO_REC = 0x12,
IB_SA_ATTR_SL2VL_REC = 0x13,
IB_SA_ATTR_SWITCH_REC = 0x14,
IB_SA_ATTR_LINEAR_FDB_REC = 0x15,
IB_SA_ATTR_RANDOM_FDB_REC = 0x16,
IB_SA_ATTR_MCAST_FDB_REC = 0x17,
IB_SA_ATTR_SM_INFO_REC = 0x18,
IB_SA_ATTR_LINK_REC = 0x20,
IB_SA_ATTR_GUID_INFO_REC = 0x30,
IB_SA_ATTR_SERVICE_REC = 0x31,
IB_SA_ATTR_PARTITION_REC = 0x33,
IB_SA_ATTR_PATH_REC = 0x35,
IB_SA_ATTR_VL_ARB_REC = 0x36,
IB_SA_ATTR_MC_MEMBER_REC = 0x38,
IB_SA_ATTR_TRACE_REC = 0x39,
IB_SA_ATTR_MULTI_PATH_REC = 0x3a,
IB_SA_ATTR_SERVICE_ASSOC_REC = 0x3b,
IB_SA_ATTR_INFORM_INFO_REC = 0xf3
}; };
enum ib_sa_selector { enum ib_sa_selector {
......
/* /*
* Copyright (c) 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Intel Corporation. All rights reserved.
* *
* This software is available to you under a choice of one of two * This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU * licenses. You may choose to be licensed under the terms of the GNU
...@@ -37,7 +38,7 @@ ...@@ -37,7 +38,7 @@
#include <linux/types.h> #include <linux/types.h>
#define IB_USER_CM_ABI_VERSION 1 #define IB_USER_CM_ABI_VERSION 2
enum { enum {
IB_USER_CM_CMD_CREATE_ID, IB_USER_CM_CMD_CREATE_ID,
...@@ -60,6 +61,7 @@ enum { ...@@ -60,6 +61,7 @@ enum {
IB_USER_CM_CMD_SEND_SIDR_REP, IB_USER_CM_CMD_SEND_SIDR_REP,
IB_USER_CM_CMD_EVENT, IB_USER_CM_CMD_EVENT,
IB_USER_CM_CMD_INIT_QP_ATTR,
}; };
/* /*
* command ABI structures. * command ABI structures.
...@@ -71,6 +73,7 @@ struct ib_ucm_cmd_hdr { ...@@ -71,6 +73,7 @@ struct ib_ucm_cmd_hdr {
}; };
struct ib_ucm_create_id { struct ib_ucm_create_id {
__u64 uid;
__u64 response; __u64 response;
}; };
...@@ -79,9 +82,14 @@ struct ib_ucm_create_id_resp { ...@@ -79,9 +82,14 @@ struct ib_ucm_create_id_resp {
}; };
struct ib_ucm_destroy_id { struct ib_ucm_destroy_id {
__u64 response;
__u32 id; __u32 id;
}; };
struct ib_ucm_destroy_id_resp {
__u32 events_reported;
};
struct ib_ucm_attr_id { struct ib_ucm_attr_id {
__u64 response; __u64 response;
__u32 id; __u32 id;
...@@ -94,6 +102,64 @@ struct ib_ucm_attr_id_resp { ...@@ -94,6 +102,64 @@ struct ib_ucm_attr_id_resp {
__be32 remote_id; __be32 remote_id;
}; };
struct ib_ucm_init_qp_attr {
__u64 response;
__u32 id;
__u32 qp_state;
};
struct ib_ucm_ah_attr {
__u8 grh_dgid[16];
__u32 grh_flow_label;
__u16 dlid;
__u16 reserved;
__u8 grh_sgid_index;
__u8 grh_hop_limit;
__u8 grh_traffic_class;
__u8 sl;
__u8 src_path_bits;
__u8 static_rate;
__u8 is_global;
__u8 port_num;
};
struct ib_ucm_init_qp_attr_resp {
__u32 qp_attr_mask;
__u32 qp_state;
__u32 cur_qp_state;
__u32 path_mtu;
__u32 path_mig_state;
__u32 qkey;
__u32 rq_psn;
__u32 sq_psn;
__u32 dest_qp_num;
__u32 qp_access_flags;
struct ib_ucm_ah_attr ah_attr;
struct ib_ucm_ah_attr alt_ah_attr;
/* ib_qp_cap */
__u32 max_send_wr;
__u32 max_recv_wr;
__u32 max_send_sge;
__u32 max_recv_sge;
__u32 max_inline_data;
__u16 pkey_index;
__u16 alt_pkey_index;
__u8 en_sqd_async_notify;
__u8 sq_draining;
__u8 max_rd_atomic;
__u8 max_dest_rd_atomic;
__u8 min_rnr_timer;
__u8 port_num;
__u8 timeout;
__u8 retry_cnt;
__u8 rnr_retry;
__u8 alt_port_num;
__u8 alt_timeout;
};
struct ib_ucm_listen { struct ib_ucm_listen {
__be64 service_id; __be64 service_id;
__be64 service_mask; __be64 service_mask;
...@@ -157,6 +223,7 @@ struct ib_ucm_req { ...@@ -157,6 +223,7 @@ struct ib_ucm_req {
}; };
struct ib_ucm_rep { struct ib_ucm_rep {
__u64 uid;
__u64 data; __u64 data;
__u32 id; __u32 id;
__u32 qpn; __u32 qpn;
...@@ -232,7 +299,6 @@ struct ib_ucm_event_get { ...@@ -232,7 +299,6 @@ struct ib_ucm_event_get {
}; };
struct ib_ucm_req_event_resp { struct ib_ucm_req_event_resp {
__u32 listen_id;
/* device */ /* device */
/* port */ /* port */
struct ib_ucm_path_rec primary_path; struct ib_ucm_path_rec primary_path;
...@@ -287,7 +353,6 @@ struct ib_ucm_apr_event_resp { ...@@ -287,7 +353,6 @@ struct ib_ucm_apr_event_resp {
}; };
struct ib_ucm_sidr_req_event_resp { struct ib_ucm_sidr_req_event_resp {
__u32 listen_id;
/* device */ /* device */
/* port */ /* port */
__u16 pkey; __u16 pkey;
...@@ -307,6 +372,7 @@ struct ib_ucm_sidr_rep_event_resp { ...@@ -307,6 +372,7 @@ struct ib_ucm_sidr_rep_event_resp {
#define IB_UCM_PRES_ALTERNATE 0x08 #define IB_UCM_PRES_ALTERNATE 0x08
struct ib_ucm_event_resp { struct ib_ucm_event_resp {
__u64 uid;
__u32 id; __u32 id;
__u32 event; __u32 event;
__u32 present; __u32 present;
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* Increment this value if any changes that break userspace ABI * Increment this value if any changes that break userspace ABI
* compatibility are made. * compatibility are made.
*/ */
#define IB_USER_VERBS_ABI_VERSION 1 #define IB_USER_VERBS_ABI_VERSION 2
enum { enum {
IB_USER_VERBS_CMD_QUERY_PARAMS, IB_USER_VERBS_CMD_QUERY_PARAMS,
...@@ -292,7 +292,14 @@ struct ib_uverbs_create_cq_resp { ...@@ -292,7 +292,14 @@ struct ib_uverbs_create_cq_resp {
}; };
struct ib_uverbs_destroy_cq { struct ib_uverbs_destroy_cq {
__u64 response;
__u32 cq_handle; __u32 cq_handle;
__u32 reserved;
};
struct ib_uverbs_destroy_cq_resp {
__u32 comp_events_reported;
__u32 async_events_reported;
}; };
struct ib_uverbs_create_qp { struct ib_uverbs_create_qp {
...@@ -372,7 +379,13 @@ struct ib_uverbs_modify_qp_resp { ...@@ -372,7 +379,13 @@ struct ib_uverbs_modify_qp_resp {
}; };
struct ib_uverbs_destroy_qp { struct ib_uverbs_destroy_qp {
__u64 response;
__u32 qp_handle; __u32 qp_handle;
__u32 reserved;
};
struct ib_uverbs_destroy_qp_resp {
__u32 events_reported;
}; };
struct ib_uverbs_attach_mcast { struct ib_uverbs_attach_mcast {
...@@ -416,7 +429,13 @@ struct ib_uverbs_modify_srq { ...@@ -416,7 +429,13 @@ struct ib_uverbs_modify_srq {
}; };
struct ib_uverbs_destroy_srq { struct ib_uverbs_destroy_srq {
__u64 response;
__u32 srq_handle; __u32 srq_handle;
__u32 reserved;
};
struct ib_uverbs_destroy_srq_resp {
__u32 events_reported;
}; };
#endif /* IB_USER_VERBS_H */ #endif /* IB_USER_VERBS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment