diff options
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 3 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 214 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 13 | ||||
-rw-r--r-- | include/rdma/ib_verbs.h | 1 | ||||
-rw-r--r-- | include/uapi/rdma/ib_user_verbs.h | 89 |
5 files changed, 318 insertions, 2 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 0fcd7aa26fa2..ad9d1028102d 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -155,6 +155,7 @@ extern struct idr ib_uverbs_cq_idr; | |||
155 | extern struct idr ib_uverbs_qp_idr; | 155 | extern struct idr ib_uverbs_qp_idr; |
156 | extern struct idr ib_uverbs_srq_idr; | 156 | extern struct idr ib_uverbs_srq_idr; |
157 | extern struct idr ib_uverbs_xrcd_idr; | 157 | extern struct idr ib_uverbs_xrcd_idr; |
158 | extern struct idr ib_uverbs_rule_idr; | ||
158 | 159 | ||
159 | void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj); | 160 | void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj); |
160 | 161 | ||
@@ -215,5 +216,7 @@ IB_UVERBS_DECLARE_CMD(destroy_srq); | |||
215 | IB_UVERBS_DECLARE_CMD(create_xsrq); | 216 | IB_UVERBS_DECLARE_CMD(create_xsrq); |
216 | IB_UVERBS_DECLARE_CMD(open_xrcd); | 217 | IB_UVERBS_DECLARE_CMD(open_xrcd); |
217 | IB_UVERBS_DECLARE_CMD(close_xrcd); | 218 | IB_UVERBS_DECLARE_CMD(close_xrcd); |
219 | IB_UVERBS_DECLARE_CMD(create_flow); | ||
220 | IB_UVERBS_DECLARE_CMD(destroy_flow); | ||
218 | 221 | ||
219 | #endif /* UVERBS_H */ | 222 | #endif /* UVERBS_H */ |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b3c07b0c9f26..6e98df929e29 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -54,6 +54,7 @@ static struct uverbs_lock_class qp_lock_class = { .name = "QP-uobj" }; | |||
54 | static struct uverbs_lock_class ah_lock_class = { .name = "AH-uobj" }; | 54 | static struct uverbs_lock_class ah_lock_class = { .name = "AH-uobj" }; |
55 | static struct uverbs_lock_class srq_lock_class = { .name = "SRQ-uobj" }; | 55 | static struct uverbs_lock_class srq_lock_class = { .name = "SRQ-uobj" }; |
56 | static struct uverbs_lock_class xrcd_lock_class = { .name = "XRCD-uobj" }; | 56 | static struct uverbs_lock_class xrcd_lock_class = { .name = "XRCD-uobj" }; |
57 | static struct uverbs_lock_class rule_lock_class = { .name = "RULE-uobj" }; | ||
57 | 58 | ||
58 | #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ | 59 | #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ |
59 | do { \ | 60 | do { \ |
@@ -330,6 +331,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, | |||
330 | INIT_LIST_HEAD(&ucontext->srq_list); | 331 | INIT_LIST_HEAD(&ucontext->srq_list); |
331 | INIT_LIST_HEAD(&ucontext->ah_list); | 332 | INIT_LIST_HEAD(&ucontext->ah_list); |
332 | INIT_LIST_HEAD(&ucontext->xrcd_list); | 333 | INIT_LIST_HEAD(&ucontext->xrcd_list); |
334 | INIT_LIST_HEAD(&ucontext->rule_list); | ||
333 | ucontext->closing = 0; | 335 | ucontext->closing = 0; |
334 | 336 | ||
335 | resp.num_comp_vectors = file->device->num_comp_vectors; | 337 | resp.num_comp_vectors = file->device->num_comp_vectors; |
@@ -2587,6 +2589,218 @@ out_put: | |||
2587 | return ret ? ret : in_len; | 2589 | return ret ? ret : in_len; |
2588 | } | 2590 | } |
2589 | 2591 | ||
2592 | static int kern_spec_to_ib_spec(struct ib_kern_spec *kern_spec, | ||
2593 | union ib_flow_spec *ib_spec) | ||
2594 | { | ||
2595 | ib_spec->type = kern_spec->type; | ||
2596 | |||
2597 | switch (ib_spec->type) { | ||
2598 | case IB_FLOW_SPEC_ETH: | ||
2599 | ib_spec->eth.size = sizeof(struct ib_flow_spec_eth); | ||
2600 | if (ib_spec->eth.size != kern_spec->eth.size) | ||
2601 | return -EINVAL; | ||
2602 | memcpy(&ib_spec->eth.val, &kern_spec->eth.val, | ||
2603 | sizeof(struct ib_flow_eth_filter)); | ||
2604 | memcpy(&ib_spec->eth.mask, &kern_spec->eth.mask, | ||
2605 | sizeof(struct ib_flow_eth_filter)); | ||
2606 | break; | ||
2607 | case IB_FLOW_SPEC_IPV4: | ||
2608 | ib_spec->ipv4.size = sizeof(struct ib_flow_spec_ipv4); | ||
2609 | if (ib_spec->ipv4.size != kern_spec->ipv4.size) | ||
2610 | return -EINVAL; | ||
2611 | memcpy(&ib_spec->ipv4.val, &kern_spec->ipv4.val, | ||
2612 | sizeof(struct ib_flow_ipv4_filter)); | ||
2613 | memcpy(&ib_spec->ipv4.mask, &kern_spec->ipv4.mask, | ||
2614 | sizeof(struct ib_flow_ipv4_filter)); | ||
2615 | break; | ||
2616 | case IB_FLOW_SPEC_TCP: | ||
2617 | case IB_FLOW_SPEC_UDP: | ||
2618 | ib_spec->tcp_udp.size = sizeof(struct ib_flow_spec_tcp_udp); | ||
2619 | if (ib_spec->tcp_udp.size != kern_spec->tcp_udp.size) | ||
2620 | return -EINVAL; | ||
2621 | memcpy(&ib_spec->tcp_udp.val, &kern_spec->tcp_udp.val, | ||
2622 | sizeof(struct ib_flow_tcp_udp_filter)); | ||
2623 | memcpy(&ib_spec->tcp_udp.mask, &kern_spec->tcp_udp.mask, | ||
2624 | sizeof(struct ib_flow_tcp_udp_filter)); | ||
2625 | break; | ||
2626 | default: | ||
2627 | return -EINVAL; | ||
2628 | } | ||
2629 | return 0; | ||
2630 | } | ||
2631 | |||
2632 | ssize_t ib_uverbs_create_flow(struct ib_uverbs_file *file, | ||
2633 | const char __user *buf, int in_len, | ||
2634 | int out_len) | ||
2635 | { | ||
2636 | struct ib_uverbs_create_flow cmd; | ||
2637 | struct ib_uverbs_create_flow_resp resp; | ||
2638 | struct ib_uobject *uobj; | ||
2639 | struct ib_flow *flow_id; | ||
2640 | struct ib_kern_flow_attr *kern_flow_attr; | ||
2641 | struct ib_flow_attr *flow_attr; | ||
2642 | struct ib_qp *qp; | ||
2643 | int err = 0; | ||
2644 | void *kern_spec; | ||
2645 | void *ib_spec; | ||
2646 | int i; | ||
2647 | int kern_attr_size; | ||
2648 | |||
2649 | if (out_len < sizeof(resp)) | ||
2650 | return -ENOSPC; | ||
2651 | |||
2652 | if (copy_from_user(&cmd, buf, sizeof(cmd))) | ||
2653 | return -EFAULT; | ||
2654 | |||
2655 | if ((cmd.flow_attr.type == IB_FLOW_ATTR_SNIFFER && | ||
2656 | !capable(CAP_NET_ADMIN)) || !capable(CAP_NET_RAW)) | ||
2657 | return -EPERM; | ||
2658 | |||
2659 | if (cmd.flow_attr.num_of_specs) { | ||
2660 | kern_flow_attr = kmalloc(cmd.flow_attr.size, GFP_KERNEL); | ||
2661 | if (!kern_flow_attr) | ||
2662 | return -ENOMEM; | ||
2663 | |||
2664 | memcpy(kern_flow_attr, &cmd.flow_attr, sizeof(*kern_flow_attr)); | ||
2665 | kern_attr_size = cmd.flow_attr.size - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr_ex); | ||
2666 | if (copy_from_user(kern_flow_attr + 1, buf + sizeof(cmd), | ||
2667 | kern_attr_size)) { | ||
2668 | err = -EFAULT; | ||
2669 | goto err_free_attr; | ||
2670 | } | ||
2671 | } else { | ||
2672 | kern_flow_attr = &cmd.flow_attr; | ||
2673 | kern_attr_size = sizeof(cmd.flow_attr); | ||
2674 | } | ||
2675 | |||
2676 | uobj = kmalloc(sizeof(*uobj), GFP_KERNEL); | ||
2677 | if (!uobj) { | ||
2678 | err = -ENOMEM; | ||
2679 | goto err_free_attr; | ||
2680 | } | ||
2681 | init_uobj(uobj, 0, file->ucontext, &rule_lock_class); | ||
2682 | down_write(&uobj->mutex); | ||
2683 | |||
2684 | qp = idr_read_qp(cmd.qp_handle, file->ucontext); | ||
2685 | if (!qp) { | ||
2686 | err = -EINVAL; | ||
2687 | goto err_uobj; | ||
2688 | } | ||
2689 | |||
2690 | flow_attr = kmalloc(cmd.flow_attr.size, GFP_KERNEL); | ||
2691 | if (!flow_attr) { | ||
2692 | err = -ENOMEM; | ||
2693 | goto err_put; | ||
2694 | } | ||
2695 | |||
2696 | flow_attr->type = kern_flow_attr->type; | ||
2697 | flow_attr->priority = kern_flow_attr->priority; | ||
2698 | flow_attr->num_of_specs = kern_flow_attr->num_of_specs; | ||
2699 | flow_attr->port = kern_flow_attr->port; | ||
2700 | flow_attr->flags = kern_flow_attr->flags; | ||
2701 | flow_attr->size = sizeof(*flow_attr); | ||
2702 | |||
2703 | kern_spec = kern_flow_attr + 1; | ||
2704 | ib_spec = flow_attr + 1; | ||
2705 | for (i = 0; i < flow_attr->num_of_specs && kern_attr_size > 0; i++) { | ||
2706 | err = kern_spec_to_ib_spec(kern_spec, ib_spec); | ||
2707 | if (err) | ||
2708 | goto err_free; | ||
2709 | flow_attr->size += | ||
2710 | ((union ib_flow_spec *) ib_spec)->size; | ||
2711 | kern_attr_size -= ((struct ib_kern_spec *) kern_spec)->size; | ||
2712 | kern_spec += ((struct ib_kern_spec *) kern_spec)->size; | ||
2713 | ib_spec += ((union ib_flow_spec *) ib_spec)->size; | ||
2714 | } | ||
2715 | if (kern_attr_size) { | ||
2716 | pr_warn("create flow failed, %d bytes left from uverb cmd\n", | ||
2717 | kern_attr_size); | ||
2718 | goto err_free; | ||
2719 | } | ||
2720 | flow_id = ib_create_flow(qp, flow_attr, IB_FLOW_DOMAIN_USER); | ||
2721 | if (IS_ERR(flow_id)) { | ||
2722 | err = PTR_ERR(flow_id); | ||
2723 | goto err_free; | ||
2724 | } | ||
2725 | flow_id->qp = qp; | ||
2726 | flow_id->uobject = uobj; | ||
2727 | uobj->object = flow_id; | ||
2728 | |||
2729 | err = idr_add_uobj(&ib_uverbs_rule_idr, uobj); | ||
2730 | if (err) | ||
2731 | goto destroy_flow; | ||
2732 | |||
2733 | memset(&resp, 0, sizeof(resp)); | ||
2734 | resp.flow_handle = uobj->id; | ||
2735 | |||
2736 | if (copy_to_user((void __user *)(unsigned long) cmd.response, | ||
2737 | &resp, sizeof(resp))) { | ||
2738 | err = -EFAULT; | ||
2739 | goto err_copy; | ||
2740 | } | ||
2741 | |||
2742 | put_qp_read(qp); | ||
2743 | mutex_lock(&file->mutex); | ||
2744 | list_add_tail(&uobj->list, &file->ucontext->rule_list); | ||
2745 | mutex_unlock(&file->mutex); | ||
2746 | |||
2747 | uobj->live = 1; | ||
2748 | |||
2749 | up_write(&uobj->mutex); | ||
2750 | kfree(flow_attr); | ||
2751 | if (cmd.flow_attr.num_of_specs) | ||
2752 | kfree(kern_flow_attr); | ||
2753 | return in_len; | ||
2754 | err_copy: | ||
2755 | idr_remove_uobj(&ib_uverbs_rule_idr, uobj); | ||
2756 | destroy_flow: | ||
2757 | ib_destroy_flow(flow_id); | ||
2758 | err_free: | ||
2759 | kfree(flow_attr); | ||
2760 | err_put: | ||
2761 | put_qp_read(qp); | ||
2762 | err_uobj: | ||
2763 | put_uobj_write(uobj); | ||
2764 | err_free_attr: | ||
2765 | if (cmd.flow_attr.num_of_specs) | ||
2766 | kfree(kern_flow_attr); | ||
2767 | return err; | ||
2768 | } | ||
2769 | |||
2770 | ssize_t ib_uverbs_destroy_flow(struct ib_uverbs_file *file, | ||
2771 | const char __user *buf, int in_len, | ||
2772 | int out_len) { | ||
2773 | struct ib_uverbs_destroy_flow cmd; | ||
2774 | struct ib_flow *flow_id; | ||
2775 | struct ib_uobject *uobj; | ||
2776 | int ret; | ||
2777 | |||
2778 | if (copy_from_user(&cmd, buf, sizeof(cmd))) | ||
2779 | return -EFAULT; | ||
2780 | |||
2781 | uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle, | ||
2782 | file->ucontext); | ||
2783 | if (!uobj) | ||
2784 | return -EINVAL; | ||
2785 | flow_id = uobj->object; | ||
2786 | |||
2787 | ret = ib_destroy_flow(flow_id); | ||
2788 | if (!ret) | ||
2789 | uobj->live = 0; | ||
2790 | |||
2791 | put_uobj_write(uobj); | ||
2792 | |||
2793 | idr_remove_uobj(&ib_uverbs_rule_idr, uobj); | ||
2794 | |||
2795 | mutex_lock(&file->mutex); | ||
2796 | list_del(&uobj->list); | ||
2797 | mutex_unlock(&file->mutex); | ||
2798 | |||
2799 | put_uobj(uobj); | ||
2800 | |||
2801 | return ret ? ret : in_len; | ||
2802 | } | ||
2803 | |||
2590 | static int __uverbs_create_xsrq(struct ib_uverbs_file *file, | 2804 | static int __uverbs_create_xsrq(struct ib_uverbs_file *file, |
2591 | struct ib_uverbs_create_xsrq *cmd, | 2805 | struct ib_uverbs_create_xsrq *cmd, |
2592 | struct ib_udata *udata) | 2806 | struct ib_udata *udata) |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index e4e7b2449d19..75ad86c4abf8 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -73,6 +73,7 @@ DEFINE_IDR(ib_uverbs_cq_idr); | |||
73 | DEFINE_IDR(ib_uverbs_qp_idr); | 73 | DEFINE_IDR(ib_uverbs_qp_idr); |
74 | DEFINE_IDR(ib_uverbs_srq_idr); | 74 | DEFINE_IDR(ib_uverbs_srq_idr); |
75 | DEFINE_IDR(ib_uverbs_xrcd_idr); | 75 | DEFINE_IDR(ib_uverbs_xrcd_idr); |
76 | DEFINE_IDR(ib_uverbs_rule_idr); | ||
76 | 77 | ||
77 | static DEFINE_SPINLOCK(map_lock); | 78 | static DEFINE_SPINLOCK(map_lock); |
78 | static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); | 79 | static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); |
@@ -113,7 +114,9 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, | |||
113 | [IB_USER_VERBS_CMD_OPEN_XRCD] = ib_uverbs_open_xrcd, | 114 | [IB_USER_VERBS_CMD_OPEN_XRCD] = ib_uverbs_open_xrcd, |
114 | [IB_USER_VERBS_CMD_CLOSE_XRCD] = ib_uverbs_close_xrcd, | 115 | [IB_USER_VERBS_CMD_CLOSE_XRCD] = ib_uverbs_close_xrcd, |
115 | [IB_USER_VERBS_CMD_CREATE_XSRQ] = ib_uverbs_create_xsrq, | 116 | [IB_USER_VERBS_CMD_CREATE_XSRQ] = ib_uverbs_create_xsrq, |
116 | [IB_USER_VERBS_CMD_OPEN_QP] = ib_uverbs_open_qp | 117 | [IB_USER_VERBS_CMD_OPEN_QP] = ib_uverbs_open_qp, |
118 | [IB_USER_VERBS_CMD_CREATE_FLOW] = ib_uverbs_create_flow, | ||
119 | [IB_USER_VERBS_CMD_DESTROY_FLOW] = ib_uverbs_destroy_flow | ||
117 | }; | 120 | }; |
118 | 121 | ||
119 | static void ib_uverbs_add_one(struct ib_device *device); | 122 | static void ib_uverbs_add_one(struct ib_device *device); |
@@ -212,6 +215,14 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, | |||
212 | kfree(uobj); | 215 | kfree(uobj); |
213 | } | 216 | } |
214 | 217 | ||
218 | list_for_each_entry_safe(uobj, tmp, &context->rule_list, list) { | ||
219 | struct ib_flow *flow_id = uobj->object; | ||
220 | |||
221 | idr_remove_uobj(&ib_uverbs_rule_idr, uobj); | ||
222 | ib_destroy_flow(flow_id); | ||
223 | kfree(uobj); | ||
224 | } | ||
225 | |||
215 | list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) { | 226 | list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) { |
216 | struct ib_qp *qp = uobj->object; | 227 | struct ib_qp *qp = uobj->object; |
217 | struct ib_uqp_object *uqp = | 228 | struct ib_uqp_object *uqp = |
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 6f874b00491a..274205d4df97 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h | |||
@@ -954,6 +954,7 @@ struct ib_ucontext { | |||
954 | struct list_head srq_list; | 954 | struct list_head srq_list; |
955 | struct list_head ah_list; | 955 | struct list_head ah_list; |
956 | struct list_head xrcd_list; | 956 | struct list_head xrcd_list; |
957 | struct list_head rule_list; | ||
957 | int closing; | 958 | int closing; |
958 | }; | 959 | }; |
959 | 960 | ||
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h index 61535aa0a62e..0b233c56b0e4 100644 --- a/include/uapi/rdma/ib_user_verbs.h +++ b/include/uapi/rdma/ib_user_verbs.h | |||
@@ -86,7 +86,9 @@ enum { | |||
86 | IB_USER_VERBS_CMD_OPEN_XRCD, | 86 | IB_USER_VERBS_CMD_OPEN_XRCD, |
87 | IB_USER_VERBS_CMD_CLOSE_XRCD, | 87 | IB_USER_VERBS_CMD_CLOSE_XRCD, |
88 | IB_USER_VERBS_CMD_CREATE_XSRQ, | 88 | IB_USER_VERBS_CMD_CREATE_XSRQ, |
89 | IB_USER_VERBS_CMD_OPEN_QP | 89 | IB_USER_VERBS_CMD_OPEN_QP, |
90 | IB_USER_VERBS_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD, | ||
91 | IB_USER_VERBS_CMD_DESTROY_FLOW | ||
90 | }; | 92 | }; |
91 | 93 | ||
92 | /* | 94 | /* |
@@ -694,6 +696,91 @@ struct ib_uverbs_detach_mcast { | |||
694 | __u64 driver_data[0]; | 696 | __u64 driver_data[0]; |
695 | }; | 697 | }; |
696 | 698 | ||
699 | struct ib_kern_eth_filter { | ||
700 | __u8 dst_mac[6]; | ||
701 | __u8 src_mac[6]; | ||
702 | __be16 ether_type; | ||
703 | __be16 vlan_tag; | ||
704 | }; | ||
705 | |||
706 | struct ib_kern_spec_eth { | ||
707 | __u32 type; | ||
708 | __u16 size; | ||
709 | __u16 reserved; | ||
710 | struct ib_kern_eth_filter val; | ||
711 | struct ib_kern_eth_filter mask; | ||
712 | }; | ||
713 | |||
714 | struct ib_kern_ipv4_filter { | ||
715 | __be32 src_ip; | ||
716 | __be32 dst_ip; | ||
717 | }; | ||
718 | |||
719 | struct ib_kern_spec_ipv4 { | ||
720 | __u32 type; | ||
721 | __u16 size; | ||
722 | __u16 reserved; | ||
723 | struct ib_kern_ipv4_filter val; | ||
724 | struct ib_kern_ipv4_filter mask; | ||
725 | }; | ||
726 | |||
727 | struct ib_kern_tcp_udp_filter { | ||
728 | __be16 dst_port; | ||
729 | __be16 src_port; | ||
730 | }; | ||
731 | |||
732 | struct ib_kern_spec_tcp_udp { | ||
733 | __u32 type; | ||
734 | __u16 size; | ||
735 | __u16 reserved; | ||
736 | struct ib_kern_tcp_udp_filter val; | ||
737 | struct ib_kern_tcp_udp_filter mask; | ||
738 | }; | ||
739 | |||
740 | struct ib_kern_spec { | ||
741 | union { | ||
742 | struct { | ||
743 | __u32 type; | ||
744 | __u16 size; | ||
745 | __u16 reserved; | ||
746 | }; | ||
747 | struct ib_kern_spec_eth eth; | ||
748 | struct ib_kern_spec_ipv4 ipv4; | ||
749 | struct ib_kern_spec_tcp_udp tcp_udp; | ||
750 | }; | ||
751 | }; | ||
752 | |||
753 | struct ib_kern_flow_attr { | ||
754 | __u32 type; | ||
755 | __u16 size; | ||
756 | __u16 priority; | ||
757 | __u8 num_of_specs; | ||
758 | __u8 reserved[2]; | ||
759 | __u8 port; | ||
760 | __u32 flags; | ||
761 | /* Following are the optional layers according to user request | ||
762 | * struct ib_flow_spec_xxx | ||
763 | * struct ib_flow_spec_yyy | ||
764 | */ | ||
765 | }; | ||
766 | |||
767 | struct ib_uverbs_create_flow { | ||
768 | __u32 comp_mask; | ||
769 | __u64 response; | ||
770 | __u32 qp_handle; | ||
771 | struct ib_kern_flow_attr flow_attr; | ||
772 | }; | ||
773 | |||
774 | struct ib_uverbs_create_flow_resp { | ||
775 | __u32 comp_mask; | ||
776 | __u32 flow_handle; | ||
777 | }; | ||
778 | |||
779 | struct ib_uverbs_destroy_flow { | ||
780 | __u32 comp_mask; | ||
781 | __u32 flow_handle; | ||
782 | }; | ||
783 | |||
697 | struct ib_uverbs_create_srq { | 784 | struct ib_uverbs_create_srq { |
698 | __u64 response; | 785 | __u64 response; |
699 | __u64 user_handle; | 786 | __u64 user_handle; |