All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v3 7/8] test_firmware: Error injection for firmware upload
@ 2022-04-19 13:01 kernel test robot
  0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2022-04-19 13:01 UTC (permalink / raw)
  To: kbuild

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

CC: kbuild-all(a)lists.01.org
BCC: lkp(a)intel.com
In-Reply-To: <20220418223753.639058-8-russell.h.weight@intel.com>
References: <20220418223753.639058-8-russell.h.weight@intel.com>
TO: Russ Weight <russell.h.weight@intel.com>
TO: mcgrof(a)kernel.org
TO: rafael(a)kernel.org
TO: linux-kernel(a)vger.kernel.org
CC: trix(a)redhat.com
CC: lgoncalv(a)redhat.com
CC: yilun.xu(a)intel.com
CC: hao.wu(a)intel.com
CC: matthew.gerlach(a)linux.intel.com
CC: basheer.ahmed.muddebihal(a)intel.com
CC: tianfei.zhang(a)intel.com
CC: Russ Weight <russell.h.weight@intel.com>

Hi Russ,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on driver-core/driver-core-testing]
[also build test WARNING on shuah-kselftest/next mcgrof/sysctl-next linus/master v5.18-rc3 next-20220419]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Russ-Weight/Extend-FW-framework-for-user-FW-uploads/20220419-064126
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git 3123109284176b1532874591f7c81f3837bbdc17
:::::: branch date: 14 hours ago
:::::: commit date: 14 hours ago
compiler: mipsel-linux-gcc (GCC) 11.2.0
reproduce (cppcheck warning):
        # apt-get install cppcheck
        git checkout 2cf984eba934c1a6b1bcfc317886e89180bcb5e3
        cppcheck --quiet --enable=style,performance,portability --template=gcc FILE

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


cppcheck possible warnings: (new ones prefixed by >>, may not real problems)

>> lib/test_firmware.c:1071:18: warning: Uninitialized variables: tst.name, tst.buf, tst.size, tst.cancel_request, tst.inject, tst.fwl [uninitvar]
     upload_release(tst);
                    ^

vim +1071 lib/test_firmware.c

cb4d12e8d75964 Russ Weight 2022-04-18  1064  
cb4d12e8d75964 Russ Weight 2022-04-18  1065  static void upload_release_all(void)
cb4d12e8d75964 Russ Weight 2022-04-18  1066  {
cb4d12e8d75964 Russ Weight 2022-04-18  1067  	struct test_firmware_upload *tst, *tmp;
cb4d12e8d75964 Russ Weight 2022-04-18  1068  
cb4d12e8d75964 Russ Weight 2022-04-18  1069  	list_for_each_entry_safe(tst, tmp, &test_upload_list, node) {
cb4d12e8d75964 Russ Weight 2022-04-18  1070  		list_del(&tst->node);
cb4d12e8d75964 Russ Weight 2022-04-18 @1071  		upload_release(tst);
cb4d12e8d75964 Russ Weight 2022-04-18  1072  	}
cb4d12e8d75964 Russ Weight 2022-04-18  1073  	test_fw_config->upload_name = NULL;
cb4d12e8d75964 Russ Weight 2022-04-18  1074  }
cb4d12e8d75964 Russ Weight 2022-04-18  1075  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH v3 7/8] test_firmware: Error injection for firmware upload
  2022-04-18 22:37 [PATCH v3 0/8] Extend FW framework for user FW uploads Russ Weight
@ 2022-04-18 22:37 ` Russ Weight
  0 siblings, 0 replies; 2+ messages in thread
From: Russ Weight @ 2022-04-18 22:37 UTC (permalink / raw)
  To: mcgrof, rafael, linux-kernel
  Cc: trix, lgoncalv, yilun.xu, hao.wu, matthew.gerlach,
	basheer.ahmed.muddebihal, tianfei.zhang, Russ Weight

Add error injection capability to the test_firmware module specifically
for firmware upload testing. Error injection instructions are transferred
as the first part of the firmware payload. The format of an error
injection string is similar to the error strings that may be read from
the error sysfs node.

To inject the error "programming:hw-error", one would use the error
injection string "inject:programming:hw-error" as the firmware payload:

$ echo 1 > loading
$ echo inject:programming:hw-error > data
$ echo 0 > loading
$ cat status
idle
$ cat error
programming:hw-error

The first part of the error string is the progress state of the upload at
the time of the error. The progress state would be one of the following:
"preparing", "transferring", or "programming". The second part of the
error string is one of the following: "hw-error", "timeout", "device-busy",
"invalid-file-size", "read-write-error", "flash-wearout", and "user-abort".

Note that all of the error strings except "user-abort" will fail without
delay. The "user-abort" error will cause the firmware upload to stall at
the requested progress state for up to 5 minutes to allow you to echo 1
to the cancel sysfs node. It is this cancellation that causes the
'user-abort" error. If the upload is not cancelled within the 5 minute
time period, then the upload will complete without an error.

Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Signed-off-by: Russ Weight <russell.h.weight@intel.com>
---
v2:
  - No changes from v1
v3:
  - Added Reviewed-by tag
---
 lib/test_firmware.c | 127 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 122 insertions(+), 5 deletions(-)

diff --git a/lib/test_firmware.c b/lib/test_firmware.c
index 2b8c56d7bf37..76115c1a2629 100644
--- a/lib/test_firmware.c
+++ b/lib/test_firmware.c
@@ -117,12 +117,18 @@ struct test_config {
 			    struct device *device);
 };
 
+struct upload_inject_err {
+	const char *prog;
+	enum fw_upload_err err_code;
+};
+
 struct test_firmware_upload {
 	char *name;
 	struct list_head node;
 	char *buf;
 	size_t size;
 	bool cancel_request;
+	struct upload_inject_err inject;
 	struct fw_upload *fwl;
 };
 
@@ -1067,20 +1073,105 @@ static void upload_release_all(void)
 	test_fw_config->upload_name = NULL;
 }
 
+/*
+ * This table is replicated from .../firmware_loader/sysfs_upload.c
+ * and needs to be kept in sync.
+ */
+static const char * const fw_upload_err_str[] = {
+	[FW_UPLOAD_ERR_NONE]	     = "none",
+	[FW_UPLOAD_ERR_HW_ERROR]     = "hw-error",
+	[FW_UPLOAD_ERR_TIMEOUT]	     = "timeout",
+	[FW_UPLOAD_ERR_CANCELED]     = "user-abort",
+	[FW_UPLOAD_ERR_BUSY]	     = "device-busy",
+	[FW_UPLOAD_ERR_INVALID_SIZE] = "invalid-file-size",
+	[FW_UPLOAD_ERR_RW_ERROR]     = "read-write-error",
+	[FW_UPLOAD_ERR_WEAROUT]	     = "flash-wearout",
+};
+
+static void upload_err_inject_error(struct test_firmware_upload *tst,
+				    const u8 *p, const char *prog)
+{
+	enum fw_upload_err err;
+
+	for (err = FW_UPLOAD_ERR_NONE + 1; err < FW_UPLOAD_ERR_MAX; err++) {
+		if (strncmp(p, fw_upload_err_str[err],
+			    strlen(fw_upload_err_str[err])) == 0) {
+			tst->inject.prog = prog;
+			tst->inject.err_code = err;
+			return;
+		}
+	}
+}
+
+static void upload_err_inject_prog(struct test_firmware_upload *tst,
+				   const u8 *p)
+{
+	static const char * const progs[] = {
+		"preparing:", "transferring:", "programming:"
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(progs); i++) {
+		if (strncmp(p, progs[i], strlen(progs[i])) == 0) {
+			upload_err_inject_error(tst, p + strlen(progs[i]),
+						progs[i]);
+			return;
+		}
+	}
+}
+
+#define FIVE_MINUTES_MS	(5 * 60 * 1000)
+static enum fw_upload_err
+fw_upload_wait_on_cancel(struct test_firmware_upload *tst)
+{
+	int ms_delay;
+
+	for (ms_delay = 0; ms_delay < FIVE_MINUTES_MS; ms_delay += 100) {
+		msleep(100);
+		if (tst->cancel_request)
+			return FW_UPLOAD_ERR_CANCELED;
+	}
+	return FW_UPLOAD_ERR_NONE;
+}
+
 static enum fw_upload_err test_fw_upload_prepare(struct fw_upload *fwl,
 						 const u8 *data, u32 size)
 {
 	struct test_firmware_upload *tst = fwl->dd_handle;
+	enum fw_upload_err ret = FW_UPLOAD_ERR_NONE;
+	const char *progress = "preparing:";
 
 	tst->cancel_request = false;
 
-	if (!size || size > TEST_UPLOAD_MAX_SIZE)
-		return FW_UPLOAD_ERR_INVALID_SIZE;
+	if (!size || size > TEST_UPLOAD_MAX_SIZE) {
+		ret = FW_UPLOAD_ERR_INVALID_SIZE;
+		goto err_out;
+	}
+
+	if (strncmp(data, "inject:", strlen("inject:")) == 0)
+		upload_err_inject_prog(tst, data + strlen("inject:"));
 
 	memset(tst->buf, 0, TEST_UPLOAD_MAX_SIZE);
 	tst->size = size;
 
-	return FW_UPLOAD_ERR_NONE;
+	if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
+	    strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
+		return FW_UPLOAD_ERR_NONE;
+
+	if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
+		ret = fw_upload_wait_on_cancel(tst);
+	else
+		ret = tst->inject.err_code;
+
+err_out:
+	/*
+	 * The cleanup op only executes if the prepare op succeeds.
+	 * If the prepare op fails, it must do it's own clean-up.
+	 */
+	tst->inject.err_code = FW_UPLOAD_ERR_NONE;
+	tst->inject.prog = NULL;
+
+	return ret;
 }
 
 static enum fw_upload_err test_fw_upload_write(struct fw_upload *fwl,
@@ -1088,6 +1179,7 @@ static enum fw_upload_err test_fw_upload_write(struct fw_upload *fwl,
 					       u32 size, u32 *written)
 {
 	struct test_firmware_upload *tst = fwl->dd_handle;
+	const char *progress = "transferring:";
 	u32 blk_size;
 
 	if (tst->cancel_request)
@@ -1097,17 +1189,33 @@ static enum fw_upload_err test_fw_upload_write(struct fw_upload *fwl,
 	memcpy(tst->buf + offset, data + offset, blk_size);
 
 	*written = blk_size;
-	return FW_UPLOAD_ERR_NONE;
+
+	if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
+	    strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
+		return FW_UPLOAD_ERR_NONE;
+
+	if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
+		return fw_upload_wait_on_cancel(tst);
+
+	return tst->inject.err_code;
 }
 
 static enum fw_upload_err test_fw_upload_complete(struct fw_upload *fwl)
 {
 	struct test_firmware_upload *tst = fwl->dd_handle;
+	const char *progress = "programming:";
 
 	if (tst->cancel_request)
 		return FW_UPLOAD_ERR_CANCELED;
 
-	return FW_UPLOAD_ERR_NONE;
+	if (tst->inject.err_code == FW_UPLOAD_ERR_NONE ||
+	    strncmp(tst->inject.prog, progress, strlen(progress)) != 0)
+		return FW_UPLOAD_ERR_NONE;
+
+	if (tst->inject.err_code == FW_UPLOAD_ERR_CANCELED)
+		return fw_upload_wait_on_cancel(tst);
+
+	return tst->inject.err_code;
 }
 
 static void test_fw_upload_cancel(struct fw_upload *fwl)
@@ -1117,11 +1225,20 @@ static void test_fw_upload_cancel(struct fw_upload *fwl)
 	tst->cancel_request = true;
 }
 
+static void test_fw_cleanup(struct fw_upload *fwl)
+{
+	struct test_firmware_upload *tst = fwl->dd_handle;
+
+	tst->inject.err_code = FW_UPLOAD_ERR_NONE;
+	tst->inject.prog = NULL;
+}
+
 static const struct fw_upload_ops upload_test_ops = {
 	.prepare = test_fw_upload_prepare,
 	.write = test_fw_upload_write,
 	.poll_complete = test_fw_upload_complete,
 	.cancel = test_fw_upload_cancel,
+	.cleanup = test_fw_cleanup
 };
 
 static ssize_t upload_register_store(struct device *dev,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-04-19 13:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-19 13:01 [PATCH v3 7/8] test_firmware: Error injection for firmware upload kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2022-04-18 22:37 [PATCH v3 0/8] Extend FW framework for user FW uploads Russ Weight
2022-04-18 22:37 ` [PATCH v3 7/8] test_firmware: Error injection for firmware upload Russ Weight

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.