[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#930801: unblock: rdma-core/22.3-1



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Hi,

rdma-core is maintained by the Linux RDMA group. It follows the Linux
kernel release schedule and concepts. Upstream backports fixes to their
stable branches. We have currently rdma-core 22.1-1 in Debian
unstable/testing. Upstream released 22.3 which contains only bug fixes.

I prepared an updated package 22.3-1 (patch attached). Before uploading
anything, I like to hear your opinion: Is this change okay for buster,
should I wait for the release, or better keep that update out of buster?

unblock rdma-core/22.3-1

-- 
Benjamin Drung
System Developer
Debian & Ubuntu Developer

1&1 IONOS Cloud GmbH | Greifswalder Str. 207 | 10405 Berlin | Germany
E-mail: benjamin.drung@cloud.ionos.com | Web: www.ionos.de

Head Office: Berlin, Germany
District Court Berlin Charlottenburg, Registration number: HRB 125506 B
Executive Management: Christoph Steffens, Matthias Steinberg, Achim
Weiss

Member of United Internet
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8310ec6c..db291328 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -65,7 +65,7 @@ endif()
 set(PACKAGE_NAME "RDMA")
 
 # See Documentation/versioning.md
-set(PACKAGE_VERSION "22.1")
+set(PACKAGE_VERSION "22.3")
 # When this is changed the values in these files need changing too:
 #   debian/control
 #   debian/libibverbs1.symbols
@@ -360,23 +360,23 @@ else()
   set(HAVE_FULL_SYMBOL_VERSIONS 1)
 endif()
 
-if (${NO_PYVERBS})
-  set(CYTHON_EXECUTABLE "")
-else ()
-  # Look for Python. We prefer some variant of python 3 if the system has it.
-  FIND_PACKAGE(PythonInterp 3 QUIET)
-  if (NOT ${PythonInterp_FOUND})
-    FIND_PACKAGE(PythonInterp REQUIRED)
-  endif()
-  FIND_PACKAGE(cython)
-endif()
-
 # Look for Python. We prefer some variant of python 3 if the system has it.
 FIND_PACKAGE(PythonInterp 3 QUIET)
-if (NOT ${PythonInterp_FOUND})
+if (PythonInterp_FOUND)
+  # pyverbs can only use python3:
+  if (NO_PYVERBS)
+    set(CYTHON_EXECUTABLE "")
+  else()
+    FIND_PACKAGE(cython)
+  endif()
+else()
+  # But we still must have python (be it 2) for the build process:
   FIND_PACKAGE(PythonInterp REQUIRED)
+  set(CYTHON_EXECUTABLE "")
 endif()
+
 # A cython & python-devel installation that matches our selected interpreter.
+
 if (CYTHON_EXECUTABLE)
  # cmake has really bad logic here, if PythonIterp has been run it tries to
  # find a matching -devel installation but will happily return a non-matching
diff --git a/buildlib/RDMA_BuildType.cmake b/buildlib/RDMA_BuildType.cmake
index 0951edad..17206f51 100644
--- a/buildlib/RDMA_BuildType.cmake
+++ b/buildlib/RDMA_BuildType.cmake
@@ -8,7 +8,7 @@ function(RDMA_BuildType)
   # in performance contexts it doesn't make much sense to have the default build
   # turn off the optimizer.
   if(NOT CMAKE_BUILD_TYPE)
-    set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE String
+	  set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
       "Options are ${build_types}"
       FORCE
       )
diff --git a/buildlib/cbuild b/buildlib/cbuild
index 9ced0de6..15095d0c 100755
--- a/buildlib/cbuild
+++ b/buildlib/cbuild
@@ -641,10 +641,6 @@ def run_deb_build(args,env):
             "-e","DEB_BUILD_OPTIONS=parallel=%u"%(multiprocessing.cpu_count()),
         ];
 
-        if not env.build_pyverbs:
-            opts.append("-e");
-            opts.append("EXTRA_CMAKE_FLAGS=%s"%(' '.join(["-DNO_PYVERBS=1"])));
-
         # Create a go.py that will let us run the compilation as the user and
         # then switch to root only for the packaging step.
         with open(os.path.join(tmpdir,"go.py"),"w") as F:
diff --git a/buildlib/check-build b/buildlib/check-build
index 5ae0cc1c..348b0590 100755
--- a/buildlib/check-build
+++ b/buildlib/check-build
@@ -14,6 +14,7 @@ import copy
 import shlex
 import pipes
 from contextlib import contextmanager;
+from distutils.version import LooseVersion;
 
 def get_src_dir():
     """Get the source directory using git"""
@@ -106,7 +107,7 @@ def check_lib_symver(args,fn):
                 private,args.PACKAGE_VERSION));
 
     syms = list(syms - private);
-    syms.sort(key=lambda x:re.split('[._]',x));
+    syms.sort(key=LooseVersion)
     if newest_symver != syms[-1]:
         raise ValueError("Symbol version %r implied by filename %r not the newest in ELF (%r)"%(
             newest_symver,fn,syms));
diff --git a/buildlib/package-build-test b/buildlib/package-build-test
index 46a1cf6f..29c17838 100755
--- a/buildlib/package-build-test
+++ b/buildlib/package-build-test
@@ -11,7 +11,7 @@ if [ -e "/.dockerenv" ] || (grep -q docker /proc/self/cgroup &>/dev/null); then
        exit 0
 fi
 
-for OS in centos7 tumbleweed
+for OS in centos7 leap
 do
 	echo
 	echo "Checking package build for ${OS} ...."
diff --git a/debian/changelog b/debian/changelog
index 1b67953d..9f805206 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+rdma-core (22.3-1) unstable; urgency=medium
+
+  * New upstream bugfix release.
+
+ -- Benjamin Drung <benjamin.drung@cloud.ionos.com>  Thu, 20 Jun 2019 13:28:44 +0200
+
 rdma-core (22.1-1) unstable; urgency=medium
 
   * New upstream bugfix release.
diff --git a/debian/rules b/debian/rules
index f5e507f8..c35d252a 100755
--- a/debian/rules
+++ b/debian/rules
@@ -37,14 +37,15 @@ DH_AUTO_CONFIGURE := "--" \
 		     $(EXTRA_CMAKE_FLAGS)
 
 override_dh_auto_configure:
-ifeq ($(EXTRA_CMAKE_FLAGS), -DNO_PYVERBS=1)
-	dh_auto_configure $(DH_AUTO_CONFIGURE)
-else
-	dh_auto_configure $(DH_AUTO_CONFIGURE) \
-		        -DNO_PYVERBS=0 \
-			-DPYTHON_EXECUTABLE:PATH=/usr/bin/python3 \
-			-DCMAKE_INSTALL_PYTHON_ARCH_LIB:PATH=/usr/lib/python3/dist-packages
-endif
+	if [ -e /usr/bin/python3 ]; then \
+		dh_auto_configure $(DH_AUTO_CONFIGURE) \
+				-DPYTHON_EXECUTABLE:PATH=/usr/bin/python3 \
+				-DCMAKE_INSTALL_PYTHON_ARCH_LIB:PATH=/usr/lib/python3/dist-packages; \
+	else \
+		dh_auto_configure $(DH_AUTO_CONFIGURE) \
+			        -DNO_PYVERBS=1; \
+	fi
+
 
 override_dh_auto_build:
 	ninja -C build-deb -v
@@ -71,6 +72,13 @@ ifeq ($(EXTRA_CMAKE_FLAGS), -DNO_PYVERBS=1)
 	INST_EXCLUDE := $(INST_EXCLUDE) "usr/lib/python3/dist-packages/pyverbs"
 endif
 INST_EXCLUDE := $(addprefix -X,$(INST_EXCLUDE))
+override_dh_install:
+	if [ -e build-deb/python/pyverbs/__init__.py ]; then \
+		dh_install; \
+	else \
+		dh_install -Npython3-pyverbs --remaining-packages; \
+	fi
+
 override_dh_missing:
 	dh_missing --fail-missing $(INST_EXCLUDE)
 
@@ -98,13 +106,6 @@ override_dh_strip:
 	dh_strip -plibrdmacm1 --dbgsym-migration='librdmacm1-dbg (<< 15)'
 	dh_strip --remaining-packages
 
-override_dh_builddeb:
-ifeq ($(EXTRA_CMAKE_FLAGS), -DNO_PYVERBS=1)
-	dh_builddeb -Npython3-pyverbs --remaining-packages
-else
-	dh_builddeb --remaining-package
-endif
-
 # Upstream encourages the use of 'build' as the developer build output
 # directory, allow that directory to be present and still allow dh to work.
 .PHONY: build
diff --git a/ibacm/src/libacm.c b/ibacm/src/libacm.c
index 1d9d7145..e50fbf43 100644
--- a/ibacm/src/libacm.c
+++ b/ibacm/src/libacm.c
@@ -56,7 +56,7 @@ static void acm_set_server_port(void)
 	}
 }
 
-int ib_acm_connect(char *dest)
+static int ib_acm_connect_open(char *dest)
 {
 	struct addrinfo hint, *res;
 	int ret;
@@ -64,67 +64,72 @@ int ib_acm_connect(char *dest)
 	acm_set_server_port();
 	memset(&hint, 0, sizeof hint);
 
-	if (dest && *dest != '/') {
-		hint.ai_family = AF_INET;
-		hint.ai_family = AF_UNSPEC;
-
-		ret = getaddrinfo(dest, NULL, &hint, &res);
-		if (ret)
-			return ret;
-
-		sock = socket(res->ai_family, res->ai_socktype,
-			      res->ai_protocol);
-		if (sock == -1) {
-			ret = errno;
-			goto err1;
-		}
+	hint.ai_family = AF_UNSPEC;
+	hint.ai_protocol = IPPROTO_TCP;
 
-		((struct sockaddr_in *) res->ai_addr)->sin_port =
-			htobe16(server_port);
-		ret = connect(sock, res->ai_addr, res->ai_addrlen);
-		if (ret)
-			goto err2;
+	ret = getaddrinfo(dest, NULL, &hint, &res);
+	if (ret)
+		return ret;
 
-		freeaddrinfo(res);
+	sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+	if (sock == -1) {
+		ret = errno;
+		goto freeaddr;
+	}
 
-err2:
+	((struct sockaddr_in *) res->ai_addr)->sin_port = htobe16(server_port);
+	ret = connect(sock, res->ai_addr, res->ai_addrlen);
+	if (ret) {
 		close(sock);
 		sock = -1;
-err1:
-		freeaddrinfo(res);
-	} else {
-		struct sockaddr_un addr;
-
-		addr.sun_family = AF_UNIX;
-		if (dest) {
-			if (snprintf(addr.sun_path, sizeof(addr.sun_path),
-				     "%s", dest) >= sizeof(addr.sun_path)) {
-				errno = ENAMETOOLONG;
-				return errno;
-			}
-		} else {
-			BUILD_ASSERT(sizeof(IBACM_IBACME_SERVER_PATH) <=
-				     sizeof(addr.sun_path));
-			strcpy(addr.sun_path, IBACM_IBACME_SERVER_PATH);
-		}
+	}
 
-		sock = socket(AF_UNIX, SOCK_STREAM, 0);
-		if (sock < 0)
-			return errno;
+freeaddr:
+	freeaddrinfo(res);
+	return ret;
+}
 
-		if (connect(sock,
-			    (struct sockaddr *)&addr, sizeof(addr)) != 0) {
-			ret = errno;
-			close(sock);
-			sock = -1;
-			errno = ret;
-			return ret;
+static int ib_acm_connect_unix(char *dest)
+{
+	struct sockaddr_un addr;
+	int ret;
+
+	addr.sun_family = AF_UNIX;
+	if (dest) {
+		if (snprintf(addr.sun_path, sizeof(addr.sun_path),
+			     "%s", dest) >= sizeof(addr.sun_path)) {
+			errno = ENAMETOOLONG;
+			return errno;
 		}
+	} else {
+		BUILD_ASSERT(sizeof(IBACM_IBACME_SERVER_PATH) <=
+			     sizeof(addr.sun_path));
+		strcpy(addr.sun_path, IBACM_IBACME_SERVER_PATH);
+	}
+
+	sock = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (sock < 0)
+		return errno;
+
+	if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
+		ret = errno;
+		close(sock);
+		sock = -1;
+		errno = ret;
+		return ret;
 	}
 
 	return 0;
 }
 
+int ib_acm_connect(char *dest)
+{
+	if (dest && *dest == '/')
+		return ib_acm_connect_unix(dest);
+
+	return ib_acm_connect_open(dest);
+}
+
 void ib_acm_disconnect(void)
 {
 	if (sock != -1) {
diff --git a/libibverbs/cmd.c b/libibverbs/cmd.c
index 34c71e56..5817c598 100644
--- a/libibverbs/cmd.c
+++ b/libibverbs/cmd.c
@@ -1854,6 +1854,7 @@ int ibv_cmd_create_rwq_ind_table(struct ibv_context *context,
 	cmd_size = sizeof(*cmd) + num_tbl_entries * sizeof(cmd->wq_handles[0]);
 	cmd_size = (cmd_size + 7) / 8 * 8;
 	cmd = alloca(cmd_size);
+	memset(cmd, 0, cmd_size);
 
 	for (i = 0; i < num_tbl_entries; i++)
 		cmd->wq_handles[i] = init_attr->ind_tbl[i]->handle;
diff --git a/libibverbs/cmd_ioctl.c b/libibverbs/cmd_ioctl.c
index 82ef2cd7..2a46c49c 100644
--- a/libibverbs/cmd_ioctl.c
+++ b/libibverbs/cmd_ioctl.c
@@ -79,7 +79,6 @@ static void prepare_attrs(struct ibv_command_buffer *cmd)
 	}
 
 	cmd->hdr.num_attrs = end - cmd->hdr.attrs;
-	cmd->last_attr = end;
 
 	/*
 	 * We keep the in UHW uninlined until directly before sending to
@@ -113,7 +112,7 @@ static void finalize_attrs(struct ibv_command_buffer *cmd)
 	struct ibv_command_buffer *link;
 	struct ib_uverbs_attr *end;
 
-	for (end = cmd->hdr.attrs; end != cmd->last_attr; end++)
+	for (end = cmd->hdr.attrs; end != cmd->next_attr; end++)
 		finalize_attr(end);
 
 	for (link = cmd->next; link; link = link->next) {
diff --git a/libibverbs/examples/rc_pingpong.c b/libibverbs/examples/rc_pingpong.c
index 8b2253d5..0f37f5df 100644
--- a/libibverbs/examples/rc_pingpong.c
+++ b/libibverbs/examples/rc_pingpong.c
@@ -488,9 +488,8 @@ static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size,
 		}
 
 		ibv_query_qp(ctx->qp, &attr, IBV_QP_CAP, &init_attr);
-		if (init_attr.cap.max_inline_data >= size) {
+		if (init_attr.cap.max_inline_data >= size && !use_dm)
 			ctx->send_flags |= IBV_SEND_INLINE;
-		}
 	}
 
 	{
diff --git a/libibverbs/examples/xsrq_pingpong.c b/libibverbs/examples/xsrq_pingpong.c
index 4c0d825f..cfd3c34a 100644
--- a/libibverbs/examples/xsrq_pingpong.c
+++ b/libibverbs/examples/xsrq_pingpong.c
@@ -876,7 +876,7 @@ int main(int argc, char *argv[])
 			{}
 		};
 
-		c = getopt_long(argc, argv, "p:d:i:s:m:n:l:eg:c", long_options,
+		c = getopt_long(argc, argv, "p:d:i:s:m:n:l:eg:c:", long_options,
 				NULL);
 		if (c == -1)
 			break;
diff --git a/providers/hns/hns_roce_u_buf.c b/providers/hns/hns_roce_u_buf.c
index f92ea651..27ed90c2 100644
--- a/providers/hns/hns_roce_u_buf.c
+++ b/providers/hns/hns_roce_u_buf.c
@@ -46,7 +46,7 @@ int hns_roce_alloc_buf(struct hns_roce_buf *buf, unsigned int size,
 	if (buf->buf == MAP_FAILED)
 		return errno;
 
-	ret = ibv_dontfork_range(buf->buf, size);
+	ret = ibv_dontfork_range(buf->buf, buf->length);
 	if (ret)
 		munmap(buf->buf, buf->length);
 
diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
index af3bab1f..7d16d5b9 100644
--- a/providers/hns/hns_roce_u_hw_v2.c
+++ b/providers/hns/hns_roce_u_hw_v2.c
@@ -555,7 +555,6 @@ int hns_roce_u_v2_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
 	unsigned int ind_sge;
 	unsigned int ind;
 	int nreq;
-	int i;
 	void *wqe;
 	int ret = 0;
 	struct hns_roce_qp *qp = to_hr_qp(ibvqp);
@@ -563,7 +562,10 @@ int hns_roce_u_v2_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
 	struct hns_roce_rc_sq_wqe *rc_sq_wqe;
 	struct hns_roce_v2_wqe_data_seg *dseg;
 	struct ibv_qp_attr attr;
+	int valid_num_sge;
 	int attr_mask;
+	int j;
+	int i;
 
 	pthread_spin_lock(&qp->sq.lock);
 
@@ -598,17 +600,25 @@ int hns_roce_u_v2_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
 		memset(rc_sq_wqe, 0, sizeof(struct hns_roce_rc_sq_wqe));
 
 		qp->sq.wrid[ind & (qp->sq.wqe_cnt - 1)] = wr->wr_id;
-		for (i = 0; i < wr->num_sge; i++)
+
+		valid_num_sge = wr->num_sge;
+		j = 0;
+
+		for (i = 0; i < wr->num_sge; i++) {
+			if (unlikely(!wr->sg_list[i].length))
+				valid_num_sge--;
+
 			rc_sq_wqe->msg_len =
 					htole32(le32toh(rc_sq_wqe->msg_len) +
 							wr->sg_list[i].length);
+		}
 
 		if (wr->opcode == IBV_WR_SEND_WITH_IMM ||
 		    wr->opcode == IBV_WR_RDMA_WRITE_WITH_IMM)
 			rc_sq_wqe->immtdata = htole32(be32toh(wr->imm_data));
 
 		roce_set_field(rc_sq_wqe->byte_16, RC_SQ_WQE_BYTE_16_SGE_NUM_M,
-			       RC_SQ_WQE_BYTE_16_SGE_NUM_S, wr->num_sge);
+			       RC_SQ_WQE_BYTE_16_SGE_NUM_S, valid_num_sge);
 
 		roce_set_field(rc_sq_wqe->byte_20,
 			       RC_SQ_WQE_BYTE_20_MSG_START_SGE_IDX_S,
@@ -774,7 +784,7 @@ int hns_roce_u_v2_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
 			set_data_seg_v2(dseg, wr->sg_list);
 			wqe += sizeof(struct hns_roce_v2_wqe_data_seg);
 			set_atomic_seg(wqe, wr);
-		} else if (wr->send_flags & IBV_SEND_INLINE && wr->num_sge) {
+		} else if (wr->send_flags & IBV_SEND_INLINE && valid_num_sge) {
 			if (le32toh(rc_sq_wqe->msg_len) > qp->max_inline_data) {
 				ret = EINVAL;
 				*bad_wr = wr;
@@ -801,7 +811,7 @@ int hns_roce_u_v2_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
 				     RC_SQ_WQE_BYTE_4_INLINE_S, 1);
 		} else {
 			/* set sge */
-			if (wr->num_sge <= 2) {
+			if (valid_num_sge <= 2) {
 				for (i = 0; i < wr->num_sge; i++)
 					if (likely(wr->sg_list[i].length)) {
 						set_data_seg_v2(dseg,
@@ -814,7 +824,7 @@ int hns_roce_u_v2_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
 					RC_SQ_WQE_BYTE_20_MSG_START_SGE_IDX_S,
 					ind_sge & (qp->sge.sge_cnt - 1));
 
-				for (i = 0; i < 2; i++)
+				for (i = 0; i < wr->num_sge && j < 2; i++)
 					if (likely(wr->sg_list[i].length)) {
 						set_data_seg_v2(dseg,
 							       wr->sg_list + i);
@@ -824,10 +834,10 @@ int hns_roce_u_v2_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
 				dseg = get_send_sge_ex(qp, ind_sge &
 						    (qp->sge.sge_cnt - 1));
 
-				for (i = 0; i < wr->num_sge - 2; i++) {
-					if (likely(wr->sg_list[i + 2].length)) {
+				for (; i < wr->num_sge; i++) {
+					if (likely(wr->sg_list[i].length)) {
 						set_data_seg_v2(dseg,
-							   wr->sg_list + 2 + i);
+							   wr->sg_list + i);
 						dseg++;
 						ind_sge++;
 					}
@@ -849,22 +859,19 @@ out:
 			*(qp->sdb) = qp->sq.head & 0xffff;
 
 		qp->next_sge = ind_sge;
-
-		if (ibvqp->state == IBV_QPS_ERR) {
-			attr_mask = IBV_QP_STATE;
-			attr.qp_state = IBV_QPS_ERR;
-
-			ret = hns_roce_u_v2_modify_qp(ibvqp, &attr, attr_mask);
-			if (ret) {
-				pthread_spin_unlock(&qp->sq.lock);
-				*bad_wr = wr;
-				return ret;
-			}
-		}
 	}
 
 	pthread_spin_unlock(&qp->sq.lock);
 
+	if (ibvqp->state == IBV_QPS_ERR) {
+		attr_mask = IBV_QP_STATE;
+		attr.qp_state = IBV_QPS_ERR;
+
+		ret = hns_roce_u_v2_modify_qp(ibvqp, &attr, attr_mask);
+		if (ret)
+			*bad_wr = wr;
+	}
+
 	return ret;
 }
 
@@ -950,22 +957,19 @@ out:
 		else
 			hns_roce_update_rq_db(ctx, qp->ibv_qp.qp_num,
 				     qp->rq.head & ((qp->rq.wqe_cnt << 1) - 1));
-
-		if (ibvqp->state == IBV_QPS_ERR) {
-			attr_mask = IBV_QP_STATE;
-			attr.qp_state = IBV_QPS_ERR;
-
-			ret = hns_roce_u_v2_modify_qp(ibvqp, &attr, attr_mask);
-			if (ret) {
-				pthread_spin_unlock(&qp->rq.lock);
-				*bad_wr = wr;
-				return ret;
-			}
-		}
 	}
 
 	pthread_spin_unlock(&qp->rq.lock);
 
+	if (ibvqp->state == IBV_QPS_ERR) {
+		attr_mask = IBV_QP_STATE;
+		attr.qp_state = IBV_QPS_ERR;
+
+		ret = hns_roce_u_v2_modify_qp(ibvqp, &attr, attr_mask);
+		if (ret)
+			*bad_wr = wr;
+	}
+
 	return ret;
 }
 
@@ -1020,9 +1024,21 @@ static int hns_roce_u_v2_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
 	int ret;
 	struct ibv_modify_qp cmd;
 	struct hns_roce_qp *hr_qp = to_hr_qp(qp);
+	bool flag = false; /* modify qp to error */
+
+	if ((attr_mask & IBV_QP_STATE) && (attr->qp_state == IBV_QPS_ERR)) {
+		pthread_spin_lock(&hr_qp->sq.lock);
+		pthread_spin_lock(&hr_qp->rq.lock);
+		flag = true;
+	}
 
 	ret = ibv_cmd_modify_qp(qp, attr, attr_mask, &cmd, sizeof(cmd));
 
+	if (flag) {
+		pthread_spin_unlock(&hr_qp->rq.lock);
+		pthread_spin_unlock(&hr_qp->sq.lock);
+	}
+
 	if (!ret && (attr_mask & IBV_QP_STATE) &&
 	    attr->qp_state == IBV_QPS_RESET) {
 		hns_roce_v2_cq_clean(to_hr_cq(qp->recv_cq), qp->qp_num,
diff --git a/providers/mlx5/man/mlx5dv_create_flow_action_modify_header.3.md b/providers/mlx5/man/mlx5dv_create_flow_action_modify_header.3.md
index 54f1c1c8..f89665f0 100644
--- a/providers/mlx5/man/mlx5dv_create_flow_action_modify_header.3.md
+++ b/providers/mlx5/man/mlx5dv_create_flow_action_modify_header.3.md
@@ -34,7 +34,7 @@ Create a modify header flow steering action, it allows mutating a packet header.
 :	The size of *actions* buffer in bytes.
 
 *actions*
-:	A buffer which contains modify actions provided in device spec format.
+:	A buffer which contains modify actions provided in device spec format (i.e. be64).
 
 *ft_type*
 :	Defines the flow table type to which the modify header action will be attached.
diff --git a/providers/mlx5/verbs.c b/providers/mlx5/verbs.c
index bab675f6..890ed980 100644
--- a/providers/mlx5/verbs.c
+++ b/providers/mlx5/verbs.c
@@ -1452,13 +1452,13 @@ static int mlx5_alloc_qp_buf(struct ibv_context *context,
 			err = -1;
 			goto ex_wrid;
 		}
-	}
 
-	qp->sq.wqe_head = malloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wqe_head));
-	if (!qp->sq.wqe_head) {
-		errno = ENOMEM;
-		err = -1;
+		qp->sq.wqe_head = malloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wqe_head));
+		if (!qp->sq.wqe_head) {
+			errno = ENOMEM;
+			err = -1;
 			goto ex_wrid;
+		}
 	}
 
 	if (qp->rq.wqe_cnt) {
@@ -2432,7 +2432,7 @@ struct ibv_ah *mlx5_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
 		ah->av.fl_mlid = attr->src_path_bits & 0x7f;
 		ah->av.rlid = htobe16(attr->dlid);
 		grh = 1;
-		ah->av.stat_rate_sl = (static_rate << 4) | (attr->sl & 0x7);
+		ah->av.stat_rate_sl = (static_rate << 4) | (attr->sl & 0xf);
 	}
 	if (attr->is_global) {
 		ah->av.tclass = attr->grh.traffic_class;
@@ -3494,13 +3494,14 @@ int mlx5_destroy_flow_action(struct ibv_flow_action *action)
 	return ret;
 }
 
-static inline int mlx5_memcpy_to_dm(struct ibv_dm *ibdm, uint64_t dm_offset,
-				    const void *host_addr, size_t length)
+static inline int mlx5_access_dm(struct ibv_dm *ibdm, uint64_t dm_offset,
+				 void *host_addr, size_t length,
+				 uint32_t read)
 {
 	struct mlx5_dm *dm = to_mdm(ibdm);
 	atomic_uint32_t *dm_ptr =
 		(atomic_uint32_t *)dm->start_va + dm_offset / 4;
-	const uint32_t *host_ptr = host_addr;
+	uint32_t *host_ptr = host_addr;
 	const uint32_t *host_end = host_ptr + length / 4;
 
 	if (dm_offset + length > dm->length)
@@ -3515,31 +3516,34 @@ static inline int mlx5_memcpy_to_dm(struct ibv_dm *ibdm, uint64_t dm_offset,
 	/* Copy granularity should be 4 Bytes since we enforce copy size to be
 	 * a multiple of 4 bytes.
 	 */
-	while (host_ptr != host_end) {
-		atomic_store_explicit(dm_ptr, *host_ptr, memory_order_relaxed);
-		host_ptr++;
-		dm_ptr++;
+	if (read) {
+		while (host_ptr != host_end) {
+			*host_ptr = atomic_load_explicit(dm_ptr,
+							 memory_order_relaxed);
+			host_ptr++;
+			dm_ptr++;
+		}
+	} else {
+		while (host_ptr != host_end) {
+			atomic_store_explicit(dm_ptr, *host_ptr,
+					      memory_order_relaxed);
+			host_ptr++;
+			dm_ptr++;
+		}
 	}
 
 	return 0;
 }
+static inline int mlx5_memcpy_to_dm(struct ibv_dm *ibdm, uint64_t dm_offset,
+				    const void *host_addr, size_t length)
+{
+	return mlx5_access_dm(ibdm, dm_offset, (void *)host_addr, length, 0);
+}
 
 static inline int mlx5_memcpy_from_dm(void *host_addr, struct ibv_dm *ibdm,
 				      uint64_t dm_offset, size_t length)
 {
-	struct mlx5_dm *dm = to_mdm(ibdm);
-	void *dm_va = dm->start_va + dm_offset;
-
-	if (dm_offset + length > dm->length)
-		return EFAULT;
-
-	/* DM access address must be aligned to 4 bytes */
-	if (dm_offset & 3)
-		return EINVAL;
-
-	memcpy(host_addr, dm_va, length);
-
-	return 0;
+	return mlx5_access_dm(ibdm, dm_offset, host_addr, length, 1);
 }
 
 struct ibv_dm *mlx5_alloc_dm(struct ibv_context *context,
diff --git a/redhat/rdma-core.spec b/redhat/rdma-core.spec
index 50b18ced..e1c1880a 100644
--- a/redhat/rdma-core.spec
+++ b/redhat/rdma-core.spec
@@ -1,5 +1,5 @@
 Name: rdma-core
-Version: 22.1
+Version: 22.3
 Release: 1%{?dist}
 Summary: RDMA core userspace libraries and daemons
 
diff --git a/suse/module-setup.sh b/suse/module-setup.sh
new file mode 100644
index 00000000..165f2af4
--- /dev/null
+++ b/suse/module-setup.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+check() {
+	[ -n "$hostonly" -a -c /sys/class/infiniband_verbs/uverbs0 ] && return 0
+	[ -n "$hostonly" ] && return 255
+	return 0
+}
+
+depends() {
+	return 0
+}
+
+install() {
+	inst /etc/rdma/mlx4.conf
+	inst /etc/rdma/modules/infiniband.conf
+	inst /etc/rdma/modules/iwarp.conf
+	inst /etc/rdma/modules/opa.conf
+	inst /etc/rdma/modules/rdma.conf
+	inst /etc/rdma/modules/roce.conf
+	inst /usr/lib/mlx4-setup.sh
+	inst_multiple lspci setpci awk sleep
+	inst_rules 70-persistent-ipoib.rules 75-rdma-description.rules 90-rdma-hw-modules.rules 90-rdma-ulp-modules.rules
+	inst_multiple -o \
+                  $systemdsystemunitdir/rdma-hw.target \
+                  $systemdsystemunitdir/rdma-load-modules@.service
+}
+
+installkernel() {
+	hostonly='' instmods =drivers/infiniband =drivers/net/ethernet/mellanox =drivers/net/ethernet/chelsio =drivers/net/ethernet/cisco =drivers/net/ethernet/emulex =drivers/target
+	hostonly='' instmods crc-t10dif crct10dif_common
+}
diff --git a/suse/rdma-core.spec b/suse/rdma-core.spec
index 87806587..0b8c7679 100644
--- a/suse/rdma-core.spec
+++ b/suse/rdma-core.spec
@@ -23,7 +23,7 @@
 
 %define         git_ver %{nil}
 Name:           rdma-core
-Version:        22.1
+Version:        22.3
 Release:        0
 Summary:        RDMA core userspace libraries and daemons
 License:        GPL-2.0 or BSD-2-Clause
@@ -392,7 +392,7 @@ cd build
 cd ..
 mkdir -p %{buildroot}/%{_sysconfdir}/rdma
 
-%global dracutlibdir %%{_sysconfdir}/dracut.conf.d
+%global dracutlibdir %%{_libexecdir}/dracut/
 %global sysmodprobedir %%{_sysconfdir}/modprobe.d
 
 mkdir -p %{buildroot}%{_libexecdir}/udev/rules.d
@@ -414,8 +414,7 @@ chmod 0644 %{buildroot}%{sysmodprobedir}/50-libmlx4.conf
 install -D -m0755 redhat/rdma.mlx4-setup.sh %{buildroot}%{_libexecdir}/mlx4-setup.sh
 
 # Dracut file for IB support during boot
-sed 's%/usr/libexec%/usr/lib%g' redhat/rdma.modules-setup.sh > %{buildroot}%{dracutlibdir}/modules.d/05rdma/module-setup.sh
-chmod 0755 %{buildroot}%{dracutlibdir}/modules.d/05rdma/module-setup.sh
+install -D -m0644 suse/module-setup.sh %{buildroot}%{dracutlibdir}/modules.d/05rdma/module-setup.sh
 
 # ibacm
 cd build

Reply to: