Netdev List
 help / color / mirror / Atom feed
* [PATCH v8 12/20] fscrypt: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

fscrypt starts several async. crypto ops and waiting for them to
complete. Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
---
 fs/crypto/crypto.c          | 28 ++++------------------------
 fs/crypto/fname.c           | 36 ++++++------------------------------
 fs/crypto/fscrypt_private.h | 10 ----------
 fs/crypto/keyinfo.c         | 21 +++------------------
 4 files changed, 13 insertions(+), 82 deletions(-)

diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index c7835df..80a3cad 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -126,21 +126,6 @@ struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, gfp_t gfp_flags)
 }
 EXPORT_SYMBOL(fscrypt_get_ctx);
 
-/**
- * page_crypt_complete() - completion callback for page crypto
- * @req: The asynchronous cipher request context
- * @res: The result of the cipher operation
- */
-static void page_crypt_complete(struct crypto_async_request *req, int res)
-{
-	struct fscrypt_completion_result *ecr = req->data;
-
-	if (res == -EINPROGRESS)
-		return;
-	ecr->res = res;
-	complete(&ecr->completion);
-}
-
 int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
 			   u64 lblk_num, struct page *src_page,
 			   struct page *dest_page, unsigned int len,
@@ -151,7 +136,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
 		u8 padding[FS_IV_SIZE - sizeof(__le64)];
 	} iv;
 	struct skcipher_request *req = NULL;
-	DECLARE_FS_COMPLETION_RESULT(ecr);
+	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist dst, src;
 	struct fscrypt_info *ci = inode->i_crypt_info;
 	struct crypto_skcipher *tfm = ci->ci_ctfm;
@@ -179,7 +164,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
 
 	skcipher_request_set_callback(
 		req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-		page_crypt_complete, &ecr);
+		crypto_req_done, &wait);
 
 	sg_init_table(&dst, 1);
 	sg_set_page(&dst, dest_page, len, offs);
@@ -187,14 +172,9 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
 	sg_set_page(&src, src_page, len, offs);
 	skcipher_request_set_crypt(req, &src, &dst, len, &iv);
 	if (rw == FS_DECRYPT)
-		res = crypto_skcipher_decrypt(req);
+		res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
 	else
-		res = crypto_skcipher_encrypt(req);
-	if (res == -EINPROGRESS || res == -EBUSY) {
-		BUG_ON(req->base.data != &ecr);
-		wait_for_completion(&ecr.completion);
-		res = ecr.res;
-	}
+		res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
 	skcipher_request_free(req);
 	if (res) {
 		printk_ratelimited(KERN_ERR
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index ad9f814..a80a0d3 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -15,21 +15,6 @@
 #include "fscrypt_private.h"
 
 /**
- * fname_crypt_complete() - completion callback for filename crypto
- * @req: The asynchronous cipher request context
- * @res: The result of the cipher operation
- */
-static void fname_crypt_complete(struct crypto_async_request *req, int res)
-{
-	struct fscrypt_completion_result *ecr = req->data;
-
-	if (res == -EINPROGRESS)
-		return;
-	ecr->res = res;
-	complete(&ecr->completion);
-}
-
-/**
  * fname_encrypt() - encrypt a filename
  *
  * The caller must have allocated sufficient memory for the @oname string.
@@ -40,7 +25,7 @@ static int fname_encrypt(struct inode *inode,
 			const struct qstr *iname, struct fscrypt_str *oname)
 {
 	struct skcipher_request *req = NULL;
-	DECLARE_FS_COMPLETION_RESULT(ecr);
+	DECLARE_CRYPTO_WAIT(wait);
 	struct fscrypt_info *ci = inode->i_crypt_info;
 	struct crypto_skcipher *tfm = ci->ci_ctfm;
 	int res = 0;
@@ -76,17 +61,12 @@ static int fname_encrypt(struct inode *inode,
 	}
 	skcipher_request_set_callback(req,
 			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-			fname_crypt_complete, &ecr);
+			crypto_req_done, &wait);
 	sg_init_one(&sg, oname->name, cryptlen);
 	skcipher_request_set_crypt(req, &sg, &sg, cryptlen, iv);
 
 	/* Do the encryption */
-	res = crypto_skcipher_encrypt(req);
-	if (res == -EINPROGRESS || res == -EBUSY) {
-		/* Request is being completed asynchronously; wait for it */
-		wait_for_completion(&ecr.completion);
-		res = ecr.res;
-	}
+	res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
 	skcipher_request_free(req);
 	if (res < 0) {
 		printk_ratelimited(KERN_ERR
@@ -110,7 +90,7 @@ static int fname_decrypt(struct inode *inode,
 				struct fscrypt_str *oname)
 {
 	struct skcipher_request *req = NULL;
-	DECLARE_FS_COMPLETION_RESULT(ecr);
+	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist src_sg, dst_sg;
 	struct fscrypt_info *ci = inode->i_crypt_info;
 	struct crypto_skcipher *tfm = ci->ci_ctfm;
@@ -131,7 +111,7 @@ static int fname_decrypt(struct inode *inode,
 	}
 	skcipher_request_set_callback(req,
 		CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-		fname_crypt_complete, &ecr);
+		crypto_req_done, &wait);
 
 	/* Initialize IV */
 	memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
@@ -140,11 +120,7 @@ static int fname_decrypt(struct inode *inode,
 	sg_init_one(&src_sg, iname->name, iname->len);
 	sg_init_one(&dst_sg, oname->name, oname->len);
 	skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
-	res = crypto_skcipher_decrypt(req);
-	if (res == -EINPROGRESS || res == -EBUSY) {
-		wait_for_completion(&ecr.completion);
-		res = ecr.res;
-	}
+	res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
 	skcipher_request_free(req);
 	if (res < 0) {
 		printk_ratelimited(KERN_ERR
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index a1d5021..c0f1881 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -69,16 +69,6 @@ typedef enum {
 #define FS_CTX_REQUIRES_FREE_ENCRYPT_FL		0x00000001
 #define FS_CTX_HAS_BOUNCE_BUFFER_FL		0x00000002
 
-struct fscrypt_completion_result {
-	struct completion completion;
-	int res;
-};
-
-#define DECLARE_FS_COMPLETION_RESULT(ecr) \
-	struct fscrypt_completion_result ecr = { \
-		COMPLETION_INITIALIZER_ONSTACK((ecr).completion), 0 }
-
-
 /* crypto.c */
 extern int fscrypt_initialize(unsigned int cop_flags);
 extern struct workqueue_struct *fscrypt_read_workqueue;
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index 018c588..3c84cac 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -17,17 +17,6 @@
 
 static struct crypto_shash *essiv_hash_tfm;
 
-static void derive_crypt_complete(struct crypto_async_request *req, int rc)
-{
-	struct fscrypt_completion_result *ecr = req->data;
-
-	if (rc == -EINPROGRESS)
-		return;
-
-	ecr->res = rc;
-	complete(&ecr->completion);
-}
-
 /**
  * derive_key_aes() - Derive a key using AES-128-ECB
  * @deriving_key: Encryption key used for derivation.
@@ -42,7 +31,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
 {
 	int res = 0;
 	struct skcipher_request *req = NULL;
-	DECLARE_FS_COMPLETION_RESULT(ecr);
+	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist src_sg, dst_sg;
 	struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
 
@@ -59,7 +48,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
 	}
 	skcipher_request_set_callback(req,
 			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-			derive_crypt_complete, &ecr);
+			crypto_req_done, &wait);
 	res = crypto_skcipher_setkey(tfm, deriving_key,
 					FS_AES_128_ECB_KEY_SIZE);
 	if (res < 0)
@@ -69,11 +58,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
 	sg_init_one(&dst_sg, derived_raw_key, source_key->size);
 	skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size,
 				   NULL);
-	res = crypto_skcipher_encrypt(req);
-	if (res == -EINPROGRESS || res == -EBUSY) {
-		wait_for_completion(&ecr.completion);
-		res = ecr.res;
-	}
+	res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
 out:
 	skcipher_request_free(req);
 	crypto_free_skcipher(tfm);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 12/20] fscrypt: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar,
	Dmitry Kasatkin, James Morris, Serge E. Hallyn, linux-crypto,
	linux-doc, linux-kernel, keyrings, linux-arm-kernel,
	linux-mediatek, linux-raid, linux-cifs, samba-technical,
	linux-fscrypt, netdev, linux-ima-devel, linux-ima-user,
	linux-security-module
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

fscrypt starts several async. crypto ops and waiting for them to
complete. Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
---
 fs/crypto/crypto.c          | 28 ++++------------------------
 fs/crypto/fname.c           | 36 ++++++------------------------------
 fs/crypto/fscrypt_private.h | 10 ----------
 fs/crypto/keyinfo.c         | 21 +++------------------
 4 files changed, 13 insertions(+), 82 deletions(-)

diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index c7835df..80a3cad 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -126,21 +126,6 @@ struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, gfp_t gfp_flags)
 }
 EXPORT_SYMBOL(fscrypt_get_ctx);
 
-/**
- * page_crypt_complete() - completion callback for page crypto
- * @req: The asynchronous cipher request context
- * @res: The result of the cipher operation
- */
-static void page_crypt_complete(struct crypto_async_request *req, int res)
-{
-	struct fscrypt_completion_result *ecr = req->data;
-
-	if (res == -EINPROGRESS)
-		return;
-	ecr->res = res;
-	complete(&ecr->completion);
-}
-
 int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
 			   u64 lblk_num, struct page *src_page,
 			   struct page *dest_page, unsigned int len,
@@ -151,7 +136,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
 		u8 padding[FS_IV_SIZE - sizeof(__le64)];
 	} iv;
 	struct skcipher_request *req = NULL;
-	DECLARE_FS_COMPLETION_RESULT(ecr);
+	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist dst, src;
 	struct fscrypt_info *ci = inode->i_crypt_info;
 	struct crypto_skcipher *tfm = ci->ci_ctfm;
@@ -179,7 +164,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
 
 	skcipher_request_set_callback(
 		req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-		page_crypt_complete, &ecr);
+		crypto_req_done, &wait);
 
 	sg_init_table(&dst, 1);
 	sg_set_page(&dst, dest_page, len, offs);
@@ -187,14 +172,9 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
 	sg_set_page(&src, src_page, len, offs);
 	skcipher_request_set_crypt(req, &src, &dst, len, &iv);
 	if (rw == FS_DECRYPT)
-		res = crypto_skcipher_decrypt(req);
+		res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
 	else
-		res = crypto_skcipher_encrypt(req);
-	if (res == -EINPROGRESS || res == -EBUSY) {
-		BUG_ON(req->base.data != &ecr);
-		wait_for_completion(&ecr.completion);
-		res = ecr.res;
-	}
+		res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
 	skcipher_request_free(req);
 	if (res) {
 		printk_ratelimited(KERN_ERR
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index ad9f814..a80a0d3 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -15,21 +15,6 @@
 #include "fscrypt_private.h"
 
 /**
- * fname_crypt_complete() - completion callback for filename crypto
- * @req: The asynchronous cipher request context
- * @res: The result of the cipher operation
- */
-static void fname_crypt_complete(struct crypto_async_request *req, int res)
-{
-	struct fscrypt_completion_result *ecr = req->data;
-
-	if (res == -EINPROGRESS)
-		return;
-	ecr->res = res;
-	complete(&ecr->completion);
-}
-
-/**
  * fname_encrypt() - encrypt a filename
  *
  * The caller must have allocated sufficient memory for the @oname string.
@@ -40,7 +25,7 @@ static int fname_encrypt(struct inode *inode,
 			const struct qstr *iname, struct fscrypt_str *oname)
 {
 	struct skcipher_request *req = NULL;
-	DECLARE_FS_COMPLETION_RESULT(ecr);
+	DECLARE_CRYPTO_WAIT(wait);
 	struct fscrypt_info *ci = inode->i_crypt_info;
 	struct crypto_skcipher *tfm = ci->ci_ctfm;
 	int res = 0;
@@ -76,17 +61,12 @@ static int fname_encrypt(struct inode *inode,
 	}
 	skcipher_request_set_callback(req,
 			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-			fname_crypt_complete, &ecr);
+			crypto_req_done, &wait);
 	sg_init_one(&sg, oname->name, cryptlen);
 	skcipher_request_set_crypt(req, &sg, &sg, cryptlen, iv);
 
 	/* Do the encryption */
-	res = crypto_skcipher_encrypt(req);
-	if (res == -EINPROGRESS || res == -EBUSY) {
-		/* Request is being completed asynchronously; wait for it */
-		wait_for_completion(&ecr.completion);
-		res = ecr.res;
-	}
+	res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
 	skcipher_request_free(req);
 	if (res < 0) {
 		printk_ratelimited(KERN_ERR
@@ -110,7 +90,7 @@ static int fname_decrypt(struct inode *inode,
 				struct fscrypt_str *oname)
 {
 	struct skcipher_request *req = NULL;
-	DECLARE_FS_COMPLETION_RESULT(ecr);
+	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist src_sg, dst_sg;
 	struct fscrypt_info *ci = inode->i_crypt_info;
 	struct crypto_skcipher *tfm = ci->ci_ctfm;
@@ -131,7 +111,7 @@ static int fname_decrypt(struct inode *inode,
 	}
 	skcipher_request_set_callback(req,
 		CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-		fname_crypt_complete, &ecr);
+		crypto_req_done, &wait);
 
 	/* Initialize IV */
 	memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
@@ -140,11 +120,7 @@ static int fname_decrypt(struct inode *inode,
 	sg_init_one(&src_sg, iname->name, iname->len);
 	sg_init_one(&dst_sg, oname->name, oname->len);
 	skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
-	res = crypto_skcipher_decrypt(req);
-	if (res == -EINPROGRESS || res == -EBUSY) {
-		wait_for_completion(&ecr.completion);
-		res = ecr.res;
-	}
+	res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
 	skcipher_request_free(req);
 	if (res < 0) {
 		printk_ratelimited(KERN_ERR
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index a1d5021..c0f1881 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -69,16 +69,6 @@ typedef enum {
 #define FS_CTX_REQUIRES_FREE_ENCRYPT_FL		0x00000001
 #define FS_CTX_HAS_BOUNCE_BUFFER_FL		0x00000002
 
-struct fscrypt_completion_result {
-	struct completion completion;
-	int res;
-};
-
-#define DECLARE_FS_COMPLETION_RESULT(ecr) \
-	struct fscrypt_completion_result ecr = { \
-		COMPLETION_INITIALIZER_ONSTACK((ecr).completion), 0 }
-
-
 /* crypto.c */
 extern int fscrypt_initialize(unsigned int cop_flags);
 extern struct workqueue_struct *fscrypt_read_workqueue;
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index 018c588..3c84cac 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -17,17 +17,6 @@
 
 static struct crypto_shash *essiv_hash_tfm;
 
-static void derive_crypt_complete(struct crypto_async_request *req, int rc)
-{
-	struct fscrypt_completion_result *ecr = req->data;
-
-	if (rc == -EINPROGRESS)
-		return;
-
-	ecr->res = rc;
-	complete(&ecr->completion);
-}
-
 /**
  * derive_key_aes() - Derive a key using AES-128-ECB
  * @deriving_key: Encryption key used for derivation.
@@ -42,7 +31,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
 {
 	int res = 0;
 	struct skcipher_request *req = NULL;
-	DECLARE_FS_COMPLETION_RESULT(ecr);
+	DECLARE_CRYPTO_WAIT(wait);
 	struct scatterlist src_sg, dst_sg;
 	struct crypto_skcipher *tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0);
 
@@ -59,7 +48,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
 	}
 	skcipher_request_set_callback(req,
 			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
-			derive_crypt_complete, &ecr);
+			crypto_req_done, &wait);
 	res = crypto_skcipher_setkey(tfm, deriving_key,
 					FS_AES_128_ECB_KEY_SIZE);
 	if (res < 0)
@@ -69,11 +58,7 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
 	sg_init_one(&dst_sg, derived_raw_key, source_key->size);
 	skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size,
 				   NULL);
-	res = crypto_skcipher_encrypt(req);
-	if (res == -EINPROGRESS || res == -EBUSY) {
-		wait_for_completion(&ecr.completion);
-		res = ecr.res;
-	}
+	res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
 out:
 	skcipher_request_free(req);
 	crypto_free_skcipher(tfm);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 13/20] dm: move dm-verity to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar
  Cc: Ofir Drang, Mikulas Patocka
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

dm-verity is starting async. crypto ops and waiting for them to complete.
Move it over to generic code doing the same.

This also avoids a future potential data coruption bug created
by the use of wait_for_completion_interruptible() without dealing
correctly with an interrupt aborting the wait prior to the
async op finishing, should this code ever move to a context
where signals are not masked.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
CC: Mikulas Patocka <mpatocka@redhat.com>
---
 drivers/md/dm-verity-target.c | 81 +++++++++++--------------------------------
 drivers/md/dm-verity.h        |  5 ---
 2 files changed, 20 insertions(+), 66 deletions(-)

diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index bda3cac..811ad28 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -92,74 +92,33 @@ static sector_t verity_position_at_level(struct dm_verity *v, sector_t block,
 	return block >> (level * v->hash_per_block_bits);
 }
 
-/*
- * Callback function for asynchrnous crypto API completion notification
- */
-static void verity_op_done(struct crypto_async_request *base, int err)
-{
-	struct verity_result *res = (struct verity_result *)base->data;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	res->err = err;
-	complete(&res->completion);
-}
-
-/*
- * Wait for async crypto API callback
- */
-static inline int verity_complete_op(struct verity_result *res, int ret)
-{
-	switch (ret) {
-	case 0:
-		break;
-
-	case -EINPROGRESS:
-	case -EBUSY:
-		ret = wait_for_completion_interruptible(&res->completion);
-		if (!ret)
-			ret = res->err;
-		reinit_completion(&res->completion);
-		break;
-
-	default:
-		DMERR("verity_wait_hash: crypto op submission failed: %d", ret);
-	}
-
-	if (unlikely(ret < 0))
-		DMERR("verity_wait_hash: crypto op failed: %d", ret);
-
-	return ret;
-}
-
 static int verity_hash_update(struct dm_verity *v, struct ahash_request *req,
 				const u8 *data, size_t len,
-				struct verity_result *res)
+				struct crypto_wait *wait)
 {
 	struct scatterlist sg;
 
 	sg_init_one(&sg, data, len);
 	ahash_request_set_crypt(req, &sg, NULL, len);
 
-	return verity_complete_op(res, crypto_ahash_update(req));
+	return crypto_wait_req(crypto_ahash_update(req), wait);
 }
 
 /*
  * Wrapper for crypto_ahash_init, which handles verity salting.
  */
 static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
-				struct verity_result *res)
+				struct crypto_wait *wait)
 {
 	int r;
 
 	ahash_request_set_tfm(req, v->tfm);
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
 					CRYPTO_TFM_REQ_MAY_BACKLOG,
-					verity_op_done, (void *)res);
-	init_completion(&res->completion);
+					crypto_req_done, (void *)wait);
+	crypto_init_wait(wait);
 
-	r = verity_complete_op(res, crypto_ahash_init(req));
+	r = crypto_wait_req(crypto_ahash_init(req), wait);
 
 	if (unlikely(r < 0)) {
 		DMERR("crypto_ahash_init failed: %d", r);
@@ -167,18 +126,18 @@ static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
 	}
 
 	if (likely(v->salt_size && (v->version >= 1)))
-		r = verity_hash_update(v, req, v->salt, v->salt_size, res);
+		r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
 
 	return r;
 }
 
 static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
-			     u8 *digest, struct verity_result *res)
+			     u8 *digest, struct crypto_wait *wait)
 {
 	int r;
 
 	if (unlikely(v->salt_size && (!v->version))) {
-		r = verity_hash_update(v, req, v->salt, v->salt_size, res);
+		r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
 
 		if (r < 0) {
 			DMERR("verity_hash_final failed updating salt: %d", r);
@@ -187,7 +146,7 @@ static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
 	}
 
 	ahash_request_set_crypt(req, NULL, digest, 0);
-	r = verity_complete_op(res, crypto_ahash_final(req));
+	r = crypto_wait_req(crypto_ahash_final(req), wait);
 out:
 	return r;
 }
@@ -196,17 +155,17 @@ int verity_hash(struct dm_verity *v, struct ahash_request *req,
 		const u8 *data, size_t len, u8 *digest)
 {
 	int r;
-	struct verity_result res;
+	struct crypto_wait wait;
 
-	r = verity_hash_init(v, req, &res);
+	r = verity_hash_init(v, req, &wait);
 	if (unlikely(r < 0))
 		goto out;
 
-	r = verity_hash_update(v, req, data, len, &res);
+	r = verity_hash_update(v, req, data, len, &wait);
 	if (unlikely(r < 0))
 		goto out;
 
-	r = verity_hash_final(v, req, digest, &res);
+	r = verity_hash_final(v, req, digest, &wait);
 
 out:
 	return r;
@@ -389,7 +348,7 @@ int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
  * Calculates the digest for the given bio
  */
 int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
-			struct bvec_iter *iter, struct verity_result *res)
+			struct bvec_iter *iter, struct crypto_wait *wait)
 {
 	unsigned int todo = 1 << v->data_dev_block_bits;
 	struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
@@ -414,7 +373,7 @@ int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
 		 */
 		sg_set_page(&sg, bv.bv_page, len, bv.bv_offset);
 		ahash_request_set_crypt(req, &sg, NULL, len);
-		r = verity_complete_op(res, crypto_ahash_update(req));
+		r = crypto_wait_req(crypto_ahash_update(req), wait);
 
 		if (unlikely(r < 0)) {
 			DMERR("verity_for_io_block crypto op failed: %d", r);
@@ -482,7 +441,7 @@ static int verity_verify_io(struct dm_verity_io *io)
 	struct dm_verity *v = io->v;
 	struct bvec_iter start;
 	unsigned b;
-	struct verity_result res;
+	struct crypto_wait wait;
 
 	for (b = 0; b < io->n_blocks; b++) {
 		int r;
@@ -507,17 +466,17 @@ static int verity_verify_io(struct dm_verity_io *io)
 			continue;
 		}
 
-		r = verity_hash_init(v, req, &res);
+		r = verity_hash_init(v, req, &wait);
 		if (unlikely(r < 0))
 			return r;
 
 		start = io->iter;
-		r = verity_for_io_block(v, io, &io->iter, &res);
+		r = verity_for_io_block(v, io, &io->iter, &wait);
 		if (unlikely(r < 0))
 			return r;
 
 		r = verity_hash_final(v, req, verity_io_real_digest(v, io),
-					&res);
+					&wait);
 		if (unlikely(r < 0))
 			return r;
 
diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
index a59e0ad..b675bc0 100644
--- a/drivers/md/dm-verity.h
+++ b/drivers/md/dm-verity.h
@@ -90,11 +90,6 @@ struct dm_verity_io {
 	 */
 };
 
-struct verity_result {
-	struct completion completion;
-	int err;
-};
-
 static inline struct ahash_request *verity_io_hash_req(struct dm_verity *v,
 						     struct dm_verity_io *io)
 {
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 13/20] dm: move dm-verity to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar,
	Dmitry Kasatkin, James Morris, Serge E. Hallyn, linux-crypto,
	linux-doc, linux-kernel, keyrings, linux-arm-kernel,
	linux-mediatek, linux-raid, linux-cifs, samba-technical,
	linux-fscrypt, netdev, linux-ima-devel, linux-ima-user,
	linux-security-module
  Cc: Ofir Drang, Mikulas Patocka
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

dm-verity is starting async. crypto ops and waiting for them to complete.
Move it over to generic code doing the same.

This also avoids a future potential data coruption bug created
by the use of wait_for_completion_interruptible() without dealing
correctly with an interrupt aborting the wait prior to the
async op finishing, should this code ever move to a context
where signals are not masked.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
CC: Mikulas Patocka <mpatocka@redhat.com>
---
 drivers/md/dm-verity-target.c | 81 +++++++++++--------------------------------
 drivers/md/dm-verity.h        |  5 ---
 2 files changed, 20 insertions(+), 66 deletions(-)

diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index bda3cac..811ad28 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -92,74 +92,33 @@ static sector_t verity_position_at_level(struct dm_verity *v, sector_t block,
 	return block >> (level * v->hash_per_block_bits);
 }
 
-/*
- * Callback function for asynchrnous crypto API completion notification
- */
-static void verity_op_done(struct crypto_async_request *base, int err)
-{
-	struct verity_result *res = (struct verity_result *)base->data;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	res->err = err;
-	complete(&res->completion);
-}
-
-/*
- * Wait for async crypto API callback
- */
-static inline int verity_complete_op(struct verity_result *res, int ret)
-{
-	switch (ret) {
-	case 0:
-		break;
-
-	case -EINPROGRESS:
-	case -EBUSY:
-		ret = wait_for_completion_interruptible(&res->completion);
-		if (!ret)
-			ret = res->err;
-		reinit_completion(&res->completion);
-		break;
-
-	default:
-		DMERR("verity_wait_hash: crypto op submission failed: %d", ret);
-	}
-
-	if (unlikely(ret < 0))
-		DMERR("verity_wait_hash: crypto op failed: %d", ret);
-
-	return ret;
-}
-
 static int verity_hash_update(struct dm_verity *v, struct ahash_request *req,
 				const u8 *data, size_t len,
-				struct verity_result *res)
+				struct crypto_wait *wait)
 {
 	struct scatterlist sg;
 
 	sg_init_one(&sg, data, len);
 	ahash_request_set_crypt(req, &sg, NULL, len);
 
-	return verity_complete_op(res, crypto_ahash_update(req));
+	return crypto_wait_req(crypto_ahash_update(req), wait);
 }
 
 /*
  * Wrapper for crypto_ahash_init, which handles verity salting.
  */
 static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
-				struct verity_result *res)
+				struct crypto_wait *wait)
 {
 	int r;
 
 	ahash_request_set_tfm(req, v->tfm);
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
 					CRYPTO_TFM_REQ_MAY_BACKLOG,
-					verity_op_done, (void *)res);
-	init_completion(&res->completion);
+					crypto_req_done, (void *)wait);
+	crypto_init_wait(wait);
 
-	r = verity_complete_op(res, crypto_ahash_init(req));
+	r = crypto_wait_req(crypto_ahash_init(req), wait);
 
 	if (unlikely(r < 0)) {
 		DMERR("crypto_ahash_init failed: %d", r);
@@ -167,18 +126,18 @@ static int verity_hash_init(struct dm_verity *v, struct ahash_request *req,
 	}
 
 	if (likely(v->salt_size && (v->version >= 1)))
-		r = verity_hash_update(v, req, v->salt, v->salt_size, res);
+		r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
 
 	return r;
 }
 
 static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
-			     u8 *digest, struct verity_result *res)
+			     u8 *digest, struct crypto_wait *wait)
 {
 	int r;
 
 	if (unlikely(v->salt_size && (!v->version))) {
-		r = verity_hash_update(v, req, v->salt, v->salt_size, res);
+		r = verity_hash_update(v, req, v->salt, v->salt_size, wait);
 
 		if (r < 0) {
 			DMERR("verity_hash_final failed updating salt: %d", r);
@@ -187,7 +146,7 @@ static int verity_hash_final(struct dm_verity *v, struct ahash_request *req,
 	}
 
 	ahash_request_set_crypt(req, NULL, digest, 0);
-	r = verity_complete_op(res, crypto_ahash_final(req));
+	r = crypto_wait_req(crypto_ahash_final(req), wait);
 out:
 	return r;
 }
@@ -196,17 +155,17 @@ int verity_hash(struct dm_verity *v, struct ahash_request *req,
 		const u8 *data, size_t len, u8 *digest)
 {
 	int r;
-	struct verity_result res;
+	struct crypto_wait wait;
 
-	r = verity_hash_init(v, req, &res);
+	r = verity_hash_init(v, req, &wait);
 	if (unlikely(r < 0))
 		goto out;
 
-	r = verity_hash_update(v, req, data, len, &res);
+	r = verity_hash_update(v, req, data, len, &wait);
 	if (unlikely(r < 0))
 		goto out;
 
-	r = verity_hash_final(v, req, digest, &res);
+	r = verity_hash_final(v, req, digest, &wait);
 
 out:
 	return r;
@@ -389,7 +348,7 @@ int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
  * Calculates the digest for the given bio
  */
 int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
-			struct bvec_iter *iter, struct verity_result *res)
+			struct bvec_iter *iter, struct crypto_wait *wait)
 {
 	unsigned int todo = 1 << v->data_dev_block_bits;
 	struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
@@ -414,7 +373,7 @@ int verity_for_io_block(struct dm_verity *v, struct dm_verity_io *io,
 		 */
 		sg_set_page(&sg, bv.bv_page, len, bv.bv_offset);
 		ahash_request_set_crypt(req, &sg, NULL, len);
-		r = verity_complete_op(res, crypto_ahash_update(req));
+		r = crypto_wait_req(crypto_ahash_update(req), wait);
 
 		if (unlikely(r < 0)) {
 			DMERR("verity_for_io_block crypto op failed: %d", r);
@@ -482,7 +441,7 @@ static int verity_verify_io(struct dm_verity_io *io)
 	struct dm_verity *v = io->v;
 	struct bvec_iter start;
 	unsigned b;
-	struct verity_result res;
+	struct crypto_wait wait;
 
 	for (b = 0; b < io->n_blocks; b++) {
 		int r;
@@ -507,17 +466,17 @@ static int verity_verify_io(struct dm_verity_io *io)
 			continue;
 		}
 
-		r = verity_hash_init(v, req, &res);
+		r = verity_hash_init(v, req, &wait);
 		if (unlikely(r < 0))
 			return r;
 
 		start = io->iter;
-		r = verity_for_io_block(v, io, &io->iter, &res);
+		r = verity_for_io_block(v, io, &io->iter, &wait);
 		if (unlikely(r < 0))
 			return r;
 
 		r = verity_hash_final(v, req, verity_io_real_digest(v, io),
-					&res);
+					&wait);
 		if (unlikely(r < 0))
 			return r;
 
diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
index a59e0ad..b675bc0 100644
--- a/drivers/md/dm-verity.h
+++ b/drivers/md/dm-verity.h
@@ -90,11 +90,6 @@ struct dm_verity_io {
 	 */
 };
 
-struct verity_result {
-	struct completion completion;
-	int err;
-};
-
 static inline struct ahash_request *verity_io_hash_req(struct dm_verity *v,
 						     struct dm_verity_io *io)
 {
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 14/20] cifs: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

cifs starts an async. crypto op and waits for their completion.
Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Acked-by: Pavel Shilovsky <pshilov@microsoft.com>
---
 fs/cifs/smb2ops.c | 30 ++++--------------------------
 1 file changed, 4 insertions(+), 26 deletions(-)

diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index fb2934b..982b39d 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -2066,22 +2066,6 @@ init_sg(struct smb_rqst *rqst, u8 *sign)
 	return sg;
 }
 
-struct cifs_crypt_result {
-	int err;
-	struct completion completion;
-};
-
-static void cifs_crypt_complete(struct crypto_async_request *req, int err)
-{
-	struct cifs_crypt_result *res = req->data;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	res->err = err;
-	complete(&res->completion);
-}
-
 static int
 smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
 {
@@ -2122,12 +2106,10 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc)
 	struct aead_request *req;
 	char *iv;
 	unsigned int iv_len;
-	struct cifs_crypt_result result = {0, };
+	DECLARE_CRYPTO_WAIT(wait);
 	struct crypto_aead *tfm;
 	unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
 
-	init_completion(&result.completion);
-
 	rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key);
 	if (rc) {
 		cifs_dbg(VFS, "%s: Could not get %scryption key\n", __func__,
@@ -2187,14 +2169,10 @@ crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc)
 	aead_request_set_ad(req, assoc_data_len);
 
 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				  cifs_crypt_complete, &result);
+				  crypto_req_done, &wait);
 
-	rc = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
-
-	if (rc == -EINPROGRESS || rc == -EBUSY) {
-		wait_for_completion(&result.completion);
-		rc = result.err;
-	}
+	rc = crypto_wait_req(enc ? crypto_aead_encrypt(req)
+				: crypto_aead_decrypt(req), &wait);
 
 	if (!rc && enc)
 		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 15/20] ima: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

ima starts several async crypto ops and  waits for their completions.
Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/integrity/ima/ima_crypto.c | 56 +++++++++++--------------------------
 1 file changed, 17 insertions(+), 39 deletions(-)

diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index a856d8c..9057b16 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -27,11 +27,6 @@
 
 #include "ima.h"
 
-struct ahash_completion {
-	struct completion completion;
-	int err;
-};
-
 /* minimum file size for ahash use */
 static unsigned long ima_ahash_minsize;
 module_param_named(ahash_minsize, ima_ahash_minsize, ulong, 0644);
@@ -196,30 +191,13 @@ static void ima_free_atfm(struct crypto_ahash *tfm)
 		crypto_free_ahash(tfm);
 }
 
-static void ahash_complete(struct crypto_async_request *req, int err)
+static inline int ahash_wait(int err, struct crypto_wait *wait)
 {
-	struct ahash_completion *res = req->data;
 
-	if (err == -EINPROGRESS)
-		return;
-	res->err = err;
-	complete(&res->completion);
-}
+	err = crypto_wait_req(err, wait);
 
-static int ahash_wait(int err, struct ahash_completion *res)
-{
-	switch (err) {
-	case 0:
-		break;
-	case -EINPROGRESS:
-	case -EBUSY:
-		wait_for_completion(&res->completion);
-		reinit_completion(&res->completion);
-		err = res->err;
-		/* fall through */
-	default:
+	if (err)
 		pr_crit_ratelimited("ahash calculation failed: err: %d\n", err);
-	}
 
 	return err;
 }
@@ -233,7 +211,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
 	int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0;
 	struct ahash_request *req;
 	struct scatterlist sg[1];
-	struct ahash_completion res;
+	struct crypto_wait wait;
 	size_t rbuf_size[2];
 
 	hash->length = crypto_ahash_digestsize(tfm);
@@ -242,12 +220,12 @@ static int ima_calc_file_hash_atfm(struct file *file,
 	if (!req)
 		return -ENOMEM;
 
-	init_completion(&res.completion);
+	crypto_init_wait(&wait);
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
 				   CRYPTO_TFM_REQ_MAY_SLEEP,
-				   ahash_complete, &res);
+				   crypto_req_done, &wait);
 
-	rc = ahash_wait(crypto_ahash_init(req), &res);
+	rc = ahash_wait(crypto_ahash_init(req), &wait);
 	if (rc)
 		goto out1;
 
@@ -288,7 +266,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
 			 * read/request, wait for the completion of the
 			 * previous ahash_update() request.
 			 */
-			rc = ahash_wait(ahash_rc, &res);
+			rc = ahash_wait(ahash_rc, &wait);
 			if (rc)
 				goto out3;
 		}
@@ -304,7 +282,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
 			 * read/request, wait for the completion of the
 			 * previous ahash_update() request.
 			 */
-			rc = ahash_wait(ahash_rc, &res);
+			rc = ahash_wait(ahash_rc, &wait);
 			if (rc)
 				goto out3;
 		}
@@ -318,7 +296,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
 			active = !active; /* swap buffers, if we use two */
 	}
 	/* wait for the last update request to complete */
-	rc = ahash_wait(ahash_rc, &res);
+	rc = ahash_wait(ahash_rc, &wait);
 out3:
 	if (read)
 		file->f_mode &= ~FMODE_READ;
@@ -327,7 +305,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
 out2:
 	if (!rc) {
 		ahash_request_set_crypt(req, NULL, hash->digest, 0);
-		rc = ahash_wait(crypto_ahash_final(req), &res);
+		rc = ahash_wait(crypto_ahash_final(req), &wait);
 	}
 out1:
 	ahash_request_free(req);
@@ -537,7 +515,7 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
 {
 	struct ahash_request *req;
 	struct scatterlist sg;
-	struct ahash_completion res;
+	struct crypto_wait wait;
 	int rc, ahash_rc = 0;
 
 	hash->length = crypto_ahash_digestsize(tfm);
@@ -546,12 +524,12 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
 	if (!req)
 		return -ENOMEM;
 
-	init_completion(&res.completion);
+	crypto_init_wait(&wait);
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
 				   CRYPTO_TFM_REQ_MAY_SLEEP,
-				   ahash_complete, &res);
+				   crypto_req_done, &wait);
 
-	rc = ahash_wait(crypto_ahash_init(req), &res);
+	rc = ahash_wait(crypto_ahash_init(req), &wait);
 	if (rc)
 		goto out;
 
@@ -561,10 +539,10 @@ static int calc_buffer_ahash_atfm(const void *buf, loff_t len,
 	ahash_rc = crypto_ahash_update(req);
 
 	/* wait for the update request to complete */
-	rc = ahash_wait(ahash_rc, &res);
+	rc = ahash_wait(ahash_rc, &wait);
 	if (!rc) {
 		ahash_request_set_crypt(req, NULL, hash->digest, 0);
-		rc = ahash_wait(crypto_ahash_final(req), &res);
+		rc = ahash_wait(crypto_ahash_final(req), &wait);
 	}
 out:
 	ahash_request_free(req);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 16/20] crypto: tcrypt: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

tcrypt starts several async crypto ops and  waits for their completions.
Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
---
 crypto/tcrypt.c | 84 +++++++++++++++++----------------------------------------
 1 file changed, 25 insertions(+), 59 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 0022a18..802aa81 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -79,34 +79,11 @@ static char *check[] = {
 	NULL
 };
 
-struct tcrypt_result {
-	struct completion completion;
-	int err;
-};
-
-static void tcrypt_complete(struct crypto_async_request *req, int err)
-{
-	struct tcrypt_result *res = req->data;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	res->err = err;
-	complete(&res->completion);
-}
-
 static inline int do_one_aead_op(struct aead_request *req, int ret)
 {
-	if (ret == -EINPROGRESS || ret == -EBUSY) {
-		struct tcrypt_result *tr = req->base.data;
+	struct crypto_wait *wait = req->base.data;
 
-		ret = wait_for_completion_interruptible(&tr->completion);
-		if (!ret)
-			ret = tr->err;
-		reinit_completion(&tr->completion);
-	}
-
-	return ret;
+	return crypto_wait_req(ret, wait);
 }
 
 static int test_aead_jiffies(struct aead_request *req, int enc,
@@ -248,7 +225,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
 	char *axbuf[XBUFSIZE];
 	unsigned int *b_size;
 	unsigned int iv_len;
-	struct tcrypt_result result;
+	struct crypto_wait wait;
 
 	iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
 	if (!iv)
@@ -284,7 +261,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
 		goto out_notfm;
 	}
 
-	init_completion(&result.completion);
+	crypto_init_wait(&wait);
 	printk(KERN_INFO "\ntesting speed of %s (%s) %s\n", algo,
 			get_driver_name(crypto_aead, tfm), e);
 
@@ -296,7 +273,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
 	}
 
 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				  tcrypt_complete, &result);
+				  crypto_req_done, &wait);
 
 	i = 0;
 	do {
@@ -397,21 +374,16 @@ static void test_hash_sg_init(struct scatterlist *sg)
 
 static inline int do_one_ahash_op(struct ahash_request *req, int ret)
 {
-	if (ret == -EINPROGRESS || ret == -EBUSY) {
-		struct tcrypt_result *tr = req->base.data;
+	struct crypto_wait *wait = req->base.data;
 
-		wait_for_completion(&tr->completion);
-		reinit_completion(&tr->completion);
-		ret = tr->err;
-	}
-	return ret;
+	return crypto_wait_req(ret, wait);
 }
 
 struct test_mb_ahash_data {
 	struct scatterlist sg[TVMEMSIZE];
 	char result[64];
 	struct ahash_request *req;
-	struct tcrypt_result tresult;
+	struct crypto_wait wait;
 	char *xbuf[XBUFSIZE];
 };
 
@@ -440,7 +412,7 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec,
 		if (testmgr_alloc_buf(data[i].xbuf))
 			goto out;
 
-		init_completion(&data[i].tresult.completion);
+		crypto_init_wait(&data[i].wait);
 
 		data[i].req = ahash_request_alloc(tfm, GFP_KERNEL);
 		if (!data[i].req) {
@@ -449,8 +421,8 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec,
 			goto out;
 		}
 
-		ahash_request_set_callback(data[i].req, 0,
-					   tcrypt_complete, &data[i].tresult);
+		ahash_request_set_callback(data[i].req, 0, crypto_req_done,
+					   &data[i].wait);
 		test_hash_sg_init(data[i].sg);
 	}
 
@@ -492,16 +464,16 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec,
 			if (ret)
 				break;
 
-			complete(&data[k].tresult.completion);
-			data[k].tresult.err = 0;
+			crypto_req_done(&data[k].req->base, 0);
 		}
 
 		for (j = 0; j < k; j++) {
-			struct tcrypt_result *tr = &data[j].tresult;
+			struct crypto_wait *wait = &data[j].wait;
+			int wait_ret;
 
-			wait_for_completion(&tr->completion);
-			if (tr->err)
-				ret = tr->err;
+			wait_ret = crypto_wait_req(-EINPROGRESS, wait);
+			if (wait_ret)
+				ret = wait_ret;
 		}
 
 		end = get_cycles();
@@ -679,7 +651,7 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs,
 				    struct hash_speed *speed, unsigned mask)
 {
 	struct scatterlist sg[TVMEMSIZE];
-	struct tcrypt_result tresult;
+	struct crypto_wait wait;
 	struct ahash_request *req;
 	struct crypto_ahash *tfm;
 	char *output;
@@ -708,9 +680,9 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs,
 		goto out;
 	}
 
-	init_completion(&tresult.completion);
+	crypto_init_wait(&wait);
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				   tcrypt_complete, &tresult);
+				   crypto_req_done, &wait);
 
 	output = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
 	if (!output)
@@ -765,15 +737,9 @@ static void test_hash_speed(const char *algo, unsigned int secs,
 
 static inline int do_one_acipher_op(struct skcipher_request *req, int ret)
 {
-	if (ret == -EINPROGRESS || ret == -EBUSY) {
-		struct tcrypt_result *tr = req->base.data;
-
-		wait_for_completion(&tr->completion);
-		reinit_completion(&tr->completion);
-		ret = tr->err;
-	}
+	struct crypto_wait *wait = req->base.data;
 
-	return ret;
+	return crypto_wait_req(ret, wait);
 }
 
 static int test_acipher_jiffies(struct skcipher_request *req, int enc,
@@ -853,7 +819,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
 				unsigned int tcount, u8 *keysize, bool async)
 {
 	unsigned int ret, i, j, k, iv_len;
-	struct tcrypt_result tresult;
+	struct crypto_wait wait;
 	const char *key;
 	char iv[128];
 	struct skcipher_request *req;
@@ -866,7 +832,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
 	else
 		e = "decryption";
 
-	init_completion(&tresult.completion);
+	crypto_init_wait(&wait);
 
 	tfm = crypto_alloc_skcipher(algo, 0, async ? 0 : CRYPTO_ALG_ASYNC);
 
@@ -887,7 +853,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
 	}
 
 	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				      tcrypt_complete, &tresult);
+				      crypto_req_done, &wait);
 
 	i = 0;
 	do {
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 16/20] crypto: tcrypt: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar,
	Dmitry Kasatkin, James Morris, Serge E. Hallyn, linux-crypto,
	linux-doc, linux-kernel, keyrings, linux-arm-kernel,
	linux-mediatek, linux-raid, linux-cifs, samba-technical,
	linux-fscrypt, netdev, linux-ima-devel, linux-ima-user,
	linux-security-module
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

tcrypt starts several async crypto ops and  waits for their completions.
Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
---
 crypto/tcrypt.c | 84 +++++++++++++++++----------------------------------------
 1 file changed, 25 insertions(+), 59 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 0022a18..802aa81 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -79,34 +79,11 @@ static char *check[] = {
 	NULL
 };
 
-struct tcrypt_result {
-	struct completion completion;
-	int err;
-};
-
-static void tcrypt_complete(struct crypto_async_request *req, int err)
-{
-	struct tcrypt_result *res = req->data;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	res->err = err;
-	complete(&res->completion);
-}
-
 static inline int do_one_aead_op(struct aead_request *req, int ret)
 {
-	if (ret == -EINPROGRESS || ret == -EBUSY) {
-		struct tcrypt_result *tr = req->base.data;
+	struct crypto_wait *wait = req->base.data;
 
-		ret = wait_for_completion_interruptible(&tr->completion);
-		if (!ret)
-			ret = tr->err;
-		reinit_completion(&tr->completion);
-	}
-
-	return ret;
+	return crypto_wait_req(ret, wait);
 }
 
 static int test_aead_jiffies(struct aead_request *req, int enc,
@@ -248,7 +225,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
 	char *axbuf[XBUFSIZE];
 	unsigned int *b_size;
 	unsigned int iv_len;
-	struct tcrypt_result result;
+	struct crypto_wait wait;
 
 	iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
 	if (!iv)
@@ -284,7 +261,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
 		goto out_notfm;
 	}
 
-	init_completion(&result.completion);
+	crypto_init_wait(&wait);
 	printk(KERN_INFO "\ntesting speed of %s (%s) %s\n", algo,
 			get_driver_name(crypto_aead, tfm), e);
 
@@ -296,7 +273,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
 	}
 
 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				  tcrypt_complete, &result);
+				  crypto_req_done, &wait);
 
 	i = 0;
 	do {
@@ -397,21 +374,16 @@ static void test_hash_sg_init(struct scatterlist *sg)
 
 static inline int do_one_ahash_op(struct ahash_request *req, int ret)
 {
-	if (ret == -EINPROGRESS || ret == -EBUSY) {
-		struct tcrypt_result *tr = req->base.data;
+	struct crypto_wait *wait = req->base.data;
 
-		wait_for_completion(&tr->completion);
-		reinit_completion(&tr->completion);
-		ret = tr->err;
-	}
-	return ret;
+	return crypto_wait_req(ret, wait);
 }
 
 struct test_mb_ahash_data {
 	struct scatterlist sg[TVMEMSIZE];
 	char result[64];
 	struct ahash_request *req;
-	struct tcrypt_result tresult;
+	struct crypto_wait wait;
 	char *xbuf[XBUFSIZE];
 };
 
@@ -440,7 +412,7 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec,
 		if (testmgr_alloc_buf(data[i].xbuf))
 			goto out;
 
-		init_completion(&data[i].tresult.completion);
+		crypto_init_wait(&data[i].wait);
 
 		data[i].req = ahash_request_alloc(tfm, GFP_KERNEL);
 		if (!data[i].req) {
@@ -449,8 +421,8 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec,
 			goto out;
 		}
 
-		ahash_request_set_callback(data[i].req, 0,
-					   tcrypt_complete, &data[i].tresult);
+		ahash_request_set_callback(data[i].req, 0, crypto_req_done,
+					   &data[i].wait);
 		test_hash_sg_init(data[i].sg);
 	}
 
@@ -492,16 +464,16 @@ static void test_mb_ahash_speed(const char *algo, unsigned int sec,
 			if (ret)
 				break;
 
-			complete(&data[k].tresult.completion);
-			data[k].tresult.err = 0;
+			crypto_req_done(&data[k].req->base, 0);
 		}
 
 		for (j = 0; j < k; j++) {
-			struct tcrypt_result *tr = &data[j].tresult;
+			struct crypto_wait *wait = &data[j].wait;
+			int wait_ret;
 
-			wait_for_completion(&tr->completion);
-			if (tr->err)
-				ret = tr->err;
+			wait_ret = crypto_wait_req(-EINPROGRESS, wait);
+			if (wait_ret)
+				ret = wait_ret;
 		}
 
 		end = get_cycles();
@@ -679,7 +651,7 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs,
 				    struct hash_speed *speed, unsigned mask)
 {
 	struct scatterlist sg[TVMEMSIZE];
-	struct tcrypt_result tresult;
+	struct crypto_wait wait;
 	struct ahash_request *req;
 	struct crypto_ahash *tfm;
 	char *output;
@@ -708,9 +680,9 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs,
 		goto out;
 	}
 
-	init_completion(&tresult.completion);
+	crypto_init_wait(&wait);
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				   tcrypt_complete, &tresult);
+				   crypto_req_done, &wait);
 
 	output = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
 	if (!output)
@@ -765,15 +737,9 @@ static void test_hash_speed(const char *algo, unsigned int secs,
 
 static inline int do_one_acipher_op(struct skcipher_request *req, int ret)
 {
-	if (ret == -EINPROGRESS || ret == -EBUSY) {
-		struct tcrypt_result *tr = req->base.data;
-
-		wait_for_completion(&tr->completion);
-		reinit_completion(&tr->completion);
-		ret = tr->err;
-	}
+	struct crypto_wait *wait = req->base.data;
 
-	return ret;
+	return crypto_wait_req(ret, wait);
 }
 
 static int test_acipher_jiffies(struct skcipher_request *req, int enc,
@@ -853,7 +819,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
 				unsigned int tcount, u8 *keysize, bool async)
 {
 	unsigned int ret, i, j, k, iv_len;
-	struct tcrypt_result tresult;
+	struct crypto_wait wait;
 	const char *key;
 	char iv[128];
 	struct skcipher_request *req;
@@ -866,7 +832,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
 	else
 		e = "decryption";
 
-	init_completion(&tresult.completion);
+	crypto_init_wait(&wait);
 
 	tfm = crypto_alloc_skcipher(algo, 0, async ? 0 : CRYPTO_ALG_ASYNC);
 
@@ -887,7 +853,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
 	}
 
 	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				      tcrypt_complete, &tresult);
+				      crypto_req_done, &wait);
 
 	i = 0;
 	do {
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 17/20] crypto: talitos: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

The talitos driver starts several async crypto ops and  waits for their
completions. Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
---
 drivers/crypto/talitos.c | 38 +++++---------------------------------
 1 file changed, 5 insertions(+), 33 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 79791c6..194a307 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2037,22 +2037,6 @@ static int ahash_import(struct ahash_request *areq, const void *in)
 	return 0;
 }
 
-struct keyhash_result {
-	struct completion completion;
-	int err;
-};
-
-static void keyhash_complete(struct crypto_async_request *req, int err)
-{
-	struct keyhash_result *res = req->data;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	res->err = err;
-	complete(&res->completion);
-}
-
 static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
 		   u8 *hash)
 {
@@ -2060,10 +2044,10 @@ static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
 
 	struct scatterlist sg[1];
 	struct ahash_request *req;
-	struct keyhash_result hresult;
+	struct crypto_wait wait;
 	int ret;
 
-	init_completion(&hresult.completion);
+	crypto_init_wait(&wait);
 
 	req = ahash_request_alloc(tfm, GFP_KERNEL);
 	if (!req)
@@ -2072,25 +2056,13 @@ static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
 	/* Keep tfm keylen == 0 during hash of the long key */
 	ctx->keylen = 0;
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				   keyhash_complete, &hresult);
+				   crypto_req_done, &wait);
 
 	sg_init_one(&sg[0], key, keylen);
 
 	ahash_request_set_crypt(req, sg, hash, keylen);
-	ret = crypto_ahash_digest(req);
-	switch (ret) {
-	case 0:
-		break;
-	case -EINPROGRESS:
-	case -EBUSY:
-		ret = wait_for_completion_interruptible(
-			&hresult.completion);
-		if (!ret)
-			ret = hresult.err;
-		break;
-	default:
-		break;
-	}
+	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
+
 	ahash_request_free(req);
 
 	return ret;
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 17/20] crypto: talitos: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar,
	Dmitry Kasatkin, James Morris, Serge E. Hallyn, linux-crypto,
	linux-doc, linux-kernel, keyrings, linux-arm-kernel,
	linux-mediatek, linux-raid, linux-cifs, samba-technical,
	linux-fscrypt, netdev, linux-ima-devel, linux-ima-user,
	linux-security-module
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

The talitos driver starts several async crypto ops and  waits for their
completions. Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
---
 drivers/crypto/talitos.c | 38 +++++---------------------------------
 1 file changed, 5 insertions(+), 33 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 79791c6..194a307 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2037,22 +2037,6 @@ static int ahash_import(struct ahash_request *areq, const void *in)
 	return 0;
 }
 
-struct keyhash_result {
-	struct completion completion;
-	int err;
-};
-
-static void keyhash_complete(struct crypto_async_request *req, int err)
-{
-	struct keyhash_result *res = req->data;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	res->err = err;
-	complete(&res->completion);
-}
-
 static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
 		   u8 *hash)
 {
@@ -2060,10 +2044,10 @@ static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
 
 	struct scatterlist sg[1];
 	struct ahash_request *req;
-	struct keyhash_result hresult;
+	struct crypto_wait wait;
 	int ret;
 
-	init_completion(&hresult.completion);
+	crypto_init_wait(&wait);
 
 	req = ahash_request_alloc(tfm, GFP_KERNEL);
 	if (!req)
@@ -2072,25 +2056,13 @@ static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
 	/* Keep tfm keylen == 0 during hash of the long key */
 	ctx->keylen = 0;
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				   keyhash_complete, &hresult);
+				   crypto_req_done, &wait);
 
 	sg_init_one(&sg[0], key, keylen);
 
 	ahash_request_set_crypt(req, sg, hash, keylen);
-	ret = crypto_ahash_digest(req);
-	switch (ret) {
-	case 0:
-		break;
-	case -EINPROGRESS:
-	case -EBUSY:
-		ret = wait_for_completion_interruptible(
-			&hresult.completion);
-		if (!ret)
-			ret = hresult.err;
-		break;
-	default:
-		break;
-	}
+	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
+
 	ahash_request_free(req);
 
 	return ret;
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 18/20] crypto: qce: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

The qce driver starts several async crypto ops and  waits for their
completions. Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
---
 drivers/crypto/qce/sha.c | 30 ++++--------------------------
 1 file changed, 4 insertions(+), 26 deletions(-)

diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c
index 47e114a..53227d7 100644
--- a/drivers/crypto/qce/sha.c
+++ b/drivers/crypto/qce/sha.c
@@ -349,28 +349,12 @@ static int qce_ahash_digest(struct ahash_request *req)
 	return qce->async_req_enqueue(tmpl->qce, &req->base);
 }
 
-struct qce_ahash_result {
-	struct completion completion;
-	int error;
-};
-
-static void qce_digest_complete(struct crypto_async_request *req, int error)
-{
-	struct qce_ahash_result *result = req->data;
-
-	if (error == -EINPROGRESS)
-		return;
-
-	result->error = error;
-	complete(&result->completion);
-}
-
 static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
 				 unsigned int keylen)
 {
 	unsigned int digestsize = crypto_ahash_digestsize(tfm);
 	struct qce_sha_ctx *ctx = crypto_tfm_ctx(&tfm->base);
-	struct qce_ahash_result result;
+	struct crypto_wait wait;
 	struct ahash_request *req;
 	struct scatterlist sg;
 	unsigned int blocksize;
@@ -405,9 +389,9 @@ static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
 		goto err_free_ahash;
 	}
 
-	init_completion(&result.completion);
+	crypto_init_wait(&wait);
 	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-				   qce_digest_complete, &result);
+				   crypto_req_done, &wait);
 	crypto_ahash_clear_flags(ahash_tfm, ~0);
 
 	buf = kzalloc(keylen + QCE_MAX_ALIGN_SIZE, GFP_KERNEL);
@@ -420,13 +404,7 @@ static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
 	sg_init_one(&sg, buf, keylen);
 	ahash_request_set_crypt(req, &sg, ctx->authkey, keylen);
 
-	ret = crypto_ahash_digest(req);
-	if (ret == -EINPROGRESS || ret == -EBUSY) {
-		ret = wait_for_completion_interruptible(&result.completion);
-		if (!ret)
-			ret = result.error;
-	}
-
+	ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
 	if (ret)
 		crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 19/20] crypto: mediatek: move to generic async completion
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

The mediatek driver starts several async crypto ops and waits for their
completions. Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Acked-by: Ryder Lee <ryder.lee@mediatek.com>
---
 drivers/crypto/mediatek/mtk-aes.c | 31 +++++--------------------------
 1 file changed, 5 insertions(+), 26 deletions(-)

diff --git a/drivers/crypto/mediatek/mtk-aes.c b/drivers/crypto/mediatek/mtk-aes.c
index 9e845e8..e2c7c95 100644
--- a/drivers/crypto/mediatek/mtk-aes.c
+++ b/drivers/crypto/mediatek/mtk-aes.c
@@ -137,11 +137,6 @@ struct mtk_aes_gcm_ctx {
 	struct crypto_skcipher *ctr;
 };
 
-struct mtk_aes_gcm_setkey_result {
-	int err;
-	struct completion completion;
-};
-
 struct mtk_aes_drv {
 	struct list_head dev_list;
 	/* Device list lock */
@@ -936,17 +931,6 @@ static int mtk_aes_gcm_crypt(struct aead_request *req, u64 mode)
 				    &req->base);
 }
 
-static void mtk_gcm_setkey_done(struct crypto_async_request *req, int err)
-{
-	struct mtk_aes_gcm_setkey_result *result = req->data;
-
-	if (err == -EINPROGRESS)
-		return;
-
-	result->err = err;
-	complete(&result->completion);
-}
-
 /*
  * Because of the hardware limitation, we need to pre-calculate key(H)
  * for the GHASH operation. The result of the encryption operation
@@ -962,7 +946,7 @@ static int mtk_aes_gcm_setkey(struct crypto_aead *aead, const u8 *key,
 		u32 hash[4];
 		u8 iv[8];
 
-		struct mtk_aes_gcm_setkey_result result;
+		struct crypto_wait wait;
 
 		struct scatterlist sg[1];
 		struct skcipher_request req;
@@ -1002,22 +986,17 @@ static int mtk_aes_gcm_setkey(struct crypto_aead *aead, const u8 *key,
 	if (!data)
 		return -ENOMEM;
 
-	init_completion(&data->result.completion);
+	crypto_init_wait(&data->wait);
 	sg_init_one(data->sg, &data->hash, AES_BLOCK_SIZE);
 	skcipher_request_set_tfm(&data->req, ctr);
 	skcipher_request_set_callback(&data->req, CRYPTO_TFM_REQ_MAY_SLEEP |
 				      CRYPTO_TFM_REQ_MAY_BACKLOG,
-				      mtk_gcm_setkey_done, &data->result);
+				      crypto_req_done, &data->wait);
 	skcipher_request_set_crypt(&data->req, data->sg, data->sg,
 				   AES_BLOCK_SIZE, data->iv);
 
-	err = crypto_skcipher_encrypt(&data->req);
-	if (err == -EINPROGRESS || err == -EBUSY) {
-		err = wait_for_completion_interruptible(
-			&data->result.completion);
-		if (!err)
-			err = data->result.err;
-	}
+	err = crypto_wait_req(crypto_skcipher_encrypt(&data->req),
+			      &data->wait);
 	if (err)
 		goto out;
 
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 20/20] crypto: adapt api sample to use async. op wait
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

The code sample is waiting for an async. crypto op completion.
Adapt sample to use the new generic infrastructure to do the same.

This also fixes a possible data coruption bug created by the
use of wait_for_completion_interruptible() without dealing
correctly with an interrupt aborting the wait prior to the
async op finishing.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
---
 Documentation/crypto/api-samples.rst | 52 +++++++-----------------------------
 1 file changed, 10 insertions(+), 42 deletions(-)

diff --git a/Documentation/crypto/api-samples.rst b/Documentation/crypto/api-samples.rst
index 2531948..006827e 100644
--- a/Documentation/crypto/api-samples.rst
+++ b/Documentation/crypto/api-samples.rst
@@ -7,59 +7,27 @@ Code Example For Symmetric Key Cipher Operation
 ::
 
 
-    struct tcrypt_result {
-        struct completion completion;
-        int err;
-    };
-
     /* tie all data structures together */
     struct skcipher_def {
         struct scatterlist sg;
         struct crypto_skcipher *tfm;
         struct skcipher_request *req;
-        struct tcrypt_result result;
+        struct crypto_wait wait;
     };
 
-    /* Callback function */
-    static void test_skcipher_cb(struct crypto_async_request *req, int error)
-    {
-        struct tcrypt_result *result = req->data;
-
-        if (error == -EINPROGRESS)
-            return;
-        result->err = error;
-        complete(&result->completion);
-        pr_info("Encryption finished successfully\n");
-    }
-
     /* Perform cipher operation */
     static unsigned int test_skcipher_encdec(struct skcipher_def *sk,
                          int enc)
     {
-        int rc = 0;
+        int rc;
 
         if (enc)
-            rc = crypto_skcipher_encrypt(sk->req);
+            rc = crypto_wait_req(crypto_skcipher_encrypt(sk->req), &sk->wait);
         else
-            rc = crypto_skcipher_decrypt(sk->req);
-
-        switch (rc) {
-        case 0:
-            break;
-        case -EINPROGRESS:
-        case -EBUSY:
-            rc = wait_for_completion_interruptible(
-                &sk->result.completion);
-            if (!rc && !sk->result.err) {
-                reinit_completion(&sk->result.completion);
-                break;
-            }
-        default:
-            pr_info("skcipher encrypt returned with %d result %d\n",
-                rc, sk->result.err);
-            break;
-        }
-        init_completion(&sk->result.completion);
+            rc = crypto_wait_req(crypto_skcipher_decrypt(sk->req), &sk->wait);
+
+	if (rc)
+		pr_info("skcipher encrypt returned with result %d\n", rc);
 
         return rc;
     }
@@ -89,8 +57,8 @@ Code Example For Symmetric Key Cipher Operation
         }
 
         skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-                          test_skcipher_cb,
-                          &sk.result);
+                          crypto_req_done,
+                          &sk.wait);
 
         /* AES 256 with random key */
         get_random_bytes(&key, 32);
@@ -122,7 +90,7 @@ Code Example For Symmetric Key Cipher Operation
         /* We encrypt one block */
         sg_init_one(&sk.sg, scratchpad, 16);
         skcipher_request_set_crypt(req, &sk.sg, &sk.sg, 16, ivdata);
-        init_completion(&sk.result.completion);
+        crypto_init_wait(&sk.wait);
 
         /* encrypt data */
         ret = test_skcipher_encdec(&sk, 1);
-- 
2.1.4

^ permalink raw reply related

* [PATCH v8 20/20] crypto: adapt api sample to use async. op wait
From: Gilad Ben-Yossef @ 2017-09-05 12:38 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Jonathan Corbet, David Howells,
	Tom Lendacky, Gary Hook, Boris Brezillon, Arnaud Ebalard,
	Matthias Brugger, Alasdair Kergon, Mike Snitzer, dm-devel,
	Shaohua Li, Steve French, Theodore Y. Ts'o, Jaegeuk Kim,
	Steffen Klassert, Alexey Kuznetsov, Hideaki YOSHIFUJI, Mimi Zohar,
	Dmitry Kasatkin, James Morris, Serge E. Hallyn, linux-crypto,
	linux-doc, linux-kernel, keyrings, linux-arm-kernel,
	linux-mediatek, linux-raid, linux-cifs, samba-technical,
	linux-fscrypt, netdev, linux-ima-devel, linux-ima-user,
	linux-security-module
  Cc: Ofir Drang
In-Reply-To: <1504615144-29770-1-git-send-email-gilad@benyossef.com>

The code sample is waiting for an async. crypto op completion.
Adapt sample to use the new generic infrastructure to do the same.

This also fixes a possible data coruption bug created by the
use of wait_for_completion_interruptible() without dealing
correctly with an interrupt aborting the wait prior to the
async op finishing.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
---
 Documentation/crypto/api-samples.rst | 52 +++++++-----------------------------
 1 file changed, 10 insertions(+), 42 deletions(-)

diff --git a/Documentation/crypto/api-samples.rst b/Documentation/crypto/api-samples.rst
index 2531948..006827e 100644
--- a/Documentation/crypto/api-samples.rst
+++ b/Documentation/crypto/api-samples.rst
@@ -7,59 +7,27 @@ Code Example For Symmetric Key Cipher Operation
 ::
 
 
-    struct tcrypt_result {
-        struct completion completion;
-        int err;
-    };
-
     /* tie all data structures together */
     struct skcipher_def {
         struct scatterlist sg;
         struct crypto_skcipher *tfm;
         struct skcipher_request *req;
-        struct tcrypt_result result;
+        struct crypto_wait wait;
     };
 
-    /* Callback function */
-    static void test_skcipher_cb(struct crypto_async_request *req, int error)
-    {
-        struct tcrypt_result *result = req->data;
-
-        if (error == -EINPROGRESS)
-            return;
-        result->err = error;
-        complete(&result->completion);
-        pr_info("Encryption finished successfully\n");
-    }
-
     /* Perform cipher operation */
     static unsigned int test_skcipher_encdec(struct skcipher_def *sk,
                          int enc)
     {
-        int rc = 0;
+        int rc;
 
         if (enc)
-            rc = crypto_skcipher_encrypt(sk->req);
+            rc = crypto_wait_req(crypto_skcipher_encrypt(sk->req), &sk->wait);
         else
-            rc = crypto_skcipher_decrypt(sk->req);
-
-        switch (rc) {
-        case 0:
-            break;
-        case -EINPROGRESS:
-        case -EBUSY:
-            rc = wait_for_completion_interruptible(
-                &sk->result.completion);
-            if (!rc && !sk->result.err) {
-                reinit_completion(&sk->result.completion);
-                break;
-            }
-        default:
-            pr_info("skcipher encrypt returned with %d result %d\n",
-                rc, sk->result.err);
-            break;
-        }
-        init_completion(&sk->result.completion);
+            rc = crypto_wait_req(crypto_skcipher_decrypt(sk->req), &sk->wait);
+
+	if (rc)
+		pr_info("skcipher encrypt returned with result %d\n", rc);
 
         return rc;
     }
@@ -89,8 +57,8 @@ Code Example For Symmetric Key Cipher Operation
         }
 
         skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-                          test_skcipher_cb,
-                          &sk.result);
+                          crypto_req_done,
+                          &sk.wait);
 
         /* AES 256 with random key */
         get_random_bytes(&key, 32);
@@ -122,7 +90,7 @@ Code Example For Symmetric Key Cipher Operation
         /* We encrypt one block */
         sg_init_one(&sk.sg, scratchpad, 16);
         skcipher_request_set_crypt(req, &sk.sg, &sk.sg, 16, ivdata);
-        init_completion(&sk.result.completion);
+        crypto_init_wait(&sk.wait);
 
         /* encrypt data */
         ret = test_skcipher_encdec(&sk, 1);
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH net] net: sched: don't use GFP_KERNEL under spin lock
From: Jiri Pirko @ 2017-09-05 12:52 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev, oss-drivers
In-Reply-To: <20170905115948.2fd38785@cakuba.netronome.com>

Tue, Sep 05, 2017 at 12:59:48PM CEST, kubakici@wp.pl wrote:
>Jiri, FWIW I also just noticed these, but they seem related to the
>earlier TC chain work?

What do you do to trigger this?

>
>unreferenced object 0xffff8807466f70c8 (size 64):
>  comm "tc", pid 1812, jiffies 4294932641 (age 1537.192s)
>  hex dump (first 32 bytes):
>    00 00 00 00 00 00 00 00 a0 83 e1 31 07 88 ff ff  ...........1....
>    d8 70 6f 46 07 88 ff ff d8 70 6f 46 07 88 ff ff  .poF.....poF....
>  backtrace:
>    [<ffffffffaa6b0118>] kmemleak_alloc+0x28/0x50
>    [<ffffffffa89a89b6>] kmem_cache_alloc_trace+0x1e6/0x550
>    [<ffffffffaa102827>] tcf_chain_create+0x97/0x460
>    [<ffffffffaa102f67>] tcf_block_get+0x127/0x230
>    [<ffffffffc03e8546>] ingress_init+0x76/0x110 [sch_ingress]
>    [<ffffffffaa0fbb1c>] qdisc_create+0x2ec/0x1100
>    [<ffffffffaa0fce1a>] tc_modify_qdisc+0x4ea/0x1ae0
>    [<ffffffffaa0355dc>] rtnetlink_rcv_msg+0xa3c/0x1400
>    [<ffffffffaa12e3cb>] netlink_rcv_skb+0x22b/0x4e0
>    [<ffffffffaa024b55>] rtnetlink_rcv+0x15/0x20
>    [<ffffffffaa12bddd>] netlink_unicast+0x47d/0x710
>    [<ffffffffaa12caef>] netlink_sendmsg+0xa7f/0x1140
>    [<ffffffffa9f15c52>] sock_sendmsg+0xe2/0x170
>    [<ffffffffa9f188bd>] ___sys_sendmsg+0x72d/0xcc0
>    [<ffffffffa9f1bfa2>] __sys_sendmsg+0xe2/0x260
>    [<ffffffffa9f1c132>] SyS_sendmsg+0x12/0x20
>unreferenced object 0xffff88074db6c008 (size 64):
>  comm "tc", pid 2097, jiffies 4294953636 (age 1453.212s)
>  hex dump (first 32 bytes):
>    00 00 00 00 00 00 00 00 60 a6 d1 31 07 88 ff ff  ........`..1....
>    18 c0 b6 4d 07 88 ff ff 18 c0 b6 4d 07 88 ff ff  ...M.......M....
>  backtrace:
>    [<ffffffffaa6b0118>] kmemleak_alloc+0x28/0x50
>    [<ffffffffa89a89b6>] kmem_cache_alloc_trace+0x1e6/0x550
>    [<ffffffffaa102827>] tcf_chain_create+0x97/0x460
>    [<ffffffffaa102f67>] tcf_block_get+0x127/0x230
>    [<ffffffffc03e8546>] ingress_init+0x76/0x110 [sch_ingress]
>    [<ffffffffaa0fbb1c>] qdisc_create+0x2ec/0x1100
>    [<ffffffffaa0fce1a>] tc_modify_qdisc+0x4ea/0x1ae0
>    [<ffffffffaa0355dc>] rtnetlink_rcv_msg+0xa3c/0x1400
>    [<ffffffffaa12e3cb>] netlink_rcv_skb+0x22b/0x4e0
>    [<ffffffffaa024b55>] rtnetlink_rcv+0x15/0x20
>    [<ffffffffaa12bddd>] netlink_unicast+0x47d/0x710
>    [<ffffffffaa12caef>] netlink_sendmsg+0xa7f/0x1140
>    [<ffffffffa9f15c52>] sock_sendmsg+0xe2/0x170
>    [<ffffffffa9f188bd>] ___sys_sendmsg+0x72d/0xcc0
>    [<ffffffffa9f1bfa2>] __sys_sendmsg+0xe2/0x260
>    [<ffffffffa9f1c132>] SyS_sendmsg+0x12/0x20
>unreferenced object 0xffff880749f82a48 (size 64):
>  comm "tc", pid 2381, jiffies 4294972986 (age 1375.812s)
>  hex dump (first 32 bytes):
>    00 00 00 00 00 00 00 00 c0 b7 31 31 07 88 ff ff  ..........11....
>    58 2a f8 49 07 88 ff ff 58 2a f8 49 07 88 ff ff  X*.I....X*.I....
>  backtrace:
>    [<ffffffffaa6b0118>] kmemleak_alloc+0x28/0x50
>    [<ffffffffa89a89b6>] kmem_cache_alloc_trace+0x1e6/0x550
>    [<ffffffffaa102827>] tcf_chain_create+0x97/0x460
>    [<ffffffffaa102f67>] tcf_block_get+0x127/0x230
>    [<ffffffffc03e8546>] ingress_init+0x76/0x110 [sch_ingress]
>    [<ffffffffaa0fbb1c>] qdisc_create+0x2ec/0x1100
>    [<ffffffffaa0fce1a>] tc_modify_qdisc+0x4ea/0x1ae0
>    [<ffffffffaa0355dc>] rtnetlink_rcv_msg+0xa3c/0x1400
>    [<ffffffffaa12e3cb>] netlink_rcv_skb+0x22b/0x4e0
>    [<ffffffffaa024b55>] rtnetlink_rcv+0x15/0x20
>    [<ffffffffaa12bddd>] netlink_unicast+0x47d/0x710
>    [<ffffffffaa12caef>] netlink_sendmsg+0xa7f/0x1140
>    [<ffffffffa9f15c52>] sock_sendmsg+0xe2/0x170
>    [<ffffffffa9f188bd>] ___sys_sendmsg+0x72d/0xcc0
>    [<ffffffffa9f1bfa2>] __sys_sendmsg+0xe2/0x260
>    [<ffffffffa9f1c132>] SyS_sendmsg+0x12/0x20
>unreferenced object 0xffff8803fd855a08 (size 64):
>  comm "tc", pid 2663, jiffies 4294992152 (age 1299.328s)
>  hex dump (first 32 bytes):
>    00 00 00 00 00 00 00 00 20 49 80 31 07 88 ff ff  ........ I.1....
>    18 5a 85 fd 03 88 ff ff 18 5a 85 fd 03 88 ff ff  .Z.......Z......
>  backtrace:
>    [<ffffffffaa6b0118>] kmemleak_alloc+0x28/0x50
>    [<ffffffffa89a89b6>] kmem_cache_alloc_trace+0x1e6/0x550
>    [<ffffffffaa102827>] tcf_chain_create+0x97/0x460
>    [<ffffffffaa102f67>] tcf_block_get+0x127/0x230
>    [<ffffffffc03e8546>] ingress_init+0x76/0x110 [sch_ingress]
>    [<ffffffffaa0fbb1c>] qdisc_create+0x2ec/0x1100
>    [<ffffffffaa0fce1a>] tc_modify_qdisc+0x4ea/0x1ae0
>    [<ffffffffaa0355dc>] rtnetlink_rcv_msg+0xa3c/0x1400
>    [<ffffffffaa12e3cb>] netlink_rcv_skb+0x22b/0x4e0
>    [<ffffffffaa024b55>] rtnetlink_rcv+0x15/0x20
>    [<ffffffffaa12bddd>] netlink_unicast+0x47d/0x710
>    [<ffffffffaa12caef>] netlink_sendmsg+0xa7f/0x1140
>    [<ffffffffa9f15c52>] sock_sendmsg+0xe2/0x170
>    [<ffffffffa9f188bd>] ___sys_sendmsg+0x72d/0xcc0
>    [<ffffffffa9f1bfa2>] __sys_sendmsg+0xe2/0x260
>    [<ffffffffa9f1c132>] SyS_sendmsg+0x12/0x20
>unreferenced object 0xffff88071b096f28 (size 64):
>  comm "tc", pid 2943, jiffies 4295013397 (age 1214.352s)
>  hex dump (first 32 bytes):
>    00 00 00 00 00 00 00 00 c0 37 e7 30 07 88 ff ff  .........7.0....
>    38 6f 09 1b 07 88 ff ff 38 6f 09 1b 07 88 ff ff  8o......8o......
>  backtrace:
>    [<ffffffffaa6b0118>] kmemleak_alloc+0x28/0x50
>    [<ffffffffa89a89b6>] kmem_cache_alloc_trace+0x1e6/0x550
>    [<ffffffffaa102827>] tcf_chain_create+0x97/0x460
>    [<ffffffffaa102f67>] tcf_block_get+0x127/0x230
>    [<ffffffffc03e8546>] ingress_init+0x76/0x110 [sch_ingress]
>    [<ffffffffaa0fbb1c>] qdisc_create+0x2ec/0x1100
>    [<ffffffffaa0fce1a>] tc_modify_qdisc+0x4ea/0x1ae0
>    [<ffffffffaa0355dc>] rtnetlink_rcv_msg+0xa3c/0x1400
>    [<ffffffffaa12e3cb>] netlink_rcv_skb+0x22b/0x4e0
>    [<ffffffffaa024b55>] rtnetlink_rcv+0x15/0x20
>    [<ffffffffaa12bddd>] netlink_unicast+0x47d/0x710
>    [<ffffffffaa12caef>] netlink_sendmsg+0xa7f/0x1140
>    [<ffffffffa9f15c52>] sock_sendmsg+0xe2/0x170
>    [<ffffffffa9f188bd>] ___sys_sendmsg+0x72d/0xcc0
>    [<ffffffffa9f1bfa2>] __sys_sendmsg+0xe2/0x260
>    [<ffffffffa9f1c132>] SyS_sendmsg+0x12/0x20
>unreferenced object 0xffff880731f66568 (size 64):
>  comm "tc", pid 3263, jiffies 4295033366 (age 1134.480s)
>  hex dump (first 32 bytes):
>    00 00 00 00 00 00 00 00 00 95 64 65 07 88 ff ff  ..........de....
>    78 65 f6 31 07 88 ff ff 78 65 f6 31 07 88 ff ff  xe.1....xe.1....
>  backtrace:
>    [<ffffffffaa6b0118>] kmemleak_alloc+0x28/0x50
>    [<ffffffffa89a89b6>] kmem_cache_alloc_trace+0x1e6/0x550
>    [<ffffffffaa102827>] tcf_chain_create+0x97/0x460
>    [<ffffffffaa102f67>] tcf_block_get+0x127/0x230
>    [<ffffffffc03e8546>] ingress_init+0x76/0x110 [sch_ingress]
>    [<ffffffffaa0fbb1c>] qdisc_create+0x2ec/0x1100
>    [<ffffffffaa0fce1a>] tc_modify_qdisc+0x4ea/0x1ae0
>    [<ffffffffaa0355dc>] rtnetlink_rcv_msg+0xa3c/0x1400
>    [<ffffffffaa12e3cb>] netlink_rcv_skb+0x22b/0x4e0
>    [<ffffffffaa024b55>] rtnetlink_rcv+0x15/0x20
>    [<ffffffffaa12bddd>] netlink_unicast+0x47d/0x710
>    [<ffffffffaa12caef>] netlink_sendmsg+0xa7f/0x1140
>    [<ffffffffa9f15c52>] sock_sendmsg+0xe2/0x170
>    [<ffffffffa9f188bd>] ___sys_sendmsg+0x72d/0xcc0
>    [<ffffffffa9f1bfa2>] __sys_sendmsg+0xe2/0x260
>    [<ffffffffa9f1c132>] SyS_sendmsg+0x12/0x20

^ permalink raw reply

* [RFC net-next] net: sch_clsact: add support for global per-netns classifier mode
From: Nikolay Aleksandrov @ 2017-09-05 12:48 UTC (permalink / raw)
  To: netdev; +Cc: roopa, dsa, jiri, xiyou.wangcong, jhs, Nikolay Aleksandrov

Hi all,
This RFC adds a new mode for clsact which designates a device's egress
classifier as global per netns. The packets that are not classified for
a particular device will be classified using the global classifier.
We have needed a global classifier for some time now for various
purposes and setting the single bridge or loopback/vrf device as the
global classifier device is acceptable for us. Doing it this way avoids
the act/cls device and queue dependencies.

This is strictly an RFC patch just to show the intent, if we agree on
the details the proposed patch will have support for both ingress and
egress, and will be using a static key to avoid the fast path test when no
global classifier has been configured.

Example (need a modified tc that adds TCA_OPTIONS when using q_clsact):
$ tc qdisc add dev lo clsact global
$ tc filter add dev lo egress protocol ip u32 match ip dst 4.3.2.1/32 action drop

the last filter will be global for all devices that don't have a
specific egress_cl_list (i.e. have clsact configured).

Any comments and thoughts would be greatly appreciated.

Thanks!

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
---
 include/linux/rtnetlink.h   |  1 +
 include/net/net_namespace.h |  3 +++
 include/net/sch_generic.h   |  1 +
 net/core/dev.c              | 36 ++++++++++++++++++++++++++++++++++--
 net/sched/sch_ingress.c     | 15 +++++++++++++--
 5 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index dea59c8eec54..cb97973b8555 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -88,6 +88,7 @@ void net_dec_ingress_queue(void);
 #ifdef CONFIG_NET_EGRESS
 void net_inc_egress_queue(void);
 void net_dec_egress_queue(void);
+int net_set_global_egress_cls_dev(struct net *net, struct net_device *dev);
 #endif
 
 void rtnetlink_init(void);
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 57faa375eab9..3fef53dfdbfc 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -149,6 +149,9 @@ struct net {
 #endif
 	struct sock		*diag_nlsk;
 	atomic_t		fnhe_genid;
+#ifdef CONFIG_NET_EGRESS
+	struct net_device __rcu *global_egress_dev;
+#endif
 } __randomize_layout;
 
 #include <linux/seq_file_net.h>
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 135f5a2dd931..a37c37062446 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -69,6 +69,7 @@ struct Qdisc {
 				      * qdisc_tree_decrease_qlen() should stop.
 				      */
 #define TCQ_F_INVISIBLE		0x80 /* invisible by default in dump */
+#define TCQ_F_GLOBAL		0x100 /* device is used as global clsact dev */
 	u32			limit;
 	const struct Qdisc_ops	*ops;
 	struct qdisc_size_table	__rcu *stab;
diff --git a/net/core/dev.c b/net/core/dev.c
index 6f845e4fec17..cf883b2470a5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1718,6 +1718,31 @@ void net_dec_egress_queue(void)
 	static_key_slow_dec(&egress_needed);
 }
 EXPORT_SYMBOL_GPL(net_dec_egress_queue);
+
+int net_set_global_egress_cls_dev(struct net *net, struct net_device *dev)
+{
+	struct net_device *cur_dev;
+
+	ASSERT_RTNL();
+
+	cur_dev = rtnl_dereference(net->global_egress_dev);
+	if (dev) {
+		/* replace not allowed */
+		if (cur_dev)
+			return -EBUSY;
+		/* global cls devices should not change netns */
+		if (!(dev->features & NETIF_F_NETNS_LOCAL))
+			return -EINVAL;
+	}
+
+	/* set or clear based on dev */
+	rcu_assign_pointer(net->global_egress_dev, dev);
+	if (!dev)
+		synchronize_rcu_bh();
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(net_set_global_egress_cls_dev);
 #endif
 
 static struct static_key netstamp_needed __read_mostly;
@@ -3244,8 +3269,15 @@ sch_handle_egress(struct sk_buff *skb, int *ret, struct net_device *dev)
 	struct tcf_proto *cl = rcu_dereference_bh(dev->egress_cl_list);
 	struct tcf_result cl_res;
 
-	if (!cl)
-		return skb;
+	if (!cl) {
+		struct net_device *gdev;
+
+		gdev = rcu_dereference_bh(dev_net(dev)->global_egress_dev);
+		if (gdev)
+			cl = rcu_dereference_bh(gdev->egress_cl_list);
+		if (!cl)
+			return skb;
+	}
 
 	/* qdisc_skb_cb(skb)->pkt_len was already set by the caller. */
 	qdisc_bstats_cpu_update(cl->q, skb);
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index 44de4ee51ce9..a4871f138904 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -153,6 +153,9 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt)
 	struct net_device *dev = qdisc_dev(sch);
 	int err;
 
+	net_inc_ingress_queue();
+	net_inc_egress_queue();
+
 	err = tcf_block_get(&q->ingress_block, &dev->ingress_cl_list);
 	if (err)
 		return err;
@@ -161,8 +164,12 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt)
 	if (err)
 		return err;
 
-	net_inc_ingress_queue();
-	net_inc_egress_queue();
+	if (opt) {
+		err = net_set_global_egress_cls_dev(dev_net(dev), dev);
+		if (err)
+			return err;
+		sch->flags |= TCQ_F_GLOBAL;
+	}
 
 	sch->flags |= TCQ_F_CPUSTATS;
 
@@ -172,6 +179,10 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt)
 static void clsact_destroy(struct Qdisc *sch)
 {
 	struct clsact_sched_data *q = qdisc_priv(sch);
+	struct net_device *dev = qdisc_dev(sch);
+
+	if (sch->flags & TCQ_F_GLOBAL)
+		WARN_ON_ONCE(net_set_global_egress_cls_dev(dev_net(dev), NULL));
 
 	tcf_block_put(q->egress_block);
 	tcf_block_put(q->ingress_block);
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH] connector: Delete an error message for a failed memory allocation in cn_queue_alloc_callback_entry()
From: Evgeniy Polyakov @ 2017-09-05 13:10 UTC (permalink / raw)
  To: SF Markus Elfring, netdev@vger.kernel.org
  Cc: LKML, kernel-janitors@vger.kernel.org
In-Reply-To: <7b206228-b3e9-5cb9-873c-75b5d8aae23b@users.sourceforge.net>

Hi everyone

27.08.2017, 22:25, "SF Markus Elfring" <elfring@users.sourceforge.net>:
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Sun, 27 Aug 2017 21:18:37 +0200
>
> Omit an extra message for a memory allocation failure in this function.
>
> This issue was detected by using the Coccinelle software.
>
> Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>

Looks good to me, thanks Markus.
There is virtually zero useful information in this print if we are in the situation, when kernel can not allocate
a few bytes to run connector queue.

Acked-by: Evgeniy Polyakov <zbr@ioremap.net>

kernel-janitors@ please queue this patch up

> ---
>  drivers/connector/cn_queue.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
> index 1f8bf054d11c..e4f31d679f02 100644
> --- a/drivers/connector/cn_queue.c
> +++ b/drivers/connector/cn_queue.c
> @@ -40,10 +40,8 @@ cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name,
>          struct cn_callback_entry *cbq;
>
>          cbq = kzalloc(sizeof(*cbq), GFP_KERNEL);
> - if (!cbq) {
> - pr_err("Failed to create new callback queue.\n");
> + if (!cbq)
>                  return NULL;
> - }
>
>          atomic_set(&cbq->refcnt, 1);
>
> --
> 2.14.1

^ permalink raw reply

* Re: [PATCH net-next v6 3/3] openvswitch: enable NSH support
From: Hannes Frederic Sowa @ 2017-09-05 13:12 UTC (permalink / raw)
  To: Yang, Yi
  Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org,
	netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	jbenc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org, e@erig.me
In-Reply-To: <20170905113848.GC92895-re2EX8HDrk21gSHoDXDV2kEOCMrvLtNR@public.gmane.org>

"Yang, Yi" <yi.y.yang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> writes:

> On Tue, Sep 05, 2017 at 12:30:09PM +0200, Hannes Frederic Sowa wrote:
>> "Yang, Yi" <yi.y.yang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> writes:
>> 
>> > I'm not sure what new action you expect to bring here, I think group
>> > action is just for this, as you said it isn't only bound to NSH, you can
>> > start a new thread to discuss this. I don't think it is in scope of NSH.
>> 
>> It is in scope of this discussion as you will provide a user space API
>> that makes the NSH context fields accessible from user space in a
>> certain way. If you commit to this, there is no way going back.
>
> We can change this later if we really find a better way to handle this
> because it isn't defined in include/uapi/linux/openvswitch.h, so I still
> have backdoor to do this if needed :-)

Sorry, I can't follow you.

It doesn't matter if something is defined in uapi headers, the
observable behavior matters. If you allow users to configure flows with
specific fields, it should not stop working at a future point in time.

>> I haven't yet grasped the idea on how those fields will be used in OVS
>> besides load balancing. Even for load balancing the tunnel itself
>> (vxlan-gpe + UDP source port or ipv6 flowlabel) already provides enough
>> entropy to do per-flow load balancing. What else is needed?  Why a
>> context header for that? You just need multiple action chains and pick
>> one randomly.
>
> For our sfc use case in Opendaylight, we use context[0] for tunnel ID,
> context[1] for destination IP for reverse RSP, they are used to match
> and set in OpenFlow table, you can't limit users to use them in such
> ways.

So in your specific case you expect the masks to be completely stable
because you defined a protocol on top of NSH, understood. And that is
stable accross all possible paths. Understood as well.

> If you check GENEVE implementation, tun_metadata* can be set or matched
> as any other match field.

Yes, I wrote that in my previous mail. I wonder why NSH context metadata
is not in tun_metadata as well?

> Actually the most important information in NSH are just these context
> headers, you can't limit imagination of users by removing them from flow
> keys.
>
> My point is to bring miniflow into kernel data path to fix your concern,
> this will benefit your employer directly :-)

Okay, interesting. It will probably not help if you still have a hash of
a packet inside the flow table and use that for load balancing.

[...]

BTW I don't want to stop this patch, I am merely interested in how the
bigger picture will look like in the end.

Bye,
Hannes

^ permalink raw reply

* [wireless-testsing2:master 4/5] drivers/net/ethernet/marvell/mvpp2.c:7618:49: error: passing argument 4 of 'mvpp2_port_copy_mac_addr' from incompatible pointer type
From: kbuild test robot @ 2017-09-05 13:16 UTC (permalink / raw)
  To: David S. Miller; +Cc: kbuild-all, netdev, Bob Copeland

[-- Attachment #1: Type: text/plain, Size: 16168 bytes --]

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-testing.git master
head:   d17be7f7503bf9492198a242779a68af93fd92de
commit: 96c03618031bae5e9068b16f9e437b79f98f6482 [4/5] Merge remote-tracking branch 'mac80211-next/master'
config: ia64-allyesconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 6.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git checkout 96c03618031bae5e9068b16f9e437b79f98f6482
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All errors (new ones prefixed by >>):

   drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_port_probe':
>> drivers/net/ethernet/marvell/mvpp2.c:7618:49: error: passing argument 4 of 'mvpp2_port_copy_mac_addr' from incompatible pointer type [-Werror=incompatible-pointer-types]
     mvpp2_port_copy_mac_addr(dev, priv, port_node, &mac_from);
                                                    ^
   drivers/net/ethernet/marvell/mvpp2.c:7468:13: note: expected 'char **' but argument is of type 'const char **'
    static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,
                ^~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/marvell/mvpp2.c:7509:7: warning: unused variable 'hw_mac_addr' [-Wunused-variable]
     char hw_mac_addr[ETH_ALEN] = {0};
          ^~~~~~~~~~~
   drivers/net/ethernet/marvell/mvpp2.c:7507:14: warning: unused variable 'dt_mac_addr' [-Wunused-variable]
     const char *dt_mac_addr;
                 ^~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/mvpp2_port_copy_mac_addr +7618 drivers/net/ethernet/marvell/mvpp2.c

3ba8c81e1 Antoine Tenart   2017-09-02  7495  
3f518509d Marcin Wojtas    2014-07-10  7496  /* Ports initialization */
3f518509d Marcin Wojtas    2014-07-10  7497  static int mvpp2_port_probe(struct platform_device *pdev,
3f518509d Marcin Wojtas    2014-07-10  7498  			    struct device_node *port_node,
59b9a31ed Thomas Petazzoni 2017-03-07  7499  			    struct mvpp2 *priv)
3f518509d Marcin Wojtas    2014-07-10  7500  {
3f518509d Marcin Wojtas    2014-07-10  7501  	struct device_node *phy_node;
542897d98 Antoine Tenart   2017-08-30  7502  	struct phy *comphy;
3f518509d Marcin Wojtas    2014-07-10  7503  	struct mvpp2_port *port;
edc660fa0 Marcin Wojtas    2015-08-06  7504  	struct mvpp2_port_pcpu *port_pcpu;
3f518509d Marcin Wojtas    2014-07-10  7505  	struct net_device *dev;
3f518509d Marcin Wojtas    2014-07-10  7506  	struct resource *res;
3f518509d Marcin Wojtas    2014-07-10  7507  	const char *dt_mac_addr;
96c036180 Bob Copeland     2017-09-04  7508  	const char *mac_from = "";
4c2286826 Antoine Tenart   2017-08-25  7509  	char hw_mac_addr[ETH_ALEN] = {0};
09f839755 Thomas Petazzoni 2017-08-03  7510  	unsigned int ntxqs, nrxqs;
213f428f5 Thomas Petazzoni 2017-08-03  7511  	bool has_tx_irqs;
3f518509d Marcin Wojtas    2014-07-10  7512  	u32 id;
3f518509d Marcin Wojtas    2014-07-10  7513  	int features;
3f518509d Marcin Wojtas    2014-07-10  7514  	int phy_mode;
edc660fa0 Marcin Wojtas    2015-08-06  7515  	int err, i, cpu;
3f518509d Marcin Wojtas    2014-07-10  7516  
213f428f5 Thomas Petazzoni 2017-08-03  7517  	has_tx_irqs = mvpp2_port_has_tx_irqs(priv, port_node);
213f428f5 Thomas Petazzoni 2017-08-03  7518  
213f428f5 Thomas Petazzoni 2017-08-03  7519  	if (!has_tx_irqs)
213f428f5 Thomas Petazzoni 2017-08-03  7520  		queue_mode = MVPP2_QDIST_SINGLE_MODE;
213f428f5 Thomas Petazzoni 2017-08-03  7521  
09f839755 Thomas Petazzoni 2017-08-03  7522  	ntxqs = MVPP2_MAX_TXQ;
213f428f5 Thomas Petazzoni 2017-08-03  7523  	if (priv->hw_version == MVPP22 && queue_mode == MVPP2_QDIST_MULTI_MODE)
213f428f5 Thomas Petazzoni 2017-08-03  7524  		nrxqs = MVPP2_DEFAULT_RXQ * num_possible_cpus();
213f428f5 Thomas Petazzoni 2017-08-03  7525  	else
09f839755 Thomas Petazzoni 2017-08-03  7526  		nrxqs = MVPP2_DEFAULT_RXQ;
09f839755 Thomas Petazzoni 2017-08-03  7527  
09f839755 Thomas Petazzoni 2017-08-03  7528  	dev = alloc_etherdev_mqs(sizeof(*port), ntxqs, nrxqs);
3f518509d Marcin Wojtas    2014-07-10  7529  	if (!dev)
3f518509d Marcin Wojtas    2014-07-10  7530  		return -ENOMEM;
3f518509d Marcin Wojtas    2014-07-10  7531  
3f518509d Marcin Wojtas    2014-07-10  7532  	phy_node = of_parse_phandle(port_node, "phy", 0);
3f518509d Marcin Wojtas    2014-07-10  7533  	phy_mode = of_get_phy_mode(port_node);
3f518509d Marcin Wojtas    2014-07-10  7534  	if (phy_mode < 0) {
3f518509d Marcin Wojtas    2014-07-10  7535  		dev_err(&pdev->dev, "incorrect phy mode\n");
3f518509d Marcin Wojtas    2014-07-10  7536  		err = phy_mode;
3f518509d Marcin Wojtas    2014-07-10  7537  		goto err_free_netdev;
3f518509d Marcin Wojtas    2014-07-10  7538  	}
3f518509d Marcin Wojtas    2014-07-10  7539  
542897d98 Antoine Tenart   2017-08-30  7540  	comphy = devm_of_phy_get(&pdev->dev, port_node, NULL);
542897d98 Antoine Tenart   2017-08-30  7541  	if (IS_ERR(comphy)) {
542897d98 Antoine Tenart   2017-08-30  7542  		if (PTR_ERR(comphy) == -EPROBE_DEFER) {
542897d98 Antoine Tenart   2017-08-30  7543  			err = -EPROBE_DEFER;
542897d98 Antoine Tenart   2017-08-30  7544  			goto err_free_netdev;
542897d98 Antoine Tenart   2017-08-30  7545  		}
542897d98 Antoine Tenart   2017-08-30  7546  		comphy = NULL;
542897d98 Antoine Tenart   2017-08-30  7547  	}
542897d98 Antoine Tenart   2017-08-30  7548  
3f518509d Marcin Wojtas    2014-07-10  7549  	if (of_property_read_u32(port_node, "port-id", &id)) {
3f518509d Marcin Wojtas    2014-07-10  7550  		err = -EINVAL;
3f518509d Marcin Wojtas    2014-07-10  7551  		dev_err(&pdev->dev, "missing port-id value\n");
3f518509d Marcin Wojtas    2014-07-10  7552  		goto err_free_netdev;
3f518509d Marcin Wojtas    2014-07-10  7553  	}
3f518509d Marcin Wojtas    2014-07-10  7554  
3f518509d Marcin Wojtas    2014-07-10  7555  	dev->tx_queue_len = MVPP2_MAX_TXD;
3f518509d Marcin Wojtas    2014-07-10  7556  	dev->watchdog_timeo = 5 * HZ;
3f518509d Marcin Wojtas    2014-07-10  7557  	dev->netdev_ops = &mvpp2_netdev_ops;
3f518509d Marcin Wojtas    2014-07-10  7558  	dev->ethtool_ops = &mvpp2_eth_tool_ops;
3f518509d Marcin Wojtas    2014-07-10  7559  
3f518509d Marcin Wojtas    2014-07-10  7560  	port = netdev_priv(dev);
591f4cfab Thomas Petazzoni 2017-08-03  7561  	port->dev = dev;
09f839755 Thomas Petazzoni 2017-08-03  7562  	port->ntxqs = ntxqs;
09f839755 Thomas Petazzoni 2017-08-03  7563  	port->nrxqs = nrxqs;
213f428f5 Thomas Petazzoni 2017-08-03  7564  	port->priv = priv;
213f428f5 Thomas Petazzoni 2017-08-03  7565  	port->has_tx_irqs = has_tx_irqs;
3f518509d Marcin Wojtas    2014-07-10  7566  
591f4cfab Thomas Petazzoni 2017-08-03  7567  	err = mvpp2_queue_vectors_init(port, port_node);
591f4cfab Thomas Petazzoni 2017-08-03  7568  	if (err)
3f518509d Marcin Wojtas    2014-07-10  7569  		goto err_free_netdev;
3f518509d Marcin Wojtas    2014-07-10  7570  
fd3651b2a Antoine Tenart   2017-09-01  7571  	port->link_irq = of_irq_get_byname(port_node, "link");
fd3651b2a Antoine Tenart   2017-09-01  7572  	if (port->link_irq == -EPROBE_DEFER) {
fd3651b2a Antoine Tenart   2017-09-01  7573  		err = -EPROBE_DEFER;
fd3651b2a Antoine Tenart   2017-09-01  7574  		goto err_deinit_qvecs;
fd3651b2a Antoine Tenart   2017-09-01  7575  	}
fd3651b2a Antoine Tenart   2017-09-01  7576  	if (port->link_irq <= 0)
fd3651b2a Antoine Tenart   2017-09-01  7577  		/* the link irq is optional */
fd3651b2a Antoine Tenart   2017-09-01  7578  		port->link_irq = 0;
fd3651b2a Antoine Tenart   2017-09-01  7579  
3f518509d Marcin Wojtas    2014-07-10  7580  	if (of_property_read_bool(port_node, "marvell,loopback"))
3f518509d Marcin Wojtas    2014-07-10  7581  		port->flags |= MVPP2_F_LOOPBACK;
3f518509d Marcin Wojtas    2014-07-10  7582  
3f518509d Marcin Wojtas    2014-07-10  7583  	port->id = id;
59b9a31ed Thomas Petazzoni 2017-03-07  7584  	if (priv->hw_version == MVPP21)
09f839755 Thomas Petazzoni 2017-08-03  7585  		port->first_rxq = port->id * port->nrxqs;
59b9a31ed Thomas Petazzoni 2017-03-07  7586  	else
59b9a31ed Thomas Petazzoni 2017-03-07  7587  		port->first_rxq = port->id * priv->max_port_rxqs;
59b9a31ed Thomas Petazzoni 2017-03-07  7588  
3f518509d Marcin Wojtas    2014-07-10  7589  	port->phy_node = phy_node;
3f518509d Marcin Wojtas    2014-07-10  7590  	port->phy_interface = phy_mode;
542897d98 Antoine Tenart   2017-08-30  7591  	port->comphy = comphy;
3f518509d Marcin Wojtas    2014-07-10  7592  
a786841df Thomas Petazzoni 2017-03-07  7593  	if (priv->hw_version == MVPP21) {
a786841df Thomas Petazzoni 2017-03-07  7594  		res = platform_get_resource(pdev, IORESOURCE_MEM, 2 + id);
3f518509d Marcin Wojtas    2014-07-10  7595  		port->base = devm_ioremap_resource(&pdev->dev, res);
3f518509d Marcin Wojtas    2014-07-10  7596  		if (IS_ERR(port->base)) {
3f518509d Marcin Wojtas    2014-07-10  7597  			err = PTR_ERR(port->base);
fd3651b2a Antoine Tenart   2017-09-01  7598  			goto err_free_irq;
3f518509d Marcin Wojtas    2014-07-10  7599  		}
a786841df Thomas Petazzoni 2017-03-07  7600  	} else {
a786841df Thomas Petazzoni 2017-03-07  7601  		if (of_property_read_u32(port_node, "gop-port-id",
a786841df Thomas Petazzoni 2017-03-07  7602  					 &port->gop_id)) {
a786841df Thomas Petazzoni 2017-03-07  7603  			err = -EINVAL;
a786841df Thomas Petazzoni 2017-03-07  7604  			dev_err(&pdev->dev, "missing gop-port-id value\n");
591f4cfab Thomas Petazzoni 2017-08-03  7605  			goto err_deinit_qvecs;
a786841df Thomas Petazzoni 2017-03-07  7606  		}
a786841df Thomas Petazzoni 2017-03-07  7607  
a786841df Thomas Petazzoni 2017-03-07  7608  		port->base = priv->iface_base + MVPP22_GMAC_BASE(port->gop_id);
a786841df Thomas Petazzoni 2017-03-07  7609  	}
3f518509d Marcin Wojtas    2014-07-10  7610  
3f518509d Marcin Wojtas    2014-07-10  7611  	/* Alloc per-cpu stats */
3f518509d Marcin Wojtas    2014-07-10  7612  	port->stats = netdev_alloc_pcpu_stats(struct mvpp2_pcpu_stats);
3f518509d Marcin Wojtas    2014-07-10  7613  	if (!port->stats) {
3f518509d Marcin Wojtas    2014-07-10  7614  		err = -ENOMEM;
fd3651b2a Antoine Tenart   2017-09-01  7615  		goto err_free_irq;
3f518509d Marcin Wojtas    2014-07-10  7616  	}
3f518509d Marcin Wojtas    2014-07-10  7617  
3ba8c81e1 Antoine Tenart   2017-09-02 @7618  	mvpp2_port_copy_mac_addr(dev, priv, port_node, &mac_from);
3f518509d Marcin Wojtas    2014-07-10  7619  
3f518509d Marcin Wojtas    2014-07-10  7620  	port->tx_ring_size = MVPP2_MAX_TXD;
3f518509d Marcin Wojtas    2014-07-10  7621  	port->rx_ring_size = MVPP2_MAX_RXD;
3f518509d Marcin Wojtas    2014-07-10  7622  	SET_NETDEV_DEV(dev, &pdev->dev);
3f518509d Marcin Wojtas    2014-07-10  7623  
3f518509d Marcin Wojtas    2014-07-10  7624  	err = mvpp2_port_init(port);
3f518509d Marcin Wojtas    2014-07-10  7625  	if (err < 0) {
3f518509d Marcin Wojtas    2014-07-10  7626  		dev_err(&pdev->dev, "failed to init port %d\n", id);
3f518509d Marcin Wojtas    2014-07-10  7627  		goto err_free_stats;
3f518509d Marcin Wojtas    2014-07-10  7628  	}
269758214 Thomas Petazzoni 2017-03-07  7629  
269758214 Thomas Petazzoni 2017-03-07  7630  	mvpp2_port_periodic_xon_disable(port);
269758214 Thomas Petazzoni 2017-03-07  7631  
269758214 Thomas Petazzoni 2017-03-07  7632  	if (priv->hw_version == MVPP21)
269758214 Thomas Petazzoni 2017-03-07  7633  		mvpp2_port_fc_adv_enable(port);
269758214 Thomas Petazzoni 2017-03-07  7634  
269758214 Thomas Petazzoni 2017-03-07  7635  	mvpp2_port_reset(port);
3f518509d Marcin Wojtas    2014-07-10  7636  
edc660fa0 Marcin Wojtas    2015-08-06  7637  	port->pcpu = alloc_percpu(struct mvpp2_port_pcpu);
edc660fa0 Marcin Wojtas    2015-08-06  7638  	if (!port->pcpu) {
edc660fa0 Marcin Wojtas    2015-08-06  7639  		err = -ENOMEM;
edc660fa0 Marcin Wojtas    2015-08-06  7640  		goto err_free_txq_pcpu;
edc660fa0 Marcin Wojtas    2015-08-06  7641  	}
edc660fa0 Marcin Wojtas    2015-08-06  7642  
213f428f5 Thomas Petazzoni 2017-08-03  7643  	if (!port->has_tx_irqs) {
edc660fa0 Marcin Wojtas    2015-08-06  7644  		for_each_present_cpu(cpu) {
edc660fa0 Marcin Wojtas    2015-08-06  7645  			port_pcpu = per_cpu_ptr(port->pcpu, cpu);
edc660fa0 Marcin Wojtas    2015-08-06  7646  
edc660fa0 Marcin Wojtas    2015-08-06  7647  			hrtimer_init(&port_pcpu->tx_done_timer, CLOCK_MONOTONIC,
edc660fa0 Marcin Wojtas    2015-08-06  7648  				     HRTIMER_MODE_REL_PINNED);
edc660fa0 Marcin Wojtas    2015-08-06  7649  			port_pcpu->tx_done_timer.function = mvpp2_hr_timer_cb;
edc660fa0 Marcin Wojtas    2015-08-06  7650  			port_pcpu->timer_scheduled = false;
edc660fa0 Marcin Wojtas    2015-08-06  7651  
213f428f5 Thomas Petazzoni 2017-08-03  7652  			tasklet_init(&port_pcpu->tx_done_tasklet,
213f428f5 Thomas Petazzoni 2017-08-03  7653  				     mvpp2_tx_proc_cb,
edc660fa0 Marcin Wojtas    2015-08-06  7654  				     (unsigned long)dev);
edc660fa0 Marcin Wojtas    2015-08-06  7655  		}
213f428f5 Thomas Petazzoni 2017-08-03  7656  	}
edc660fa0 Marcin Wojtas    2015-08-06  7657  
186cd4d4e Antoine Tenart   2017-08-23  7658  	features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
3f518509d Marcin Wojtas    2014-07-10  7659  	dev->features = features | NETIF_F_RXCSUM;
3f518509d Marcin Wojtas    2014-07-10  7660  	dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO;
3f518509d Marcin Wojtas    2014-07-10  7661  	dev->vlan_features |= features;
3f518509d Marcin Wojtas    2014-07-10  7662  
5777987e0 Jarod Wilson     2016-10-17  7663  	/* MTU range: 68 - 9676 */
5777987e0 Jarod Wilson     2016-10-17  7664  	dev->min_mtu = ETH_MIN_MTU;
5777987e0 Jarod Wilson     2016-10-17  7665  	/* 9676 == 9700 - 20 and rounding to 8 */
5777987e0 Jarod Wilson     2016-10-17  7666  	dev->max_mtu = 9676;
5777987e0 Jarod Wilson     2016-10-17  7667  
3f518509d Marcin Wojtas    2014-07-10  7668  	err = register_netdev(dev);
3f518509d Marcin Wojtas    2014-07-10  7669  	if (err < 0) {
3f518509d Marcin Wojtas    2014-07-10  7670  		dev_err(&pdev->dev, "failed to register netdev\n");
edc660fa0 Marcin Wojtas    2015-08-06  7671  		goto err_free_port_pcpu;
3f518509d Marcin Wojtas    2014-07-10  7672  	}
3f518509d Marcin Wojtas    2014-07-10  7673  	netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr);
3f518509d Marcin Wojtas    2014-07-10  7674  
3f518509d Marcin Wojtas    2014-07-10  7675  	priv->port_list[id] = port;
3f518509d Marcin Wojtas    2014-07-10  7676  	return 0;
3f518509d Marcin Wojtas    2014-07-10  7677  
edc660fa0 Marcin Wojtas    2015-08-06  7678  err_free_port_pcpu:
edc660fa0 Marcin Wojtas    2015-08-06  7679  	free_percpu(port->pcpu);
3f518509d Marcin Wojtas    2014-07-10  7680  err_free_txq_pcpu:
09f839755 Thomas Petazzoni 2017-08-03  7681  	for (i = 0; i < port->ntxqs; i++)
3f518509d Marcin Wojtas    2014-07-10  7682  		free_percpu(port->txqs[i]->pcpu);
3f518509d Marcin Wojtas    2014-07-10  7683  err_free_stats:
3f518509d Marcin Wojtas    2014-07-10  7684  	free_percpu(port->stats);
fd3651b2a Antoine Tenart   2017-09-01  7685  err_free_irq:
fd3651b2a Antoine Tenart   2017-09-01  7686  	if (port->link_irq)
fd3651b2a Antoine Tenart   2017-09-01  7687  		irq_dispose_mapping(port->link_irq);
591f4cfab Thomas Petazzoni 2017-08-03  7688  err_deinit_qvecs:
591f4cfab Thomas Petazzoni 2017-08-03  7689  	mvpp2_queue_vectors_deinit(port);
3f518509d Marcin Wojtas    2014-07-10  7690  err_free_netdev:
ccb80393c Peter Chen       2016-08-01  7691  	of_node_put(phy_node);
3f518509d Marcin Wojtas    2014-07-10  7692  	free_netdev(dev);
3f518509d Marcin Wojtas    2014-07-10  7693  	return err;
3f518509d Marcin Wojtas    2014-07-10  7694  }
3f518509d Marcin Wojtas    2014-07-10  7695  

:::::: The code at line 7618 was first introduced by commit
:::::: 3ba8c81e15c11fc396d0b5d11adaf9db6ed39533 net: mvpp2: move the mac retrieval/copy logic into its own function

:::::: TO: Antoine Tenart <antoine.tenart@free-electrons.com>
:::::: CC: David S. Miller <davem@davemloft.net>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 51551 bytes --]

^ permalink raw reply

* Re: [wireless-testsing2:master 4/5] drivers/net/ethernet/marvell/mvpp2.c:7618:49: error: passing argument 4 of 'mvpp2_port_copy_mac_addr' from incompatible pointer type
From: Bob Copeland @ 2017-09-05 13:29 UTC (permalink / raw)
  To: kbuild test robot; +Cc: David S. Miller, kbuild-all, netdev
In-Reply-To: <201709052144.zyrDXrmL%fengguang.wu@intel.com>


My fault, mismerged a driver conflict -- will fix in next w-t build.

On Tue, Sep 05, 2017 at 09:16:48PM +0800, kbuild test robot wrote:
> tree:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-testing.git master
> head:   d17be7f7503bf9492198a242779a68af93fd92de
> commit: 96c03618031bae5e9068b16f9e437b79f98f6482 [4/5] Merge remote-tracking branch 'mac80211-next/master'
> config: ia64-allyesconfig (attached as .config)
> compiler: ia64-linux-gcc (GCC) 6.2.0
> reproduce:
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         git checkout 96c03618031bae5e9068b16f9e437b79f98f6482
>         # save the attached .config to linux build tree
>         make.cross ARCH=ia64 
> 
> All errors (new ones prefixed by >>):
> 
>    drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_port_probe':
> >> drivers/net/ethernet/marvell/mvpp2.c:7618:49: error: passing argument 4 of 'mvpp2_port_copy_mac_addr' from incompatible pointer type [-Werror=incompatible-pointer-types]
>      mvpp2_port_copy_mac_addr(dev, priv, port_node, &mac_from);

-- 
Bob Copeland %% https://bobcopeland.com/

^ permalink raw reply

* Re: [PATCH net-next v6 3/3] openvswitch: enable NSH support
From: Hannes Frederic Sowa @ 2017-09-05 13:34 UTC (permalink / raw)
  To: Jan Scheurich
  Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org,
	netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	jbenc-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org, e@erig.me
In-Reply-To: <CFF8EF42F1132E4CBE2BF0AB6C21C58D787F5650-hqolJogE5njKJFWPz4pdheaU1rCVNFv4@public.gmane.org>

Hello Jan,

Jan Scheurich <jan.scheurich-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org> writes:

> Please have a look at the Google doc that sketches the overall
> solution to support NSH in OVS.
> https://drive.google.com/open?id=1oWMYUH8sjZJzWa72o2q9kU0N6pNE-rwZcLH3-kbbDR8
>
> In details it is slightly outdated but the NSH MD1 support (and all
> prerequisites like PTAP and Generic Encap/Decap) have been implemented
> in OVS 2.8 (ofproto layer and the userspace datapath).
>
> The NSH use cases are discussed in the chapter "Support for NSH". OVS
> is primarily targeting the Classifier and SFF use cases. Obviously the
> classifier must be able to set the MD1 context headers. The final SFF
> must be able to inspect the context headers, typically to determine
> the L2 or L3 forwarding context (e.g. VRF) in which to forward the
> decapsulated packet on to its final destination.

>From Yi Yang's mail I understood that you put a tunnel ID into
context[0]. In this case, I can understand that you want to match on
that. I was under the impression that the combination of tenant id from
the vxlan-gpe header and the path id plus ttl would give enough state
for the SDN to keep state on where the packet is in the network. I don't
understand what a tunnel id is.

I understood that the context fields are usable by the service function
chains, but they are actually in use by the outer SDN and basically
standardized.

> This information has end-to-end significance for the SFP and is
> encoded by the classifier in the NSH context headers. It cannot be put
> into transport tunnel options of e.g. a Geneve tunnel connecting two
> SFFs along the SFP.

Because the TLVs are not end to end in the geneve case? Yes, this makes
sense.

> We are now trying to establish feature parity in the kernel
> datapath. If the kernel datapath chooses not to support the MD1
> fields, OVS with kernel datapath will not be able to address the
> classifier and final SFF use cases.

As I understand this now, you are designing some kind of protocol or
particular implementation on top of NSH. Thus you don't expect masks to
grow limitless and you don't allow any SFC elements to take part in the
decision what to communicate over the context fields.

I still wonder about the hash as part of the NSH context and how that
fits into the picture, which looked like the only standardized
application of context headers from your google doc.

Btw., I don't want to block this patch.

Bye,
Hannes

^ permalink raw reply

* Re: [RFC net-next] net: sch_clsact: add support for global per-netns classifier mode
From: Jiri Pirko @ 2017-09-05 14:07 UTC (permalink / raw)
  To: Nikolay Aleksandrov; +Cc: netdev, roopa, dsa, xiyou.wangcong, jhs
In-Reply-To: <1504615701-20912-1-git-send-email-nikolay@cumulusnetworks.com>

Tue, Sep 05, 2017 at 02:48:21PM CEST, nikolay@cumulusnetworks.com wrote:
>Hi all,
>This RFC adds a new mode for clsact which designates a device's egress
>classifier as global per netns. The packets that are not classified for
>a particular device will be classified using the global classifier.
>We have needed a global classifier for some time now for various
>purposes and setting the single bridge or loopback/vrf device as the
>global classifier device is acceptable for us. Doing it this way avoids
>the act/cls device and queue dependencies.
>
>This is strictly an RFC patch just to show the intent, if we agree on
>the details the proposed patch will have support for both ingress and
>egress, and will be using a static key to avoid the fast path test when no
>global classifier has been configured.
>
>Example (need a modified tc that adds TCA_OPTIONS when using q_clsact):
>$ tc qdisc add dev lo clsact global
>$ tc filter add dev lo egress protocol ip u32 match ip dst 4.3.2.1/32 action drop
>
>the last filter will be global for all devices that don't have a
>specific egress_cl_list (i.e. have clsact configured).
>
>Any comments and thoughts would be greatly appreciated.

Did you see my shared blocks work? I believe that it should resolve your
usecase, in a generic way. You just have to bind the devices you need to
the shared block. Please see the RFC:

https://www.spinics.net/lists/netdev/msg444067.html

^ permalink raw reply

* Re: [PATCH net-next] virtio-net: invoke zerocopy callback on xmit path if no tx napi
From: Willem de Bruijn @ 2017-09-05 14:09 UTC (permalink / raw)
  To: Jason Wang
  Cc: Network Development, virtualization, Koichiro Den,
	Michael S. Tsirkin
In-Reply-To: <96819b6a-6d44-fd7e-37af-5a0db81b3840@redhat.com>

On Mon, Sep 4, 2017 at 5:03 AM, Jason Wang <jasowang@redhat.com> wrote:
>
>
> On 2017年09月02日 00:17, Willem de Bruijn wrote:
>>>>>
>>>>> This is not a 50/50 split, which impliesTw that some packets from the
>>>>> large
>>>>> packet flow are still converted to copying. Without the change the rate
>>>>> without queue was 80k zerocopy vs 80k copy, so this choice of
>>>>> (vq->num >> 2) appears too conservative.
>>>>>
>>>>> However, testing with (vq->num >> 1) was not as effective at mitigating
>>>>> stalls. I did not save that data, unfortunately. Can run more tests on
>>>>> fine
>>>>> tuning this variable, if the idea sounds good.
>>>>
>>>>
>>>> Looks like there're still two cases were left:
>>>
>>> To be clear, this patch is not intended to fix all issues. It is a small
>>> improvement to avoid HoL blocking due to queued zerocopy skbs.
>
>
> Right, just want to see if there's anything left.
>
>>>
>>> The trade-off is that reverting to copying in these cases increases
>>> cycle cost. I think that that is a trade-off worth making compared to
>>> the alternative drop in throughput. It probably would be good to be
>>> able to measure this without kernel instrumentation: export
>>> counters similar to net->tx_zcopy_err and net->tx_packets (though
>>> without reset to zero, as in vhost_net_tx_packet).
>
>
> I think it's acceptable if extra cycles were spent if we detect HOL anyhow.
>
>>>
>>>> 1) sndbuf is not INT_MAX
>>>
>>> You mean the case where the device stalls, later zerocopy notifications
>>> are queued, but these are never cleaned in free_old_xmit_skbs,
>>> because it requires a start_xmit and by now the (only) socket is out of
>>> descriptors?
>>
>> Typo, sorry. I meant out of sndbuf.
>
>
> I mean e.g for tun. If its sndbuf is smaller than e.g (vq->num >> 1) *
> $pkt_size and if all packet were held by some modules, limitation like
> vq->num >> 1 won't work since we hit sudbuf before it.

Good point.

>>
>>> A watchdog would help somewhat. With tx-napi, this case cannot occur,
>>> either, as free_old_xmit_skbs no longer depends on a call to start_xmit.
>>>
>>>> 2) tx napi is used for virtio-net
>>>
>>> I am not aware of any issue specific to the use of tx-napi?
>
>
> Might not be clear here, I mean e.g virtio_net (tx-napi) in guest +
> vhost_net (zerocopy) in host. In this case, even if we switch to datacopy if
> ubuf counts exceeds vq->num >> 1, we still complete tx buffers in order, tx
> interrupt could be delayed for indefinite time.

Copied buffers are completed immediately in handle_tx.

Do you mean when a process sends fewer packets than vq->num >> 1,
so that all are queued? Yes, then the latency is indeed that of the last
element leaving the qdisc.

>>>
>>>> 1) could be a corner case, and for 2) what your suggest here may not
>>>> solve
>>>> the issue since it still do in order completion.
>>>
>>> Somewhat tangential, but it might also help to break the in-order
>>> completion processing in vhost_zerocopy_signal_used. Complete
>>> all descriptors between done_idx and upend_idx. done_idx should
>>> then only be forward to the oldest still not-completed descriptor.
>>>
>>> In the test I ran, where the oldest descriptors are held in a queue and
>>> all newer ones are tail-dropped,
>
>
> Do you mean the descriptors were tail-dropped by vhost?

Tail-dropped by netem. The dropped items are completed out of
order by vhost before the held items.
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply

* Re: [PATCH net] net: sched: don't use GFP_KERNEL under spin lock
From: Eric Dumazet @ 2017-09-05 14:10 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev, jiri, Chris Mi, xiyou.wangcong, jhs, oss-drivers
In-Reply-To: <20170905105442.30972-1-jakub.kicinski@netronome.com>

On Tue, 2017-09-05 at 03:54 -0700, Jakub Kicinski wrote:
> The new TC IDR code uses GFP_KERNEL under spinlocks.  Which leads
> to:

> ...
> 
> Fixes: 65a206c01e8e ("net/sched: Change act_api and act_xxx modules to use IDR")
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> Reviewed-by: Simon Horman <simon.horman@netronome.com>
> ---
>  net/sched/act_api.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> index 0eb545bcb247..a48e4b45722d 100644
> --- a/net/sched/act_api.c
> +++ b/net/sched/act_api.c
> @@ -298,7 +298,7 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
>  	if (!index) {


		idr_preload(GFP_KERNEL);

>  		spin_lock_bh(&idrinfo->lock);
>  		err = idr_alloc_ext(idr, NULL, &idr_index, 1, 0,
> -				    GFP_KERNEL);
> +				    GFP_ATOMIC);
>  		spin_unlock_bh(&idrinfo->lock);
>  		if (err) {
>  err3:
> @@ -309,7 +309,7 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
>  	} else {

		idr_preload(GFP_KERNEL);

>  		spin_lock_bh(&idrinfo->lock);
>  		err = idr_alloc_ext(idr, NULL, NULL, index, index + 1,
> -				    GFP_KERNEL);
> +				    GFP_ATOMIC);
>  		spin_unlock_bh(&idrinfo->lock);
>  		if (err)
>  			goto err3;

^ permalink raw reply

* VLAN/bridge "compression" in wifi (was: Re: [PATCH 3/8] qtnfmac: implement AP_VLAN iftype support)
From: Johannes Berg @ 2017-09-05 14:20 UTC (permalink / raw)
  To: Sergey Matyukevich, linux-wireless-u79uwXL29TY76Z2rM5mHXA, netdev
  Cc: Igor Mitsyanko, Avinash Patil
In-Reply-To: <1504619151.12380.16.camel-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>

+netdev

On Tue, 2017-09-05 at 15:45 +0200, Johannes Berg wrote:
> 
> In a way this feature seems mis-designed - you never have 802.1Q tags
> over the air, but you're inserting them on RX and stripping them on
> TX, probably in order to make bridging to ethernet easier and not
> have to have 802.1Q acceleration on the ethernet port, or - well - in
> order to have an ability to do this with an ethernet card that only
> has a single CPU port.

Ok this isn't really right either - it's only for saving the 802.1Q
acceleration on the Ethernet port, really - and saving the extra
bridges.

To clarify, I think what you - conceptually - want is the following
topology:

        +--- eth0.1  ---  br.1  ---  wlan0.1
        |
eth0 ---+--- eth0.2  ---  br.2  ---  wlan0.2
        | 
        +--- eth0.3  ---  br.3  ---  wlan0.3

where eth0.N is just "ip link add link eth0 name eth0.N type vlan id N"
and br.N is obviously a bridge for each, and the wlan0.N are AP_VLAN
type interfaces that isolate the clients against each other as far as
wifi is concerned.

Is this correct? As far as I understand, that's the baseline topology
that you're trying to achieve, expressed in terms of Linux networking.

Now, you seem to want to compress this to

                  +---  wlan0.1
                  |
eth0  ---  br  ---+---  wlan0.2
                  |
                  +---  wlan0.3

and have the 802.1Q tag insertion/removal that's normally configured to
happen in eth0.N already be handled in wlan0.N.

Also correct?


We clearly don't have APIs for this, and I don't think it makes sense
in the Linux space - the bridge and wlan0.N suddenly have tagged
traffic rather than untagged, and the VLAN tagging is completely hidden
from the management view.

johannes

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox