Skip to content

Commit e2773c0

Browse files
Roland DreierLinus Torvalds
authored andcommitted
[PATCH] IB uverbs: core API extensions
First of a series of patches which add support for direct userspace access to InfiniBand hardware -- so-called "userspace verbs." I believe these patches are ready to merge, but a final review would be useful. These patches should incorporate all of the feedback from the discussion when I posted an earlier version back in April (see http://lkml.org/lkml/2005/4/4/267 for the start of the thread). In particular, memory pinned for use by userspace is accounted for in current->mm->vm_locked and requests to pin memory are checked against RLIMIT_MEMLOCK. This patch: Modify the ib_verbs.h header file with changes required for InfiniBand userspace verbs support. We add a few structures to keep track of userspace context, and extend the driver API so that low-level drivers know when they're creating resources that will be used from userspace. Signed-off-by: Roland Dreier <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 4048655 commit e2773c0

File tree

1 file changed

+106
-18
lines changed

1 file changed

+106
-18
lines changed

drivers/infiniband/include/ib_verbs.h

Lines changed: 106 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (c) 2004 Intel Corporation. All rights reserved.
55
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
66
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7+
* Copyright (c) 2005 Cisco Systems. All rights reserved.
78
*
89
* This software is available to you under a choice of one of two
910
* licenses. You may choose to be licensed under the terms of the GNU
@@ -41,7 +42,10 @@
4142

4243
#include <linux/types.h>
4344
#include <linux/device.h>
45+
4446
#include <asm/atomic.h>
47+
#include <asm/scatterlist.h>
48+
#include <asm/uaccess.h>
4549

4650
union ib_gid {
4751
u8 raw[16];
@@ -544,7 +548,7 @@ struct ib_send_wr {
544548
int num_sge;
545549
enum ib_wr_opcode opcode;
546550
int send_flags;
547-
u32 imm_data;
551+
__be32 imm_data;
548552
union {
549553
struct {
550554
u64 remote_addr;
@@ -618,29 +622,86 @@ struct ib_fmr_attr {
618622
u8 page_size;
619623
};
620624

625+
struct ib_ucontext {
626+
struct ib_device *device;
627+
struct list_head pd_list;
628+
struct list_head mr_list;
629+
struct list_head mw_list;
630+
struct list_head cq_list;
631+
struct list_head qp_list;
632+
struct list_head srq_list;
633+
struct list_head ah_list;
634+
spinlock_t lock;
635+
};
636+
637+
struct ib_uobject {
638+
u64 user_handle; /* handle given to us by userspace */
639+
struct ib_ucontext *context; /* associated user context */
640+
struct list_head list; /* link to context's list */
641+
u32 id; /* index into kernel idr */
642+
};
643+
644+
struct ib_umem {
645+
unsigned long user_base;
646+
unsigned long virt_base;
647+
size_t length;
648+
int offset;
649+
int page_size;
650+
int writable;
651+
struct list_head chunk_list;
652+
};
653+
654+
struct ib_umem_chunk {
655+
struct list_head list;
656+
int nents;
657+
int nmap;
658+
struct scatterlist page_list[0];
659+
};
660+
661+
struct ib_udata {
662+
void __user *inbuf;
663+
void __user *outbuf;
664+
size_t inlen;
665+
size_t outlen;
666+
};
667+
668+
#define IB_UMEM_MAX_PAGE_CHUNK \
669+
((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \
670+
((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \
671+
(void *) &((struct ib_umem_chunk *) 0)->page_list[0]))
672+
673+
struct ib_umem_object {
674+
struct ib_uobject uobject;
675+
struct ib_umem umem;
676+
};
677+
621678
struct ib_pd {
622-
struct ib_device *device;
623-
atomic_t usecnt; /* count all resources */
679+
struct ib_device *device;
680+
struct ib_uobject *uobject;
681+
atomic_t usecnt; /* count all resources */
624682
};
625683

626684
struct ib_ah {
627685
struct ib_device *device;
628686
struct ib_pd *pd;
687+
struct ib_uobject *uobject;
629688
};
630689

631690
typedef void (*ib_comp_handler)(struct ib_cq *cq, void *cq_context);
632691

633692
struct ib_cq {
634-
struct ib_device *device;
635-
ib_comp_handler comp_handler;
636-
void (*event_handler)(struct ib_event *, void *);
637-
void * cq_context;
638-
int cqe;
639-
atomic_t usecnt; /* count number of work queues */
693+
struct ib_device *device;
694+
struct ib_uobject *uobject;
695+
ib_comp_handler comp_handler;
696+
void (*event_handler)(struct ib_event *, void *);
697+
void * cq_context;
698+
int cqe;
699+
atomic_t usecnt; /* count number of work queues */
640700
};
641701

642702
struct ib_srq {
643703
struct ib_device *device;
704+
struct ib_uobject *uobject;
644705
struct ib_pd *pd;
645706
void *srq_context;
646707
atomic_t usecnt;
@@ -652,23 +713,26 @@ struct ib_qp {
652713
struct ib_cq *send_cq;
653714
struct ib_cq *recv_cq;
654715
struct ib_srq *srq;
716+
struct ib_uobject *uobject;
655717
void (*event_handler)(struct ib_event *, void *);
656718
void *qp_context;
657719
u32 qp_num;
658720
enum ib_qp_type qp_type;
659721
};
660722

661723
struct ib_mr {
662-
struct ib_device *device;
663-
struct ib_pd *pd;
664-
u32 lkey;
665-
u32 rkey;
666-
atomic_t usecnt; /* count number of MWs */
724+
struct ib_device *device;
725+
struct ib_pd *pd;
726+
struct ib_uobject *uobject;
727+
u32 lkey;
728+
u32 rkey;
729+
atomic_t usecnt; /* count number of MWs */
667730
};
668731

669732
struct ib_mw {
670733
struct ib_device *device;
671734
struct ib_pd *pd;
735+
struct ib_uobject *uobject;
672736
u32 rkey;
673737
};
674738

@@ -737,7 +801,14 @@ struct ib_device {
737801
int (*modify_port)(struct ib_device *device,
738802
u8 port_num, int port_modify_mask,
739803
struct ib_port_modify *port_modify);
740-
struct ib_pd * (*alloc_pd)(struct ib_device *device);
804+
struct ib_ucontext * (*alloc_ucontext)(struct ib_device *device,
805+
struct ib_udata *udata);
806+
int (*dealloc_ucontext)(struct ib_ucontext *context);
807+
int (*mmap)(struct ib_ucontext *context,
808+
struct vm_area_struct *vma);
809+
struct ib_pd * (*alloc_pd)(struct ib_device *device,
810+
struct ib_ucontext *context,
811+
struct ib_udata *udata);
741812
int (*dealloc_pd)(struct ib_pd *pd);
742813
struct ib_ah * (*create_ah)(struct ib_pd *pd,
743814
struct ib_ah_attr *ah_attr);
@@ -747,7 +818,8 @@ struct ib_device {
747818
struct ib_ah_attr *ah_attr);
748819
int (*destroy_ah)(struct ib_ah *ah);
749820
struct ib_qp * (*create_qp)(struct ib_pd *pd,
750-
struct ib_qp_init_attr *qp_init_attr);
821+
struct ib_qp_init_attr *qp_init_attr,
822+
struct ib_udata *udata);
751823
int (*modify_qp)(struct ib_qp *qp,
752824
struct ib_qp_attr *qp_attr,
753825
int qp_attr_mask);
@@ -762,8 +834,9 @@ struct ib_device {
762834
int (*post_recv)(struct ib_qp *qp,
763835
struct ib_recv_wr *recv_wr,
764836
struct ib_recv_wr **bad_recv_wr);
765-
struct ib_cq * (*create_cq)(struct ib_device *device,
766-
int cqe);
837+
struct ib_cq * (*create_cq)(struct ib_device *device, int cqe,
838+
struct ib_ucontext *context,
839+
struct ib_udata *udata);
767840
int (*destroy_cq)(struct ib_cq *cq);
768841
int (*resize_cq)(struct ib_cq *cq, int *cqe);
769842
int (*poll_cq)(struct ib_cq *cq, int num_entries,
@@ -780,6 +853,10 @@ struct ib_device {
780853
int num_phys_buf,
781854
int mr_access_flags,
782855
u64 *iova_start);
856+
struct ib_mr * (*reg_user_mr)(struct ib_pd *pd,
857+
struct ib_umem *region,
858+
int mr_access_flags,
859+
struct ib_udata *udata);
783860
int (*query_mr)(struct ib_mr *mr,
784861
struct ib_mr_attr *mr_attr);
785862
int (*dereg_mr)(struct ib_mr *mr);
@@ -817,6 +894,7 @@ struct ib_device {
817894
struct ib_mad *in_mad,
818895
struct ib_mad *out_mad);
819896

897+
struct module *owner;
820898
struct class_device class_dev;
821899
struct kobject ports_parent;
822900
struct list_head port_list;
@@ -852,6 +930,16 @@ void *ib_get_client_data(struct ib_device *device, struct ib_client *client);
852930
void ib_set_client_data(struct ib_device *device, struct ib_client *client,
853931
void *data);
854932

933+
static inline int ib_copy_from_udata(void *dest, struct ib_udata *udata, size_t len)
934+
{
935+
return copy_from_user(dest, udata->inbuf, len) ? -EFAULT : 0;
936+
}
937+
938+
static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len)
939+
{
940+
return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0;
941+
}
942+
855943
int ib_register_event_handler (struct ib_event_handler *event_handler);
856944
int ib_unregister_event_handler(struct ib_event_handler *event_handler);
857945
void ib_dispatch_event(struct ib_event *event);

0 commit comments

Comments
 (0)