@@ -255,6 +255,17 @@ static void put_wq_read(struct ib_wq *wq)
255
255
put_uobj_read (wq -> uobject );
256
256
}
257
257
258
+ static struct ib_rwq_ind_table * idr_read_rwq_indirection_table (int ind_table_handle ,
259
+ struct ib_ucontext * context )
260
+ {
261
+ return idr_read_obj (& ib_uverbs_rwq_ind_tbl_idr , ind_table_handle , context , 0 );
262
+ }
263
+
264
+ static void put_rwq_indirection_table_read (struct ib_rwq_ind_table * ind_table )
265
+ {
266
+ put_uobj_read (ind_table -> uobject );
267
+ }
268
+
258
269
static struct ib_qp * idr_write_qp (int qp_handle , struct ib_ucontext * context )
259
270
{
260
271
struct ib_uobject * uobj ;
@@ -1761,9 +1772,11 @@ static int create_qp(struct ib_uverbs_file *file,
1761
1772
struct ib_srq * srq = NULL ;
1762
1773
struct ib_qp * qp ;
1763
1774
char * buf ;
1764
- struct ib_qp_init_attr attr ;
1775
+ struct ib_qp_init_attr attr = {} ;
1765
1776
struct ib_uverbs_ex_create_qp_resp resp ;
1766
1777
int ret ;
1778
+ struct ib_rwq_ind_table * ind_tbl = NULL ;
1779
+ bool has_sq = true;
1767
1780
1768
1781
if (cmd -> qp_type == IB_QPT_RAW_PACKET && !capable (CAP_NET_RAW ))
1769
1782
return - EPERM ;
@@ -1775,6 +1788,32 @@ static int create_qp(struct ib_uverbs_file *file,
1775
1788
init_uobj (& obj -> uevent .uobject , cmd -> user_handle , file -> ucontext ,
1776
1789
& qp_lock_class );
1777
1790
down_write (& obj -> uevent .uobject .mutex );
1791
+ if (cmd_sz >= offsetof(typeof (* cmd ), rwq_ind_tbl_handle ) +
1792
+ sizeof (cmd -> rwq_ind_tbl_handle ) &&
1793
+ (cmd -> comp_mask & IB_UVERBS_CREATE_QP_MASK_IND_TABLE )) {
1794
+ ind_tbl = idr_read_rwq_indirection_table (cmd -> rwq_ind_tbl_handle ,
1795
+ file -> ucontext );
1796
+ if (!ind_tbl ) {
1797
+ ret = - EINVAL ;
1798
+ goto err_put ;
1799
+ }
1800
+
1801
+ attr .rwq_ind_tbl = ind_tbl ;
1802
+ }
1803
+
1804
+ if ((cmd_sz >= offsetof(typeof (* cmd ), reserved1 ) +
1805
+ sizeof (cmd -> reserved1 )) && cmd -> reserved1 ) {
1806
+ ret = - EOPNOTSUPP ;
1807
+ goto err_put ;
1808
+ }
1809
+
1810
+ if (ind_tbl && (cmd -> max_recv_wr || cmd -> max_recv_sge || cmd -> is_srq )) {
1811
+ ret = - EINVAL ;
1812
+ goto err_put ;
1813
+ }
1814
+
1815
+ if (ind_tbl && !cmd -> max_send_wr )
1816
+ has_sq = false;
1778
1817
1779
1818
if (cmd -> qp_type == IB_QPT_XRC_TGT ) {
1780
1819
xrcd = idr_read_xrcd (cmd -> pd_handle , file -> ucontext ,
@@ -1798,20 +1837,24 @@ static int create_qp(struct ib_uverbs_file *file,
1798
1837
}
1799
1838
}
1800
1839
1801
- if (cmd -> recv_cq_handle != cmd -> send_cq_handle ) {
1802
- rcq = idr_read_cq (cmd -> recv_cq_handle ,
1803
- file -> ucontext , 0 );
1804
- if (!rcq ) {
1805
- ret = - EINVAL ;
1806
- goto err_put ;
1840
+ if (!ind_tbl ) {
1841
+ if (cmd -> recv_cq_handle != cmd -> send_cq_handle ) {
1842
+ rcq = idr_read_cq (cmd -> recv_cq_handle ,
1843
+ file -> ucontext , 0 );
1844
+ if (!rcq ) {
1845
+ ret = - EINVAL ;
1846
+ goto err_put ;
1847
+ }
1807
1848
}
1808
1849
}
1809
1850
}
1810
1851
1811
- scq = idr_read_cq (cmd -> send_cq_handle , file -> ucontext , !!rcq );
1812
- rcq = rcq ?: scq ;
1852
+ if (has_sq )
1853
+ scq = idr_read_cq (cmd -> send_cq_handle , file -> ucontext , !!rcq );
1854
+ if (!ind_tbl )
1855
+ rcq = rcq ?: scq ;
1813
1856
pd = idr_read_pd (cmd -> pd_handle , file -> ucontext );
1814
- if (!pd || !scq ) {
1857
+ if (!pd || ( !scq && has_sq ) ) {
1815
1858
ret = - EINVAL ;
1816
1859
goto err_put ;
1817
1860
}
@@ -1878,16 +1921,20 @@ static int create_qp(struct ib_uverbs_file *file,
1878
1921
qp -> send_cq = attr .send_cq ;
1879
1922
qp -> recv_cq = attr .recv_cq ;
1880
1923
qp -> srq = attr .srq ;
1924
+ qp -> rwq_ind_tbl = ind_tbl ;
1881
1925
qp -> event_handler = attr .event_handler ;
1882
1926
qp -> qp_context = attr .qp_context ;
1883
1927
qp -> qp_type = attr .qp_type ;
1884
1928
atomic_set (& qp -> usecnt , 0 );
1885
1929
atomic_inc (& pd -> usecnt );
1886
- atomic_inc (& attr .send_cq -> usecnt );
1930
+ if (attr .send_cq )
1931
+ atomic_inc (& attr .send_cq -> usecnt );
1887
1932
if (attr .recv_cq )
1888
1933
atomic_inc (& attr .recv_cq -> usecnt );
1889
1934
if (attr .srq )
1890
1935
atomic_inc (& attr .srq -> usecnt );
1936
+ if (ind_tbl )
1937
+ atomic_inc (& ind_tbl -> usecnt );
1891
1938
}
1892
1939
qp -> uobject = & obj -> uevent .uobject ;
1893
1940
@@ -1927,6 +1974,8 @@ static int create_qp(struct ib_uverbs_file *file,
1927
1974
put_cq_read (rcq );
1928
1975
if (srq )
1929
1976
put_srq_read (srq );
1977
+ if (ind_tbl )
1978
+ put_rwq_indirection_table_read (ind_tbl );
1930
1979
1931
1980
mutex_lock (& file -> mutex );
1932
1981
list_add_tail (& obj -> uevent .uobject .list , & file -> ucontext -> qp_list );
@@ -1954,6 +2003,8 @@ static int create_qp(struct ib_uverbs_file *file,
1954
2003
put_cq_read (rcq );
1955
2004
if (srq )
1956
2005
put_srq_read (srq );
2006
+ if (ind_tbl )
2007
+ put_rwq_indirection_table_read (ind_tbl );
1957
2008
1958
2009
put_uobj_write (& obj -> uevent .uobject );
1959
2010
return ret ;
@@ -2047,7 +2098,7 @@ int ib_uverbs_ex_create_qp(struct ib_uverbs_file *file,
2047
2098
if (err )
2048
2099
return err ;
2049
2100
2050
- if (cmd .comp_mask )
2101
+ if (cmd .comp_mask & ~ IB_UVERBS_CREATE_QP_SUP_COMP_MASK )
2051
2102
return - EINVAL ;
2052
2103
2053
2104
if (cmd .reserved )
0 commit comments