All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v4] Refactoring aio-stress.c using LTP API
From: Andrea Cervesato via ltp @ 2022-01-05 10:05 UTC (permalink / raw)
  To: ltp

Patch-set: aio-stress.c refactoring
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 testcases/kernel/io/ltp-aiodio/aio-stress.c | 839 ++++++++++----------
 1 file changed, 402 insertions(+), 437 deletions(-)

diff --git a/testcases/kernel/io/ltp-aiodio/aio-stress.c b/testcases/kernel/io/ltp-aiodio/aio-stress.c
index 348f398db..5bb741f43 100644
--- a/testcases/kernel/io/ltp-aiodio/aio-stress.c
+++ b/testcases/kernel/io/ltp-aiodio/aio-stress.c
@@ -1,51 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) 2004 SuSE, Inc.  All Rights Reserved.
+ * Copyright (C) 2021 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- *
- * aio-stress
- *
- * will open or create each file on the command line, and start a series
+ * Will open or create each file on the command line, and start a series
  * of aio to it.
  *
- * aio is done in a rotating loop.  first file1 gets 8 requests, then
- * file2, then file3 etc.  As each file finishes writing, it is switched
- * to reads
- *
- * io buffers are aligned in case you want to do raw io
+ * aio is done in a rotating loop. First file1.bin gets 8 requests, then
+ * file2.bin, then file3.bin etc. As each file finishes writing, it is switched
+ * to reads.
  *
- * compile with gcc -Wall -laio -lpthread -o aio-stress aio-stress.c
- *
- * run aio-stress -h to see the options
- *
- * Please mail Chris Mason (mason@suse.com) with bug reports or patches
+ * io buffers are aligned in case you want to do raw io.
  */
+
 #define _FILE_OFFSET_BITS 64
-#define PROG_VERSION "0.21"
 #define NEW_GETEVENTS
 
 #define _GNU_SOURCE
+#include "tst_test.h"
+
+#ifdef HAVE_LIBAIO
 #include <stdio.h>
 #include <errno.h>
 #include <assert.h>
@@ -60,11 +38,6 @@
 #include <sys/mman.h>
 #include <string.h>
 #include <pthread.h>
-
-#include "config.h"
-#include "tst_res_flags.h"
-
-#ifdef HAVE_LIBAIO
 #include <libaio.h>
 
 #define IO_FREE 0
@@ -83,52 +56,71 @@ enum {
 #define USE_SHM 1
 #define USE_SHMFS 2
 
-/*
- * various globals, these are effectively read only by the time the threads
- * are started
- */
-long stages = 0;
-unsigned long page_size_mask;
-int o_direct = 0;
-int o_sync = 0;
-int latency_stats = 0;
-int completion_latency_stats = 0;
-int io_iter = 8;
-int iterations = RUN_FOREVER;
-int max_io_submit = 0;
-long rec_len = 64 * 1024;
-int depth = 64;
-int num_threads = 1;
-int num_contexts = 1;
-off_t context_offset = 2 * 1024 * 1024;
-int fsync_stages = 1;
-int use_shm = 0;
-int shm_id;
-char *unaligned_buffer = NULL;
-char *aligned_buffer = NULL;
-int padded_reclen = 0;
-int stonewall = 1;
-int verify = 0;
-char *verify_buf = NULL;
-int unlink_files = 0;
+static char *str_num_files;
+static char *str_max_io_submit;
+static char *str_num_contexts;
+static char *str_context_offset;
+static char *str_file_size;
+static char *str_rec_len;
+static char *str_depth;
+static char *str_io_iter;
+static char *str_iterations;
+static char *str_o_direct;
+static char *str_o_sync;
+static char *str_stages;
+static char *str_use_shm;
+static char *str_fsync_stages;
+static char *str_latency_stats;
+static char *str_completion_latency_stats;
+static char *str_num_threads;
+static char *str_unlink_files;
+static char *str_verify;
+static char *str_stonewall;
+
+static int num_files;
+static long long file_size;
+static long stages;
+static unsigned long page_size_mask;
+static int o_direct;
+static int o_sync;
+static int latency_stats;
+static int completion_latency_stats;
+static int io_iter;
+static int iterations;
+static int max_io_submit;
+static long rec_len;
+static int depth;
+static int num_threads;
+static int num_contexts;
+static long long context_offset;
+static int fsync_stages;
+static int use_shm;
+static int shm_id;
+static char *unaligned_buffer;
+static char *aligned_buffer;
+static int padded_reclen;
+static int stonewall;
+static int verify;
+static char *verify_buf;
+static int unlink_files;
 
 struct io_unit;
 struct thread_info;
 
 /* pthread mutexes and other globals for keeping the threads in sync */
-pthread_cond_t stage_cond = PTHREAD_COND_INITIALIZER;
-pthread_mutex_t stage_mutex = PTHREAD_MUTEX_INITIALIZER;
-int threads_ending = 0;
-int threads_starting = 0;
-struct timeval global_stage_start_time;
-struct thread_info *global_thread_info;
+static pthread_cond_t stage_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t stage_mutex = PTHREAD_MUTEX_INITIALIZER;
+static int threads_ending;
+static int threads_starting;
+static struct timeval global_stage_start_time;
+static struct thread_info *global_thread_info;
 
 /*
  * latencies during io_submit are measured, these are the
  * granularities for deviations
  */
 #define DEVIATIONS 6
-int deviations[DEVIATIONS] = { 100, 250, 500, 1000, 5000, 10000 };
+static int deviations[DEVIATIONS] = { 100, 250, 500, 1000, 5000, 10000 };
 
 struct io_latency {
 	double max;
@@ -262,6 +254,7 @@ static double time_since(struct timeval *start_tv, struct timeval *stop_tv)
 {
 	double sec, usec;
 	double ret;
+
 	sec = stop_tv->tv_sec - start_tv->tv_sec;
 	usec = stop_tv->tv_usec - start_tv->tv_usec;
 	if (sec > 0 && usec < 0) {
@@ -280,6 +273,7 @@ static double time_since(struct timeval *start_tv, struct timeval *stop_tv)
 static double time_since_now(struct timeval *start_tv)
 {
 	struct timeval stop_time;
+
 	gettimeofday(&stop_time, NULL);
 	return time_since(start_tv, &stop_time);
 }
@@ -292,6 +286,7 @@ static void calc_latency(struct timeval *start_tv, struct timeval *stop_tv,
 {
 	double delta;
 	int i;
+
 	delta = time_since(start_tv, stop_tv);
 	delta = delta * 1000;
 
@@ -320,7 +315,6 @@ static void oper_list_add(struct io_oper *oper, struct io_oper **list)
 	oper->next = *list;
 	(*list)->prev->next = oper;
 	(*list)->prev = oper;
-	return;
 }
 
 static void oper_list_del(struct io_oper *oper, struct io_oper **list)
@@ -338,11 +332,16 @@ static void oper_list_del(struct io_oper *oper, struct io_oper **list)
 /* worker func to check error fields in the io unit */
 static int check_finished_io(struct io_unit *io)
 {
+	char out[4 * 1024];
+	char *ptr = out;
+	char *msg;
+	int ret;
 	int i;
-	if (io->res != io->buf_size) {
 
+	if (io->res != io->buf_size) {
 		struct stat s;
-		fstat(io->io_oper->fd, &s);
+
+		SAFE_FSTAT(io->io_oper->fd, &s);
 
 		/*
 		 * If file size is large enough for the read, then this short
@@ -351,8 +350,8 @@ static int check_finished_io(struct io_unit *io)
 		if ((io->io_oper->rw == READ || io->io_oper->rw == RREAD) &&
 		    s.st_size > (io->iocb.u.c.offset + io->res)) {
 
-			fprintf(stderr,
-				"io err %lu (%s) op %d, off %Lu size %d\n",
+			tst_res(TINFO,
+				"io err %lu (%s) op %d, off %llu size %d",
 				io->res, strerror(-io->res),
 				io->iocb.aio_lio_opcode, io->iocb.u.c.offset,
 				io->buf_size);
@@ -361,19 +360,23 @@ static int check_finished_io(struct io_unit *io)
 			return -1;
 		}
 	}
+
 	if (verify && io->io_oper->rw == READ) {
 		if (memcmp(io->buf, verify_buf, io->io_oper->reclen)) {
-			fprintf(stderr,
-				"verify error, file %s offset %Lu contents (offset:bad:good):\n",
+			tst_res(TINFO,
+				"verify error, file %s offset %llu contents (offset:bad:good):",
 				io->io_oper->file_name, io->iocb.u.c.offset);
 
 			for (i = 0; i < io->io_oper->reclen; i++) {
 				if (io->buf[i] != verify_buf[i]) {
-					fprintf(stderr, "%d:%c:%c ", i,
-						io->buf[i], verify_buf[i]);
+					ret = asprintf(&msg, "%d:%c:%c ", i, io->buf[i], verify_buf[i]);
+					if (ret < 0)
+						tst_brk(TBROK, "asprintf memory allocation error");
+					ptr += sprintf(ptr, "%s", msg);
+					free(msg);
 				}
 			}
-			fprintf(stderr, "\n");
+			tst_res(TINFO, "%s", out);
 		}
 
 	}
@@ -392,7 +395,7 @@ static int grab_iou(struct io_unit *io, struct io_oper *oper)
 	return 0;
 }
 
-char *stage_name(int rw)
+static char *stage_name(int rw)
 {
 	switch (rw) {
 	case WRITE:
@@ -422,38 +425,54 @@ static void print_time(struct io_oper *oper)
 	runtime = time_since_now(&oper->start_time);
 	mb = oper_mb_trans(oper);
 	tput = mb / runtime;
-	fprintf(stderr, "%s on %s (%.2f MB/s) %.2f MB in %.2fs\n",
+	tst_res(TINFO, "%s on %s (%.2f MB/s) %.2f MB in %.2fs",
 		stage_name(oper->rw), oper->file_name, tput, mb, runtime);
 }
 
 static void print_lat(char *str, struct io_latency *lat)
 {
+	char out[4 * 1024];
+	char *ptr = out;
+	char *msg;
 	double avg = lat->total_lat / lat->total_io;
 	int i;
 	double total_counted = 0;
-	fprintf(stderr, "%s min %.2f avg %.2f max %.2f\n\t",
-		str, lat->min, avg, lat->max);
+	int ret;
+
+	tst_res(TINFO, "%s min %.2f avg %.2f max %.2f", str, lat->min, avg, lat->max);
 
 	for (i = 0; i < DEVIATIONS; i++) {
-		fprintf(stderr, " %.0f < %d", lat->deviations[i],
-			deviations[i]);
+		ret = asprintf(&msg, " %.0f < %d", lat->deviations[i], deviations[i]);
+		if (ret < 0)
+			tst_brk(TBROK, "asprintf memory allocation error");
+		ptr += sprintf(ptr, "%s", msg);
 		total_counted += lat->deviations[i];
+		free(msg);
 	}
-	if (total_counted && lat->total_io - total_counted)
-		fprintf(stderr, " < %.0f", lat->total_io - total_counted);
-	fprintf(stderr, "\n");
+
+	if (total_counted && lat->total_io - total_counted) {
+		ret = asprintf(&msg, " < %.0f", lat->total_io - total_counted);
+		if (ret < 0)
+			tst_brk(TBROK, "asprintf memory allocation error");
+		ptr += sprintf(ptr, "%s", msg);
+		free(msg);
+	}
+
+	tst_res(TINFO, "%s", out);
 	memset(lat, 0, sizeof(*lat));
 }
 
 static void print_latency(struct thread_info *t)
 {
 	struct io_latency *lat = &t->io_submit_latency;
+
 	print_lat("latency", lat);
 }
 
 static void print_completion_latency(struct thread_info *t)
 {
 	struct io_latency *lat = &t->io_completion_latency;
+
 	print_lat("completion latency", lat);
 }
 
@@ -461,7 +480,7 @@ static void print_completion_latency(struct thread_info *t)
  * updates the fields in the io operation struct that belongs to this
  * io unit, and make the io unit reusable again
  */
-void finish_io(struct thread_info *t, struct io_unit *io, long result,
+static void finish_io(struct thread_info *t, struct io_unit *io, long result,
 	       struct timeval *tv_now)
 {
 	struct io_oper *oper = io->io_oper;
@@ -480,7 +499,7 @@ void finish_io(struct thread_info *t, struct io_unit *io, long result,
 	}
 }
 
-int read_some_events(struct thread_info *t)
+static int read_some_events(struct thread_info *t)
 {
 	struct io_unit *event_io;
 	struct io_event *event;
@@ -524,7 +543,7 @@ retry:
 		event_io = t->free_ious;
 		t->free_ious = t->free_ious->next;
 		if (grab_iou(event_io, oper)) {
-			fprintf(stderr, "io unit on free list but not free\n");
+			tst_res(TINFO, "io unit on free list but not free");
 			abort();
 		}
 		return event_io;
@@ -533,7 +552,8 @@ retry:
 	if (nr > 0)
 		goto retry;
 	else
-		fprintf(stderr, "no free ious after read_some_events\n");
+		tst_res(TINFO, "no free ious after read_some_events");
+
 	return NULL;
 }
 
@@ -545,9 +565,8 @@ static int io_oper_wait(struct thread_info *t, struct io_oper *oper)
 	struct io_event event;
 	struct io_unit *event_io;
 
-	if (oper == NULL) {
+	if (oper == NULL)
 		return 0;
-	}
 
 	if (oper->num_pending == 0)
 		goto done;
@@ -561,6 +580,7 @@ static int io_oper_wait(struct thread_info *t, struct io_oper *oper)
 	while (io_getevents(t->io_ctx, 1, &event, NULL) > 0) {
 #endif
 		struct timeval tv_now;
+
 		event_io = (struct io_unit *)((unsigned long)event.obj);
 
 		gettimeofday(&tv_now, NULL);
@@ -570,14 +590,13 @@ static int io_oper_wait(struct thread_info *t, struct io_oper *oper)
 			break;
 	}
 done:
-	if (oper->num_err) {
-		fprintf(stderr, "%u errors on oper, last %u\n",
-			oper->num_err, oper->last_err);
-	}
+	if (oper->num_err)
+		tst_res(TINFO, "%u errors on oper, last %u", oper->num_err, oper->last_err);
+
 	return 0;
 }
 
-off_t random_byte_offset(struct io_oper * oper)
+static off_t random_byte_offset(struct io_oper *oper)
 {
 	off_t num;
 	off_t rand_byte = oper->start;
@@ -603,9 +622,9 @@ off_t random_byte_offset(struct io_oper * oper)
 	num = (num + page_size_mask) & ~page_size_mask;
 	rand_byte += num;
 
-	if (rand_byte + oper->reclen > oper->end) {
+	if (rand_byte + oper->reclen > oper->end)
 		rand_byte -= oper->reclen;
-	}
+
 	return rand_byte;
 }
 
@@ -623,10 +642,8 @@ static struct io_unit *build_iocb(struct thread_info *t, struct io_oper *oper)
 	off_t rand_byte;
 
 	io = find_iou(t, oper);
-	if (!io) {
-		fprintf(stderr, "unable to find io unit\n");
-		return NULL;
-	}
+	if (!io)
+		tst_brk(TBROK, "unable to find io unit");
 
 	switch (oper->rw) {
 	case WRITE:
@@ -667,10 +684,10 @@ static int finish_oper(struct thread_info *t, struct io_oper *oper)
 
 	io_oper_wait(t, oper);
 	last_err = oper->last_err;
-	if (oper->num_pending > 0) {
-		fprintf(stderr, "oper num_pending is %d\n", oper->num_pending);
-	}
-	close(oper->fd);
+	if (oper->num_pending > 0)
+		tst_res(TINFO, "oper num_pending is %d", oper->num_pending);
+
+	SAFE_CLOSE(oper->fd);
 	free(oper);
 	return last_err;
 }
@@ -680,16 +697,12 @@ static int finish_oper(struct thread_info *t, struct io_oper *oper)
  * null on error
  */
 static struct io_oper *create_oper(int fd, int rw, off_t start, off_t end,
-				   int reclen, int depth, int iter,
+				   int reclen, int depth,
 				   char *file_name)
 {
 	struct io_oper *oper;
 
-	oper = malloc(sizeof(*oper));
-	if (!oper) {
-		fprintf(stderr, "unable to allocate io oper\n");
-		return NULL;
-	}
+	oper = SAFE_MALLOC(sizeof(*oper));
 	memset(oper, 0, sizeof(*oper));
 
 	oper->depth = depth;
@@ -709,7 +722,7 @@ static struct io_oper *create_oper(int fd, int rw, off_t start, off_t end,
  * does setup on num_ios worth of iocbs, but does not actually
  * start any io
  */
-int build_oper(struct thread_info *t, struct io_oper *oper, int num_ios,
+static int build_oper(struct thread_info *t, struct io_oper *oper, int num_ios,
 	       struct iocb **my_iocbs)
 {
 	int i;
@@ -726,9 +739,9 @@ int build_oper(struct thread_info *t, struct io_oper *oper, int num_ios,
 
 	for (i = 0; i < num_ios; i++) {
 		io = build_iocb(t, oper);
-		if (!io) {
+		if (!io)
 			return -1;
-		}
+
 		my_iocbs[i] = &io->iocb;
 	}
 	return num_ios;
@@ -743,6 +756,7 @@ static void update_iou_counters(struct iocb **my_iocbs, int nr,
 {
 	struct io_unit *io;
 	int i;
+
 	for (i = 0; i < nr; i++) {
 		io = (struct io_unit *)(my_iocbs[i]);
 		io->io_oper->num_pending++;
@@ -752,7 +766,7 @@ static void update_iou_counters(struct iocb **my_iocbs, int nr,
 }
 
 /* starts some io for a given file, returns zero if all went well */
-int run_built(struct thread_info *t, int num_ios, struct iocb **my_iocbs)
+static int run_built(struct thread_info *t, int num_ios, struct iocb **my_iocbs)
 {
 	int ret;
 	struct timeval start_time;
@@ -778,17 +792,17 @@ resubmit:
 		 */
 		if (ret > 0 || ret == -EAGAIN) {
 			int old_ret = ret;
-			if ((ret = read_some_events(t) > 0)) {
+
+			ret = read_some_events(t);
+			if (ret > 0) {
 				goto resubmit;
 			} else {
-				fprintf(stderr, "ret was %d and now is %d\n",
-					ret, old_ret);
+				tst_res(TINFO, "ret was %d and now is %d", ret, old_ret);
 				abort();
 			}
 		}
 
-		fprintf(stderr, "ret %d (%s) on io_submit\n", ret,
-			strerror(-ret));
+		tst_res(TINFO, "ret %d (%s) on io_submit", ret, strerror(-ret));
 		return -1;
 	}
 	update_iou_counters(my_iocbs, ret, &stop_time);
@@ -803,18 +817,18 @@ resubmit:
 static int restart_oper(struct io_oper *oper)
 {
 	int new_rw = 0;
+
 	if (oper->last_err)
 		return 0;
 
 	/* this switch falls through */
-	switch (oper->rw) {
-	case WRITE:
+	if (oper->rw == WRITE) {
 		if (stages & (1 << READ))
 			new_rw = READ;
-	case READ:
+	} else if (oper->rw == READ) {
 		if (!new_rw && stages & (1 << RWRITE))
 			new_rw = RWRITE;
-	case RWRITE:
+	} else if (oper->rw == RWRITE) {
 		if (!new_rw && stages & (1 << RREAD))
 			new_rw = RREAD;
 	}
@@ -840,24 +854,21 @@ static int restart_oper(struct io_oper *oper)
 static int oper_runnable(struct io_oper *oper)
 {
 	struct stat buf;
-	int ret;
 
 	/* first context is always runnable, if started_ios > 0, no need to
 	 * redo the calculations
 	 */
 	if (oper->started_ios || oper->start == 0)
 		return 1;
-	/*
-	 * only the sequential phases force delays in starting */
+
+	/* only the sequential phases force delays in starting */
 	if (oper->rw >= RWRITE)
 		return 1;
-	ret = fstat(oper->fd, &buf);
-	if (ret < 0) {
-		perror("fstat");
-		exit(1);
-	}
+
+	SAFE_FSTAT(oper->fd, &buf);
 	if (S_ISREG(buf.st_mode) && buf.st_size < oper->start)
 		return 0;
+
 	return 1;
 }
 
@@ -903,10 +914,9 @@ static int run_active_list(struct thread_info *t,
 	}
 	if (num_built) {
 		ret = run_built(t, num_built, t->iocbs);
-		if (ret < 0) {
-			fprintf(stderr, "error %d on run_built\n", ret);
-			exit(1);
-		}
+		if (ret < 0)
+			tst_brk(TBROK, "error %d on run_built", ret);
+
 		while (built_opers) {
 			oper = built_opers;
 			oper_list_del(oper, &built_opers);
@@ -917,46 +927,44 @@ static int run_active_list(struct thread_info *t,
 			}
 		}
 	}
+
 	return 0;
 }
 
-void drop_shm()
+static void drop_shm(void)
 {
 	int ret;
 	struct shmid_ds ds;
+
 	if (use_shm != USE_SHM)
 		return;
 
 	ret = shmctl(shm_id, IPC_RMID, &ds);
-	if (ret) {
-		perror("shmctl IPC_RMID");
-	}
+	if (ret)
+		tst_brk(TBROK, "shmctl IPC_RMID");
 }
 
-void aio_setup(io_context_t * io_ctx, int n)
+static void aio_setup(io_context_t *io_ctx, int n)
 {
 	int res = io_queue_init(n, io_ctx);
-	if (res != 0) {
-		fprintf(stderr, "io_queue_setup(%d) returned %d (%s)\n",
-			n, res, strerror(-res));
-		exit(3);
-	}
+
+	if (res != 0)
+		tst_brk(TBROK, "io_queue_setup(%d) returned %d (%s)", n, res, strerror(-res));
 }
 
 /*
  * allocate io operation and event arrays for a given thread
  */
-int setup_ious(struct thread_info *t,
+static int setup_ious(struct thread_info *t,
 	       int num_files, int depth, int reclen, int max_io_submit)
 {
 	int i;
 	size_t bytes = num_files * depth * sizeof(*t->ios);
 
 	t->ios = malloc(bytes);
-	if (!t->ios) {
-		fprintf(stderr, "unable to allocate io units\n");
-		return -1;
-	}
+	if (!t->ios)
+		tst_brk(TBROK, "unable to allocate io units");
+
 	memset(t->ios, 0, bytes);
 
 	for (i = 0; i < depth * num_files; i++) {
@@ -977,7 +985,7 @@ int setup_ious(struct thread_info *t,
 
 	t->iocbs = malloc(sizeof(struct iocb *) * max_io_submit);
 	if (!t->iocbs) {
-		fprintf(stderr, "unable to allocate iocbs\n");
+		tst_res(TINFO, "unable to allocate iocbs");
 		goto free_buffers;
 	}
 
@@ -985,9 +993,10 @@ int setup_ious(struct thread_info *t,
 
 	t->events = malloc(sizeof(struct io_event) * depth * num_files);
 	if (!t->events) {
-		fprintf(stderr, "unable to allocate ram for events\n");
+		tst_res(TINFO, "unable to allocate ram for events");
 		goto free_buffers;
 	}
+
 	memset(t->events, 0, num_files * sizeof(struct io_event) * depth);
 
 	t->num_global_ios = num_files * depth;
@@ -1008,8 +1017,8 @@ free_buffers:
  * and without trying to find a special place in each thread to map the
  * buffers to
  */
-int setup_shared_mem(int num_threads, int num_files, int depth,
-		     int reclen, int max_io_submit)
+static int setup_shared_mem(int num_threads, int num_files, int depth,
+		     int reclen)
 {
 	char *p = NULL;
 	size_t total_ram;
@@ -1024,17 +1033,17 @@ int setup_shared_mem(int num_threads, int num_files, int depth,
 	total_ram += page_size_mask;
 
 	if (use_shm == USE_MALLOC) {
-		p = malloc(total_ram);
+		p = SAFE_MALLOC(total_ram);
 	} else if (use_shm == USE_SHM) {
 		shm_id = shmget(IPC_PRIVATE, total_ram, IPC_CREAT | 0700);
 		if (shm_id < 0) {
-			perror("shmget");
+			tst_res(TINFO, "shmget error");
 			drop_shm();
 			goto free_buffers;
 		}
 		p = shmat(shm_id, (char *)0x50000000, 0);
 		if ((long)p == -1) {
-			perror("shmat");
+			tst_res(TINFO, "shmat error");
 			goto free_buffers;
 		}
 		/* won't really be dropped until we shmdt */
@@ -1046,22 +1055,22 @@ int setup_shared_mem(int num_threads, int num_files, int depth,
 		strcpy(mmap_name, "/dev/shm/XXXXXX");
 		fd = mkstemp(mmap_name);
 		if (fd < 0) {
-			perror("mkstemp");
+			tst_res(TINFO, "mkstemp error");
 			goto free_buffers;
 		}
-		unlink(mmap_name);
-		ftruncate(fd, total_ram);
+		SAFE_UNLINK(mmap_name);
+		SAFE_FTRUNCATE(fd, total_ram);
 		shm_id = fd;
 		p = mmap((char *)0x50000000, total_ram,
 			 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 
 		if (p == MAP_FAILED) {
-			perror("mmap");
+			tst_res(TINFO, "mmap error");
 			goto free_buffers;
 		}
 	}
 	if (!p) {
-		fprintf(stderr, "unable to allocate buffers\n");
+		tst_res(TINFO, "unable to allocate buffers");
 		goto free_buffers;
 	}
 	unaligned_buffer = p;
@@ -1080,7 +1089,7 @@ free_buffers:
  * runs through all the thread_info structs and calculates a combined
  * throughput
  */
-void global_thread_throughput(struct thread_info *t, char *this_stage)
+static void global_thread_throughput(struct thread_info *t, char *this_stage)
 {
 	int i;
 	double runtime = time_since_now(&global_stage_start_time);
@@ -1093,12 +1102,10 @@ void global_thread_throughput(struct thread_info *t, char *this_stage)
 			min_trans = t->stage_mb_trans;
 	}
 	if (total_mb) {
-		fprintf(stderr, "%s throughput (%.2f MB/s) ", this_stage,
-			total_mb / runtime);
-		fprintf(stderr, "%.2f MB in %.2fs", total_mb, runtime);
+		tst_res(TINFO, "%s throughput (%.2f MB/s)", this_stage, total_mb / runtime);
+		tst_res(TINFO, "%.2f MB in %.2fs", total_mb, runtime);
 		if (stonewall)
-			fprintf(stderr, " min transfer %.2fMB", min_trans);
-		fprintf(stderr, "\n");
+			tst_res(TINFO, "min transfer %.2fMB", min_trans);
 	}
 }
 
@@ -1111,7 +1118,7 @@ void global_thread_throughput(struct thread_info *t, char *this_stage)
  * various timings are printed in between the stages, along with
  * thread synchronization if there are more than one threads.
  */
-int worker(struct thread_info *t)
+static int *worker(struct thread_info *t)
 {
 	struct io_oper *oper;
 	char *this_stage = NULL;
@@ -1119,6 +1126,7 @@ int worker(struct thread_info *t)
 	int status = 0;
 	int iteration = 0;
 	int cnt;
+	int *ret;
 
 	aio_setup(&t->io_ctx, 512);
 
@@ -1176,7 +1184,7 @@ restart:
 	oper = t->finished_opers;
 	while (oper) {
 		if (fsync_stages)
-			fsync(oper->fd);
+			SAFE_FSYNC(oper->fd);
 		t->stage_mb_trans += oper_mb_trans(oper);
 		if (restart_oper(oper)) {
 			oper_list_del(oper, &t->finished_opers);
@@ -1191,8 +1199,8 @@ restart:
 
 	if (t->stage_mb_trans && t->num_files > 0) {
 		double seconds = time_since_now(&stage_time);
-		fprintf(stderr,
-			"thread %td %s totals (%.2f MB/s) %.2f MB in %.2fs\n",
+
+		tst_res(TINFO, "thread %td %s totals (%.2f MB/s) %.2f MB in %.2fs",
 			t - global_thread_info, this_stage,
 			t->stage_mb_trans / seconds, t->stage_mb_trans,
 			seconds);
@@ -1224,210 +1232,169 @@ restart:
 		status = finish_oper(t, oper);
 	}
 
-	if (t->num_global_pending) {
-		fprintf(stderr, "global num pending is %d\n",
-			t->num_global_pending);
-	}
+	if (t->num_global_pending)
+		tst_res(TINFO, "global num pending is %d", t->num_global_pending);
+
 	io_queue_release(t->io_ctx);
 
-	return status;
+	ret = SAFE_MALLOC(sizeof(int));
+	*ret = status;
+
+	return ret;
 }
 
 typedef void *(*start_routine) (void *);
-int run_workers(struct thread_info *t, int num_threads)
+static int run_workers(struct thread_info *t, int num_threads)
 {
+	void *retval;
 	int ret;
 	int i;
 
 	for (i = 0; i < num_threads; i++) {
-		ret =
-		    pthread_create(&t[i].tid, NULL, (start_routine) worker,
-				   t + i);
-		if (ret) {
-			perror("pthread_create");
-			exit(1);
-		}
+		ret = pthread_create(&t[i].tid, NULL, (start_routine) worker, t + i);
+		if (ret)
+			tst_brk(TBROK, "pthread_create: %s", tst_strerrno(ret));
 	}
+
 	for (i = 0; i < num_threads; i++) {
-		ret = pthread_join(t[i].tid, NULL);
-		if (ret) {
-			perror("pthread_join");
-			exit(1);
-		}
+		ret = pthread_join(t[i].tid, &retval);
+		if (ret)
+			tst_brk(TBROK, "pthread_join: %s", tst_strerrno(ret));
+
+		ret = *((int *) retval);
+		if (ret)
+			return ret;
 	}
+
 	return 0;
 }
 
-off_t parse_size(char *size_arg, off_t mult)
+static void setup(void)
 {
-	char c;
-	int num;
-	off_t ret;
-	c = size_arg[strlen(size_arg) - 1];
-	if (c > '9') {
-		size_arg[strlen(size_arg) - 1] = '\0';
-	}
-	num = atoi(size_arg);
-	switch (c) {
-	case 'g':
-	case 'G':
-		mult = 1024 * 1024 * 1024;
-		break;
-	case 'm':
-	case 'M':
-		mult = 1024 * 1024;
-		break;
-	case 'k':
-	case 'K':
-		mult = 1024;
-		break;
-	case 'b':
-	case 'B':
-		mult = 1;
-		break;
+	struct stat sb;
+	int maxaio;
+	int stages_i;
+
+	num_files = 1;
+	max_io_submit = 0;
+	num_contexts = 1;
+	context_offset = 2 * 1024 * 1024;
+	file_size = 1024 * 1024 * 1024;
+	rec_len = 64 * 1024;
+	depth = 64;
+	io_iter = 8;
+	iterations = RUN_FOREVER;
+	o_direct = 0;
+	o_sync = 0;
+	stages = 0;
+	use_shm = 0;
+	fsync_stages = 1;
+	latency_stats = 0;
+	completion_latency_stats = 0;
+	num_threads = 1;
+	unlink_files = 0;
+	verify = 0;
+	stonewall = 1;
+	padded_reclen = 0;
+	threads_ending = 0;
+	threads_starting = 0;
+
+	SAFE_STAT(".", &sb);
+	page_size_mask = sb.st_blksize;
+
+	SAFE_FILE_SCANF("/proc/sys/fs/aio-max-nr", "%d", &maxaio);
+	tst_res(TINFO, "Maximum AIO blocks: %d", maxaio);
+
+	if (tst_parse_int(str_num_files, &num_files, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of files to generate '%s'", str_num_files);
+
+	if (tst_parse_int(str_max_io_submit, &max_io_submit, 0, INT_MAX))
+		tst_brk(TBROK, "Invalid number of iocbs '%s'", str_max_io_submit);
+
+	if (max_io_submit > maxaio)
+		tst_res(TCONF, "Number of async IO blocks passed the maximum (%d)", maxaio);
+
+	if (tst_parse_int(str_num_contexts, &num_contexts, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of contexts per file '%s'", str_num_contexts);
+
+	if (tst_parse_filesize(str_context_offset, &context_offset, 1, LLONG_MAX))
+		tst_brk(TBROK, "Invalid offset between contexts '%s'", str_context_offset);
+
+	if (tst_parse_filesize(str_file_size, &file_size, 1, LLONG_MAX))
+		tst_brk(TBROK, "Invalid file size '%s'", str_file_size);
+
+	if (tst_parse_long(str_rec_len, &rec_len, 1, LONG_MAX))
+		tst_brk(TBROK, "Invalid record size '%s'", str_rec_len);
+
+	if (tst_parse_int(str_depth, &depth, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of pending aio requests '%s'", str_depth);
+
+	if (tst_parse_int(str_io_iter, &io_iter, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of I/O per file '%s'", str_io_iter);
+
+	if (tst_parse_int(str_iterations, &iterations, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of total ayncs I/O '%s'", str_iterations);
+
+	if (iterations == INT_MAX)
+		iterations = RUN_FOREVER;
+
+	if (tst_parse_int(str_stages, &stages_i, 0, INT_MAX))
+		tst_brk(TBROK, "Invalid stage number '%s'", str_stages);
+
+	if (stages_i) {
+		stages |= 1 << stages_i;
+		tst_res(TINFO, "Adding stage %s", stage_name(stages_i));
+	}
+
+	if (tst_parse_int(str_num_threads, &num_threads, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of threads '%s'", str_num_threads);
+
+	if (str_o_direct)
+		o_direct = O_DIRECT;
+
+	if (str_o_sync)
+		o_sync = O_SYNC;
+
+	if (str_use_shm) {
+		if (!strcmp(str_use_shm, "shm")) {
+			tst_res(TINFO, "using ipc shm");
+			use_shm = USE_SHM;
+		} else if (!strcmp(str_use_shm, "shmfs")) {
+			tst_res(TINFO, "using /dev/shm for buffers");
+			use_shm = USE_SHMFS;
+		}
 	}
-	ret = mult * num;
-	return ret;
-}
 
-void print_usage(void)
-{
-	printf
-	    ("usage: aio-stress [-s size] [-r size] [-a size] [-d num] [-b num]\n");
-	printf
-	    ("                  [-i num] [-t num] [-c num] [-C size] [-nxhOS ]\n");
-	printf("                  file1 [file2 ...]\n");
-	printf("\t-a size in KB at which to align buffers\n");
-	printf("\t-b max number of iocbs to give io_submit at once\n");
-	printf("\t-c number of io contexts per file\n");
-	printf("\t-C offset between contexts, default 2MB\n");
-	printf("\t-s size in MB of the test file(s), default 1024MB\n");
-	printf("\t-r record size in KB used for each io, default 64KB\n");
-	printf
-	    ("\t-d number of pending aio requests for each file, default 64\n");
-	printf("\t-i number of I/O per file sent before switching\n"
-	       "\t   to the next file, default 8\n");
-	printf("\t-I total number of ayncs I/O the program will run, "
-	       "default is run until Cntl-C\n");
-	printf("\t-O Use O_DIRECT (not available in 2.4 kernels),\n");
-	printf("\t-S Use O_SYNC for writes\n");
-	printf("\t-o add an operation to the list: write=0, read=1,\n");
-	printf("\t   random write=2, random read=3.\n");
-	printf("\t   repeat -o to specify multiple ops: -o 0 -o 1 etc.\n");
-	printf
-	    ("\t-m shm use ipc shared memory for io buffers instead of malloc\n");
-	printf("\t-m shmfs mmap a file in /dev/shm for io buffers\n");
-	printf("\t-n no fsyncs between write stage and read stage\n");
-	printf("\t-l print io_submit latencies after each stage\n");
-	printf("\t-L print io completion latencies after each stage\n");
-	printf("\t-t number of threads to run\n");
-	printf("\t-u unlink files after completion\n");
-	printf("\t-v verification of bytes written\n");
-	printf("\t-x turn off thread stonewalling\n");
-	printf("\t-h this message\n");
-	printf
-	    ("\n\t   the size options (-a -s and -r) allow modifiers -s 400{k,m,g}\n");
-	printf("\t   translate to 400KB, 400MB and 400GB\n");
-	printf("version %s\n", PROG_VERSION);
+	if (str_fsync_stages)
+		fsync_stages = 0;
+
+	if (str_latency_stats)
+		latency_stats = 1;
+
+	if (str_completion_latency_stats)
+		completion_latency_stats = 1;
+
+	if (str_unlink_files)
+		unlink_files = 1;
+
+	if (str_verify)
+		verify = 1;
+
+	if (str_stonewall)
+		stonewall = 0;
 }
 
-int main(int ac, char **av)
+static void run(void)
 {
-	int rwfd;
-	int i;
-	int j;
-	int c;
-
-	off_t file_size = 1 * 1024 * 1024 * 1024;
+	char files[num_files][265];
 	int first_stage = WRITE;
 	struct io_oper *oper;
 	int status = 0;
-	int num_files = 0;
 	int open_fds = 0;
 	struct thread_info *t;
-
-	page_size_mask = getpagesize() - 1;
-
-	while (1) {
-		c = getopt(ac, av, "a:b:c:C:m:s:r:d:i:I:o:t:lLnhOSxvu");
-		if (c < 0)
-			break;
-
-		switch (c) {
-		case 'a':
-			page_size_mask = parse_size(optarg, 1024);
-			page_size_mask--;
-			break;
-		case 'c':
-			num_contexts = atoi(optarg);
-			break;
-		case 'C':
-			context_offset = parse_size(optarg, 1024 * 1024);
-		case 'b':
-			max_io_submit = atoi(optarg);
-			break;
-		case 's':
-			file_size = parse_size(optarg, 1024 * 1024);
-			break;
-		case 'd':
-			depth = atoi(optarg);
-			break;
-		case 'r':
-			rec_len = parse_size(optarg, 1024);
-			break;
-		case 'i':
-			io_iter = atoi(optarg);
-			break;
-		case 'I':
-			iterations = atoi(optarg);
-			break;
-		case 'n':
-			fsync_stages = 0;
-			break;
-		case 'l':
-			latency_stats = 1;
-			break;
-		case 'L':
-			completion_latency_stats = 1;
-			break;
-		case 'm':
-			if (!strcmp(optarg, "shm")) {
-				fprintf(stderr, "using ipc shm\n");
-				use_shm = USE_SHM;
-			} else if (!strcmp(optarg, "shmfs")) {
-				fprintf(stderr, "using /dev/shm for buffers\n");
-				use_shm = USE_SHMFS;
-			}
-			break;
-		case 'o':
-			i = atoi(optarg);
-			stages |= 1 << i;
-			fprintf(stderr, "adding stage %s\n", stage_name(i));
-			break;
-		case 'O':
-			o_direct = O_DIRECT;
-			break;
-		case 'S':
-			o_sync = O_SYNC;
-			break;
-		case 't':
-			num_threads = atoi(optarg);
-			break;
-		case 'x':
-			stonewall = 0;
-			break;
-		case 'u':
-			unlink_files = 1;
-			break;
-		case 'v':
-			verify = 1;
-			break;
-		case 'h':
-		default:
-			print_usage();
-			exit(1);
-		}
-	}
+	int rwfd;
+	int i;
+	int j;
 
 	/*
 	 * make sure we don't try to submit more I/O than we have allocated
@@ -1435,28 +1402,15 @@ int main(int ac, char **av)
 	 */
 	if (depth < io_iter) {
 		io_iter = depth;
-		fprintf(stderr, "dropping io_iter to %d\n", io_iter);
-	}
-
-	if (optind >= ac) {
-		print_usage();
-		exit(1);
+		tst_res(TINFO, "dropping io_iter to %d", io_iter);
 	}
 
-	num_files = ac - optind;
-
 	if (num_threads > (num_files * num_contexts)) {
 		num_threads = num_files * num_contexts;
-		fprintf(stderr,
-			"dropping thread count to the number of contexts %d\n",
-			num_threads);
+		tst_res(TINFO, "Dropping thread count to the number of contexts %d", num_threads);
 	}
 
-	t = malloc(num_threads * sizeof(*t));
-	if (!t) {
-		perror("malloc");
-		exit(1);
-	}
+	t = SAFE_MALLOC(num_threads * sizeof(*t));
 	memset(t, 0, num_threads * sizeof(*t));
 	global_thread_info = t;
 
@@ -1471,100 +1425,111 @@ int main(int ac, char **av)
 	 */
 	if (max_io_submit < io_iter) {
 		io_iter = max_io_submit;
-		fprintf(stderr, "dropping io_iter to %d\n", io_iter);
+		tst_res(TINFO, "dropping io_iter to %d", io_iter);
 	}
 
 	if (!stages) {
-		stages =
-		    (1 << WRITE) | (1 << READ) | (1 << RREAD) | (1 << RWRITE);
+		stages = (1 << WRITE) | (1 << READ) | (1 << RREAD) | (1 << RWRITE);
 	} else {
 		for (i = 0; i < LAST_STAGE; i++) {
 			if (stages & (1 << i)) {
 				first_stage = i;
-				fprintf(stderr, "starting with %s\n",
-					stage_name(i));
+				tst_res(TINFO, "starting with %s", stage_name(i));
 				break;
 			}
 		}
 	}
 
-	if (file_size < num_contexts * context_offset) {
-		fprintf(stderr, "file size %ld too small for %d contexts\n",
+	if (file_size < num_contexts * context_offset)
+		tst_brk(TBROK, "file size %ld too small for %d contexts",
 			(long)file_size, num_contexts);
-		exit(1);
-	}
 
-	fprintf(stderr, "file size %ldMB, record size %ldKB, depth %d, "
-		"I/O per iteration %d\n",
+	tst_res(TINFO, "file size %ldMB, record size %ldKB, depth %d, "
+		"I/O per iteration %d",
 		(long)(file_size / (1024 * 1024)),
 		rec_len / 1024, depth, io_iter);
-	fprintf(stderr, "max io_submit %d, buffer alignment set to %luKB\n",
+	tst_res(TINFO, "max io_submit %d, buffer alignment set to %luKB",
 		max_io_submit, (page_size_mask + 1) / 1024);
-	fprintf(stderr, "threads %d files %d contexts %d context offset %ldMB "
-		"verification %s\n", num_threads, num_files, num_contexts,
+	tst_res(TINFO, "threads %d files %d contexts %d context offset %ldMB "
+		"verification %s", num_threads, num_files, num_contexts,
 		(long)(context_offset / (1024 * 1024)), verify ? "on" : "off");
+
 	/* open all the files and do any required setup for them */
-	for (i = optind; i < ac; i++) {
+	for (i = 0; i < num_files; i++) {
 		int thread_index;
+
+		snprintf(files[i], sizeof(files[i]), "file%d.bin", i);
+
 		for (j = 0; j < num_contexts; j++) {
 			thread_index = open_fds % num_threads;
 			open_fds++;
 
-			rwfd =
-			    open(av[i], O_CREAT | O_RDWR | o_direct | o_sync,
-				 0600);
-			if (rwfd == -1) {
-				fprintf(stderr,
-					"error while creating file %s: %s",
-					av[i], strerror(errno));
-				exit(1);
-			}
+			rwfd = SAFE_OPEN(files[i], O_CREAT | O_RDWR | o_direct | o_sync, 0600);
+
+			oper = create_oper(rwfd, first_stage, j * context_offset,
+				file_size - j * context_offset, rec_len,
+				depth, files[i]);
+			if (!oper)
+				tst_brk(TBROK, "error in create_oper");
 
-			oper =
-			    create_oper(rwfd, first_stage, j * context_offset,
-					file_size - j * context_offset, rec_len,
-					depth, io_iter, av[i]);
-			if (!oper) {
-				fprintf(stderr, "error in create_oper\n");
-				exit(-1);
-			}
 			oper_list_add(oper, &t[thread_index].active_opers);
 			t[thread_index].num_files++;
 		}
 	}
-	if (setup_shared_mem(num_threads, num_files * num_contexts,
-			     depth, rec_len, max_io_submit)) {
-		exit(1);
-	}
+
+	if (setup_shared_mem(num_threads, num_files * num_contexts, depth, rec_len))
+		tst_brk(TBROK, "error in setup_shared_mem");
+
 	for (i = 0; i < num_threads; i++) {
-		if (setup_ious
-		    (&t[i], t[i].num_files, depth, rec_len, max_io_submit))
-			exit(1);
+		if (setup_ious(&t[i], t[i].num_files, depth, rec_len, max_io_submit))
+			tst_brk(TBROK, "error in setup_ious");
 	}
+
 	if (num_threads > 1) {
-		printf("Running multi thread version num_threads:%d\n",
-		       num_threads);
-		run_workers(t, num_threads);
+		tst_res(TINFO, "Running multi thread version num_threads: %d", num_threads);
+		status = run_workers(t, num_threads);
 	} else {
-		printf("Running single thread version \n");
-		status = worker(t);
-	}
-	if (unlink_files) {
-		for (i = optind; i < ac; i++) {
-			printf("Cleaning up file %s \n", av[i]);
-			unlink(av[i]);
-		}
+		tst_res(TINFO, "Running single thread version");
+		status = *worker(t);
 	}
 
-	if (status) {
-		exit(1);
-	}
-	return status;
+	for (i = 0; i < num_files; i++)
+		SAFE_UNLINK(files[i]);
+
+	if (status)
+		tst_res(TFAIL, "Test did not pass");
+	else
+		tst_res(TPASS, "Test passed");
 }
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.needs_tmpdir = 1,
+	.options = (struct tst_option[]) {
+		{"f:", &str_num_files, "Number of files to generate"},
+		{"b:", &str_max_io_submit, "Max number of iocbs to give io_submit at once"},
+		{"c:", &str_num_contexts, "Number of io contexts per file"},
+		{"g:", &str_context_offset, "Offset between contexts (default 2M)"},
+		{"s:", &str_file_size, "Size in MB of the test file(s) (default 1024M)"},
+		{"r:", &str_rec_len, "Record size in KB used for each io (default 64K)"},
+		{"d:", &str_depth, "Number of pending aio requests for each file (default 64)"},
+		{"e:", &str_io_iter, "Number of I/O per file sent before switching to the next file (default 8)"},
+		{"a:", &str_iterations, "Total number of ayncs I/O the program will run, default is run until Cntl-C"},
+		{"O", &str_o_direct, "Use O_DIRECT (not available in 2.4 kernels)"},
+		{"S", &str_o_sync, "Use O_SYNC for writes"},
+		{"o:", &str_stages, "Add an operation to the list: write=0, read=1, random write=2, random read=3"},
+		{"m", &str_use_shm, "SHM use ipc shared memory for io buffers instead of malloc"},
+		{"n", &str_fsync_stages, "No fsyncs between write stage and read stage"},
+		{"l", &str_latency_stats, "Print io_submit latencies after each stage"},
+		{"L", &str_completion_latency_stats, "Print io completion latencies after each stage"},
+		{"t:", &str_num_threads, "Number of threads to run"},
+		{"u", &str_unlink_files, "Unlink files after completion"},
+		{"v", &str_verify, "Verification of bytes written"},
+		{"x", &str_stonewall, "Turn off thread stonewalling"},
+		{}
+	}
+};
 #else
-int main(void)
-{
-	fprintf(stderr, "test requires libaio and it's development packages\n");
-	return TCONF;
-}
+TST_TEST_TCONF("test requires libaio and its development packages");
 #endif
-- 
2.34.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related

* Re: [PATCH 1/4] arm64: Add Cortex-A510 CPU part definition
From: Suzuki K Poulose @ 2022-01-05 10:05 UTC (permalink / raw)
  To: Anshuman Khandual, linux-arm-kernel
  Cc: Catalin Marinas, Will Deacon, Mathieu Poirier, coresight,
	linux-doc, linux-kernel
In-Reply-To: <1641359159-22726-2-git-send-email-anshuman.khandual@arm.com>

On 05/01/2022 05:05, Anshuman Khandual wrote:
> Add the CPU Partnumbers for the new Arm designs.
> 
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Suzuki Poulose <suzuki.poulose@arm.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>   arch/arm64/include/asm/cputype.h | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 19b8441aa8f2..e8fdc10395b6 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -73,6 +73,7 @@
>   #define ARM_CPU_PART_CORTEX_A76		0xD0B
>   #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
>   #define ARM_CPU_PART_CORTEX_A77		0xD0D
> +#define ARM_CPU_PART_CORTEX_A510	0xD46
>   #define ARM_CPU_PART_CORTEX_A710	0xD47
>   #define ARM_CPU_PART_NEOVERSE_N2	0xD49

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>

^ permalink raw reply

* Re: [PATCH V40 12/29] x86: Lock down IO port access when the kernel is locked down
From: Kai-Heng Feng @ 2022-01-05 10:05 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: jmorris, linux-security-module, linux-kernel, linux-api,
	David Howells, Kees Cook, x86
In-Reply-To: <20220105072010.GA31134@srcf.ucam.org>

On Wed, Jan 5, 2022 at 3:20 PM Matthew Garrett <mjg59@srcf.ucam.org> wrote:
>
> On Wed, Jan 05, 2022 at 02:57:57PM +0800, Kai-Heng Feng wrote:
>
> > The affected system from the customer has SecureBoot enabled (and
> > hence lockdown), and the kernel upgrade surprisingly broke ioperm()
> > usage.
>
> Which kernel was being used that was signed but didn't implement
> lockdown? That sounds, uh, bad.

It was upgraded from older distro release. Older kernels don't have lockdown.

>
> > The userspace program is proprietary so I can't share it here.
>
> Ok. Are you able to describe anything about what it does so we can
> figure out a better solution?
>
> > Basically this patch makes ioperm() a noop on SecureBoot enabled x86 systems.
> > If reverting is not an option, what else can we do to circumvent the regression?
>
> There's two main choices:
>
> 1) Disable secure boot on the system in question - if there's a need to
> run userland that can do arbitrary port IO then secure boot isn't
> providing any meaningful security benefit in any case.

How so?
Other security features are still incredible valuable, we don't want
to toss them out just because someone has to use ioperm().

>
> 2) Implement a kernel driver that abstracts the hardware access away
> from userland, and ensures that all the accesses are performed in a safe
> way.
>
> Doing port IO from userland is almost always a terrible idea - it
> usually involves indexed accesses (you write an address to one port and
> then write or read data from another), and if two processes are trying
> to do this simultaneously (either because SMP or because one process
> gets preempted after writing the address but before accessing the data
> register), and in that case you can end up with accesses to the wrong
> register as a result. You really want this sort of thing to be mediated
> by the kernel, both from a safety perspective and to ensure appropriate
> synchronisation.

Agree, let me start a discussion with them.

Kai-Heng

^ permalink raw reply

* [PATCH 0/2] Add toprgu reset-controller support for MT7986
From: Sam Shih @ 2022-01-05 10:04 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Matthias Brugger, Philipp Zabel,
	Rob Herring, Ryder Lee, linux-kernel, linux-watchdog,
	linux-arm-kernel, linux-mediatek, devicetree
  Cc: John Crispin, Sam Shih

These patches aim to add watchdog toprgu reset-controller support
for MT7986.

Sam Shih (2):
  dt-bindings: reset: mt7986: Add reset-controller header file
  watchdog: mtk_wdt: mt7986: Add toprgu reset controller support

 drivers/watchdog/mtk_wdt.c                |  6 +++
 include/dt-bindings/reset/mt7986-resets.h | 55 +++++++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt7986-resets.h

-- 
2.29.2


^ permalink raw reply

* [Intel-gfx] [PATCH 2/2] drm/i915/uncore: rename i915_reg_read_ioctl intel_uncore_reg_read_ioctl
From: Jani Nikula @ 2022-01-05 10:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Jani Nikula
In-Reply-To: <20220105100520.976092-1-jani.nikula@intel.com>

Follow the usual naming convention.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_driver.c  | 2 +-
 drivers/gpu/drm/i915/intel_uncore.c | 4 ++--
 drivers/gpu/drm/i915/intel_uncore.h | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
index 95174938b160..f9a494e159dc 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -1805,7 +1805,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE_EXT, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
-	DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_REG_READ, intel_uncore_reg_read_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index fc25ebf1a593..33f95bb2d3d5 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -2269,8 +2269,8 @@ static const struct reg_whitelist {
 	.size = 8
 } };
 
-int i915_reg_read_ioctl(struct drm_device *dev,
-			void *data, struct drm_file *file)
+int intel_uncore_reg_read_ioctl(struct drm_device *dev,
+				void *data, struct drm_file *file)
 {
 	struct drm_i915_private *i915 = to_i915(dev);
 	struct intel_uncore *uncore = &i915->uncore;
diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h
index 3a87bbd906f8..697ac4586159 100644
--- a/drivers/gpu/drm/i915/intel_uncore.h
+++ b/drivers/gpu/drm/i915/intel_uncore.h
@@ -457,7 +457,7 @@ static inline int intel_uncore_write_and_verify(struct intel_uncore *uncore,
 #define raw_reg_write(base, reg, value) \
 	writel(value, base + i915_mmio_reg_offset(reg))
 
-int i915_reg_read_ioctl(struct drm_device *dev, void *data,
-			struct drm_file *file);
+int intel_uncore_reg_read_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file);
 
 #endif /* !__INTEL_UNCORE_H__ */
-- 
2.30.2


^ permalink raw reply related

* Re: [PATCH 4/8] PM: runtime: Add DEFINE_RUNTIME_DEV_PM_OPS() macro
From: Jonathan Cameron @ 2022-01-05 10:05 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: Rafael J . Wysocki, Ulf Hansson, Jonathan Cameron,
	Lars-Peter Clausen, Linus Walleij, Arnd Bergmann, Len Brown,
	Pavel Machek, list, linux-iio, linux-kernel, linux-mips,
	linux-mmc, linux-pm
In-Reply-To: <20220104214214.198843-5-paul@crapouillou.net>

On Tue, 4 Jan 2022 21:42:10 +0000
Paul Cercueil <paul@crapouillou.net> wrote:

> A lot of drivers create a dev_pm_ops struct with the system sleep
> suspend/resume callbacks set to pm_runtime_force_suspend() and
> pm_runtime_force_resume().
> 
> These drivers can now use the DEFINE_RUNTIME_DEV_PM_OPS() macro, which
> will use pm_runtime_force_{suspend,resume}() as the system sleep
> callbacks, while having the same dead code removal characteristic that
> is already provided by DEFINE_SIMPLE_DEV_PM_OPS().
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>

I guess this is common enough to bother with a macro.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

> ---
>  include/linux/pm.h         |  3 +++
>  include/linux/pm_runtime.h | 14 ++++++++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index a1ce29566aea..01c4fe495b7a 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -411,6 +411,9 @@ const struct dev_pm_ops __maybe_unused name = { \
>   * suspend and "early" resume callback pointers, .suspend_late() and
>   * .resume_early(), to the same routines as .runtime_suspend() and
>   * .runtime_resume(), respectively (and analogously for hibernation).
> + *
> + * Deprecated. You most likely don't want this macro. Use
> + * DEFINE_RUNTIME_DEV_PM_OPS() instead.
>   */
>  #define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
>  const struct dev_pm_ops __maybe_unused name = { \
> diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
> index 016de5776b6d..4af454d29281 100644
> --- a/include/linux/pm_runtime.h
> +++ b/include/linux/pm_runtime.h
> @@ -22,6 +22,20 @@
>  					    usage_count */
>  #define RPM_AUTO		0x08	/* Use autosuspend_delay */
>  
> +/*
> + * Use this for defining a set of PM operations to be used in all situations
> + * (system suspend, hibernation or runtime PM).
> + *
> + * Note that the behaviour differs from the deprecated UNIVERSAL_DEV_PM_OPS()
> + * macro, which uses the provided callbacks for both runtime PM and system
> + * sleep, while DEFINE_RUNTIME_DEV_PM_OPS() uses pm_runtime_force_suspend()
> + * and pm_runtime_force_resume() for its system sleep callbacks.
> + */
> +#define DEFINE_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
> +	_DEFINE_DEV_PM_OPS(name, pm_runtime_force_suspend, \
> +			   pm_runtime_force_resume, suspend_fn, \
> +			   resume_fn, idle_fn)
> +
>  #ifdef CONFIG_PM
>  extern struct workqueue_struct *pm_wq;
>  


^ permalink raw reply

* [Intel-gfx] [PATCH 1/2] drm/i915: move i915_reg_read_ioctl declaration to intel_uncore.h
From: Jani Nikula @ 2022-01-05 10:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Jani Nikula

Declarations should be where the implementation is.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h     | 3 ---
 drivers/gpu/drm/i915/intel_uncore.h | 7 ++++++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index beeb42a14aae..e5183743fe93 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1778,9 +1778,6 @@ mkwrite_device_info(struct drm_i915_private *dev_priv)
 	return (struct intel_device_info *)INTEL_INFO(dev_priv);
 }
 
-int i915_reg_read_ioctl(struct drm_device *dev, void *data,
-			struct drm_file *file);
-
 static inline int intel_hws_csb_write_index(struct drm_i915_private *i915)
 {
 	if (GRAPHICS_VER(i915) >= 11)
diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h
index 210fe2a71612..3a87bbd906f8 100644
--- a/drivers/gpu/drm/i915/intel_uncore.h
+++ b/drivers/gpu/drm/i915/intel_uncore.h
@@ -32,10 +32,12 @@
 
 #include "i915_reg.h"
 
+struct drm_device;
+struct drm_file;
 struct drm_i915_private;
+struct intel_gt;
 struct intel_runtime_pm;
 struct intel_uncore;
-struct intel_gt;
 
 struct intel_uncore_mmio_debug {
 	spinlock_t lock; /** lock is also taken in irq contexts. */
@@ -455,4 +457,7 @@ static inline int intel_uncore_write_and_verify(struct intel_uncore *uncore,
 #define raw_reg_write(base, reg, value) \
 	writel(value, base + i915_mmio_reg_offset(reg))
 
+int i915_reg_read_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file);
+
 #endif /* !__INTEL_UNCORE_H__ */
-- 
2.30.2


^ permalink raw reply related

* Re: mtd-utils-2.1.3.tar.bz2 missing jffs2.h file?
From: David Oberhollenzer @ 2022-01-05 10:04 UTC (permalink / raw)
  To: Nick, linux-mtd
In-Reply-To: <5be0bd36-f135-f474-293d-75824c118e7c@systemli.org>

Hi,

On 12/29/21 16:58, Nick wrote:
> In "mtd-utils-2.1.3.tar.bz2" the file "include/linux/jffs2.h" is
> missing. In "mtd-utils-2.1.2.tar.bz2" it is contained and also in the
> git. Is that intended?
>

that is not intended. I just investigated this and can confirm, that the
recent release tarball misses the header.

It appears this was caused by commit a888044525. The source file list was
reshuffled and a missing escape character caused the file to be omitted
from the source list.

The problem apparently went unnoticed, as the system on which the release
tarball was built, as well as a test VM, had the same header installed in
the system include directory, so a `make distcheck` didn't fail and the
build/test from the tarball on the VM also succeeded.

This should now be fixed in commit c3a92d6bdc. Although there were only a
hand full of fixes on master, but 2.1.3 is already 6 months old, so I would
simply follow that up later with a new release from the current master.

Greetings,

David


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply

* Re: [PATCH 1/4] i2c: at91: add compatible with microchip,sama7g5-i2c
From: Michael Walle @ 2022-01-05 10:04 UTC (permalink / raw)
  To: eugen.hristev; +Cc: hs, u-boot, Michael Walle
In-Reply-To: <20220104184359.315440-1-eugen.hristev@microchip.com>

Hi,

> Add compatible and data platform struct for sama7g5 SoC.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> ---
>  drivers/i2c/at91_i2c.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c
> index 6b4c0e4804..400a3786ca 100644
> --- a/drivers/i2c/at91_i2c.c
> +++ b/drivers/i2c/at91_i2c.c
> @@ -305,6 +305,11 @@ static const struct at91_i2c_pdata sama5d2_config = {
>  	.clk_offset = 3,
>  };
>  
> +static const struct at91_i2c_pdata sama7g5_config = {
> +	.clk_max_div = 7,
> +	.clk_offset = 3,
> +};
> +
>  static const struct udevice_id at91_i2c_ids[] = {
>  { .compatible = "atmel,at91rm9200-i2c", .data = (long)&at91rm9200_config },
>  { .compatible = "atmel,at91sam9260-i2c", .data = (long)&at91sam9260_config },
> @@ -314,6 +319,7 @@ static const struct udevice_id at91_i2c_ids[] = {
>  { .compatible = "atmel,at91sam9x5-i2c", .data = (long)&at91sam9x5_config },
>  { .compatible = "atmel,sama5d4-i2c", .data = (long)&sama5d4_config },
>  { .compatible = "atmel,sama5d2-i2c", .data = (long)&sama5d2_config },
> +{ .compatible = "microchip,sama7g5-i2c", .data = (long)&sama7g5_config },

I see that this compatible string is is also used in the linux
device tree, but there is no dt binding for it in linux. Could you
add it, so the binding is approved by Rob?

-michael

^ permalink raw reply

* Re: [RFC 04/10] vdpa-dev: implement the instance_init/class_init interface
From: Stefan Hajnoczi @ 2022-01-05 10:00 UTC (permalink / raw)
  To: Longpeng(Mike)
  Cc: mst, jasowang, cohuck, qemu-devel, yechuan, arei.gonglei,
	huangzhichao, pbonzini, sgarzare
In-Reply-To: <20220105005900.860-5-longpeng2@huawei.com>

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

On Wed, Jan 05, 2022 at 08:58:54AM +0800, Longpeng(Mike) wrote:
> From: Longpeng <longpeng2@huawei.com>
> 
> Implements the .instance_init and the .class_init interface.
> 
> Signed-off-by: Longpeng <longpeng2@huawei.com>
> ---
>  hw/virtio/vdpa-dev-pci.c     | 80 +++++++++++++++++++++++++++++++++++-
>  hw/virtio/vdpa-dev.c         | 68 +++++++++++++++++++++++++++++-
>  include/hw/virtio/vdpa-dev.h |  2 +
>  3 files changed, 146 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/virtio/vdpa-dev-pci.c b/hw/virtio/vdpa-dev-pci.c
> index a5a7b528a9..0af54a26d4 100644
> --- a/hw/virtio/vdpa-dev-pci.c
> +++ b/hw/virtio/vdpa-dev-pci.c
> @@ -23,14 +23,90 @@ struct VhostVdpaDevicePCI {
>      VhostVdpaDevice vdev;
>  };
>  
> +static uint32_t
> +vdpa_dev_pci_get_info(const char *name, uint64_t cmd, Error **errp)

vdpa_dev_pci_get_u32() might be a clearer name.

> +{
> +    int device_fd;
> +    uint32_t val;
> +    int ret;
> +
> +    device_fd = qemu_open(name, O_RDWR, errp);
> +    if (device_fd == -1) {
> +        return (uint32_t)-1;
> +    }
> +
> +    ret = ioctl(device_fd, cmd, &val);
> +    if (ret < 0) {
> +        error_setg(errp, "vhost-vdpa-device-pci: cmd 0x%lx failed: %s",
> +                   cmd, strerror(errno));
> +        goto out;
> +    }
> +
> +out:
> +    close(device_fd);

Race conditions are possible if the device node is replaced between
calls. Why not open the file once and reuse the fd across ioctl calls?

Both VhostVdpaDevicePCI and VhostVdpaDevice need the fd but
VhostVdpaDevicePCI needs it first. I suggest passing ownership of the fd
to the VhostVdpaDevice. One way of doing this is using QOM properties so
that VhostVdpaDevice can use the given fd instead of reopening the file.
(If fd is -1 then VhostVdpaDevice can try to open the file. That is
necessary when VhostVdpaDevice is used directly with virtio-mmio because
there is no proxy object.)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [Buildroot] [PATCH 1/2] package/x11r7/xdriver_xf86-video-amdgpu: needs opengl
From: Arnout Vandecappelle @ 2022-01-05 10:04 UTC (permalink / raw)
  To: Bernd Kuhls, buildroot
In-Reply-To: <20200410123207.3145145-1-bernd.kuhls@t-online.de>



On 10/04/2020 14:32, Bernd Kuhls wrote:
> The package needs dri.h
> https://cgit.freedesktop.org/xorg/driver/xf86-video-amdgpu/tree/src/amdgpu_probe.c#n53
> https://cgit.freedesktop.org/xorg/driver/xf86-video-amdgpu/tree/src/drmmode_display.c#n50
> 
> which is only provided by xserver_xorg-server when opengl is enabled:
> https://git.buildroot.net/buildroot/tree/package/x11r7/xserver_xorg-server/xserver_xorg-server.mk#n123
> 
> Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
> ---
> The build error was not recorded by the autobuilders because they fail
> already during at configure stage due to wrong dependencies for glamor
> support fixed in the second patch of this series.
> 
>   package/x11r7/xdriver_xf86-video-amdgpu/Config.in | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/package/x11r7/xdriver_xf86-video-amdgpu/Config.in b/package/x11r7/xdriver_xf86-video-amdgpu/Config.in
> index c42255f55c..fb18c0d812 100644
> --- a/package/x11r7/xdriver_xf86-video-amdgpu/Config.in
> +++ b/package/x11r7/xdriver_xf86-video-amdgpu/Config.in
> @@ -2,6 +2,7 @@ config BR2_PACKAGE_XDRIVER_XF86_VIDEO_AMDGPU
>   	bool "xf86-video-amdgpu"
>   	depends on BR2_USE_MMU # libdrm
>   	depends on BR2_PACKAGE_MESA3D_DRI_DRIVER
> +	depends on BR2_PACKAGE_MESA3D_OPENGL_GLX # dri.h

  The condition in xorg-server is:

ifeq ($(BR2_PACKAGE_HAS_LIBGL),y)
XSERVER_XORG_SERVER_CONF_OPTS += --enable-dri --enable-glx
XSERVER_XORG_SERVER_DEPENDENCIES += libgl
else
XSERVER_XORG_SERVER_CONF_OPTS += --disable-dri --disable-glx
endif

So this should depend on HAS_LIBGL, no?


>   	depends on BR2_PACKAGE_MESA3D_OPENGL_EGL # gbm

  This one should probably also switch to the new gbm option.

  Regards,
  Arnout

>   	select BR2_PACKAGE_LIBDRM
>   	select BR2_PACKAGE_LIBDRM_AMDGPU
> @@ -14,4 +15,5 @@ config BR2_PACKAGE_XDRIVER_XF86_VIDEO_AMDGPU
>   comment "xf86-video-amdgpu needs egl/opengl support from mesa3d"
>   	depends on BR2_USE_MMU
>   	depends on !BR2_PACKAGE_MESA3D_OPENGL_EGL || \
> +		!BR2_PACKAGE_MESA3D_OPENGL_GLX || \
>   		!BR2_PACKAGE_MESA3D_DRI_DRIVER
> 
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply

* Re: [PATCH 3/8] PM: core: Add EXPORT[_GPL]_SIMPLE_DEV_PM_OPS macros
From: Jonathan Cameron @ 2022-01-05 10:03 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: Rafael J . Wysocki, Ulf Hansson, Jonathan Cameron,
	Lars-Peter Clausen, Linus Walleij, Arnd Bergmann, Len Brown,
	Pavel Machek, list, linux-iio, linux-kernel, linux-mips,
	linux-mmc, linux-pm
In-Reply-To: <20220104214214.198843-4-paul@crapouillou.net>

On Tue, 4 Jan 2022 21:42:09 +0000
Paul Cercueil <paul@crapouillou.net> wrote:

> These macros are defined conditionally, according to CONFIG_PM:
> - if CONFIG_PM is enabled, these macros resolve to
>   DEFINE_SIMPLE_DEV_PM_OPS(), and the dev_pm_ops symbol will be
>   exported.
> 
> - if CONFIG_PM is disabled, these macros will result in a dummy static
>   dev_pm_ops to be created with the __maybe_unused flag. The dev_pm_ops
>   will then be discarded by the compiler, along with the provided
>   callback functions if they are not used anywhere else.
> 
> In the second case, the symbol is not exported, which should be
> perfectly fine - users of the symbol should all use the pm_ptr() or
> pm_sleep_ptr() macro, so the dev_pm_ops marked as "extern" in the
> client's code will never be accessed.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> ---
>  include/linux/pm.h | 33 ++++++++++++++++++++++++++++++---
>  1 file changed, 30 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 389e600df233..a1ce29566aea 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -8,6 +8,7 @@
>  #ifndef _LINUX_PM_H
>  #define _LINUX_PM_H
>  
> +#include <linux/export.h>
>  #include <linux/list.h>
>  #include <linux/workqueue.h>
>  #include <linux/spinlock.h>
> @@ -357,14 +358,40 @@ struct dev_pm_ops {
>  #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn)
>  #endif
>  
> +#define _DEFINE_DEV_PM_OPS(name, \
> +			   suspend_fn, resume_fn, \
> +			   runtime_suspend_fn, runtime_resume_fn, idle_fn) \
> +const struct dev_pm_ops name = { \
> +	SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
> +	RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \
> +}
> +

one blank line probably enough.

> +
>  /*
>   * Use this if you want to use the same suspend and resume callbacks for suspend
>   * to RAM and hibernation.
>   */
>  #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
> -const struct dev_pm_ops name = { \
> -	SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
> -}
> +	_DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL)
> +
> +#ifdef CONFIG_PM
> +#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \
> +			   runtime_resume_fn, idle_fn, sec) \
> +	_DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \
> +			   runtime_resume_fn, idle_fn); \
> +	_EXPORT_SYMBOL(name, sec)
> +#else
> +#define _EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, runtime_suspend_fn, \
> +			   runtime_resume_fn, idle_fn, sec) \
> +static __maybe_unused _DEFINE_DEV_PM_OPS(__static_##name, suspend_fn, \
> +					 resume_fn, runtime_suspend_fn, \
> +					 runtime_resume_fn, idle_fn)
> +#endif
> +
> +#define EXPORT_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
> +	_EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "")
> +#define EXPORT_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
> +	_EXPORT_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL, "_gpl")

So you can get away with these two cases because the SYSTEM_SLEEP_PM_OPS() all have
pm_sleep_ptr() wrappers.  However, _EXPORT_DEV_PM_OPS() could be used directly and
would require __maybe_unused for the RUNTIME_PM_OPS() parameters which isn't ideal.

Maybe I'm missing some reason that isn't a problem though as easy to get lost in
these macros. :)

You could argue that the _ is meant to indicate that macro shouldn't be used directly
but I'm not that optimistic.

Jonathan



>  
>  /* Deprecated. Use DEFINE_SIMPLE_DEV_PM_OPS() instead. */
>  #define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \


^ permalink raw reply

* [andrea-aa:main 44/48] mm/ksm.c:2134 cmp_and_merge_page() error: uninitialized symbol 'checksum'.
From: Dan Carpenter @ 2022-01-05 10:02 UTC (permalink / raw)
  To: kbuild, Andrea Arcangeli; +Cc: lkp, kbuild-all, linux-kernel

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/andrea/aa.git main
head:   2f1336124b54750df7ae428da9352e4d8091f31e
commit: fec43fa50ccf8365ae2a8d9f150970ab6ca42b18 [44/48] KSM: only attempt to merge with KSM pages if the payload doesn't change
config: i386-randconfig-m021-20211218 (https://download.01.org/0day-ci/archive/20211219/202112190517.NPcuhEOX-lkp@intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

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

smatch warnings:
mm/ksm.c:2134 cmp_and_merge_page() error: uninitialized symbol 'checksum'.

vim +/checksum +2134 mm/ksm.c

31dbd01f314364 Izik Eidus        2009-09-21  2059  static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
31dbd01f314364 Izik Eidus        2009-09-21  2060  {
4b22927f0cbd58 Kirill Tkhai      2017-10-03  2061  	struct mm_struct *mm = rmap_item->mm;
31dbd01f314364 Izik Eidus        2009-09-21  2062  	struct rmap_item *tree_rmap_item;
8dd3557a52f0bc Hugh Dickins      2009-12-14  2063  	struct page *tree_page = NULL;
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2064  	struct stable_node *stable_node;
8dd3557a52f0bc Hugh Dickins      2009-12-14  2065  	struct page *kpage;
31dbd01f314364 Izik Eidus        2009-09-21  2066  	unsigned int checksum;
31dbd01f314364 Izik Eidus        2009-09-21  2067  	int err;
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2068  	bool max_page_sharing_bypass = false;
31dbd01f314364 Izik Eidus        2009-09-21  2069  
4146d2d673e8d6 Hugh Dickins      2013-02-22  2070  	stable_node = page_stable_node(page);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2071  	if (stable_node) {
4146d2d673e8d6 Hugh Dickins      2013-02-22  2072  		if (stable_node->head != &migrate_nodes &&
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2073  		    get_kpfn_nid(READ_ONCE(stable_node->kpfn)) !=
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2074  		    NUMA(stable_node->nid)) {
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2075  			stable_node_dup_del(stable_node);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2076  			stable_node->head = &migrate_nodes;
4146d2d673e8d6 Hugh Dickins      2013-02-22  2077  			list_add(&stable_node->list, stable_node->head);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2078  		}
4146d2d673e8d6 Hugh Dickins      2013-02-22  2079  		if (stable_node->head != &migrate_nodes &&
4146d2d673e8d6 Hugh Dickins      2013-02-22  2080  		    rmap_item->head == stable_node)
4146d2d673e8d6 Hugh Dickins      2013-02-22  2081  			return;
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2082  		/*
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2083  		 * If it's a KSM fork, allow it to go over the sharing limit
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2084  		 * without warnings.
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2085  		 */
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2086  		if (!is_page_sharing_candidate(stable_node))
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2087  			max_page_sharing_bypass = true;
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2088  	} else {
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2089  		/*
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2090  		 * If the hash value of the page has changed from the last
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2091  		 * time we calculated it, this page is changing frequently:
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2092  		 * therefore we don't want to write protect it.
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2093  		 */
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2094  		checksum = calc_checksum(page);

"checksum" initialized here.  Not intialized for stable_node.

fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2095  		if (rmap_item->oldchecksum != checksum) {
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2096  			rmap_item->oldchecksum = checksum;
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2097  			remove_rmap_item_from_tree(rmap_item);
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2098  			return;
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2099  		}
4146d2d673e8d6 Hugh Dickins      2013-02-22  2100  	}
31dbd01f314364 Izik Eidus        2009-09-21  2101  
31dbd01f314364 Izik Eidus        2009-09-21  2102  	/* We first start with searching the page inside the stable tree */
62b61f611eb5e2 Hugh Dickins      2009-12-14  2103  	kpage = stable_tree_search(page);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2104  	if (kpage == page && rmap_item->head == stable_node) {
4146d2d673e8d6 Hugh Dickins      2013-02-22  2105  		put_page(kpage);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2106  		return;
4146d2d673e8d6 Hugh Dickins      2013-02-22  2107  	}
4146d2d673e8d6 Hugh Dickins      2013-02-22  2108  
4146d2d673e8d6 Hugh Dickins      2013-02-22  2109  	remove_rmap_item_from_tree(rmap_item);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2110  
62b61f611eb5e2 Hugh Dickins      2009-12-14  2111  	if (kpage) {
2cee57d1b08877 Yang Shi          2019-03-05  2112  		if (PTR_ERR(kpage) == -EBUSY)
2cee57d1b08877 Yang Shi          2019-03-05  2113  			return;
2cee57d1b08877 Yang Shi          2019-03-05  2114  
08beca44dfb0ab Hugh Dickins      2009-12-14  2115  		err = try_to_merge_with_ksm_page(rmap_item, page, kpage);
31dbd01f314364 Izik Eidus        2009-09-21  2116  		if (!err) {
31dbd01f314364 Izik Eidus        2009-09-21  2117  			/*
31dbd01f314364 Izik Eidus        2009-09-21  2118  			 * The page was successfully merged:
31dbd01f314364 Izik Eidus        2009-09-21  2119  			 * add its rmap_item to the stable tree.
31dbd01f314364 Izik Eidus        2009-09-21  2120  			 */
5ad6468801d28c Hugh Dickins      2009-12-14  2121  			lock_page(kpage);
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2122  			stable_tree_append(rmap_item, page_stable_node(kpage),
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2123  					   max_page_sharing_bypass);
5ad6468801d28c Hugh Dickins      2009-12-14  2124  			unlock_page(kpage);
31dbd01f314364 Izik Eidus        2009-09-21  2125  		}
8dd3557a52f0bc Hugh Dickins      2009-12-14  2126  		put_page(kpage);
31dbd01f314364 Izik Eidus        2009-09-21  2127  		return;
31dbd01f314364 Izik Eidus        2009-09-21  2128  	}
31dbd01f314364 Izik Eidus        2009-09-21  2129  
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2130  	/*
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2131  	 * Same checksum as an empty page. We attempt to merge it with the
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2132  	 * appropriate zero page if the user enabled this via sysfs.
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2133  	 */
e86c59b1b12d0d Claudio Imbrenda  2017-02-24 @2134  	if (ksm_use_zero_pages && (checksum == zero_checksum)) {

uninitialized here.  Smatch cannot see how ksm_use_zero_pages and
stable_node are related.  (Neither can I but I have not looked at the
context).

e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2135  		struct vm_area_struct *vma;
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2136  
d8ed45c5dcd455 Michel Lespinasse 2020-06-08  2137  		mmap_read_lock(mm);
4b22927f0cbd58 Kirill Tkhai      2017-10-03  2138  		vma = find_mergeable_vma(mm, rmap_item->address);
56df70a63ed5d9 Muchun Song       2020-04-20  2139  		if (vma) {
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2140  			err = try_to_merge_one_page(vma, page,
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2141  					ZERO_PAGE(rmap_item->address));
56df70a63ed5d9 Muchun Song       2020-04-20  2142  		} else {
56df70a63ed5d9 Muchun Song       2020-04-20  2143  			/*
56df70a63ed5d9 Muchun Song       2020-04-20  2144  			 * If the vma is out of date, we do not need to
56df70a63ed5d9 Muchun Song       2020-04-20  2145  			 * continue.
56df70a63ed5d9 Muchun Song       2020-04-20  2146  			 */
56df70a63ed5d9 Muchun Song       2020-04-20  2147  			err = 0;
56df70a63ed5d9 Muchun Song       2020-04-20  2148  		}
d8ed45c5dcd455 Michel Lespinasse 2020-06-08  2149  		mmap_read_unlock(mm);
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2150  		/*
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2151  		 * In case of failure, the page was not really empty, so we
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2152  		 * need to continue. Otherwise we're done.
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2153  		 */
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2154  		if (!err)
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2155  			return;
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2156  	}
8dd3557a52f0bc Hugh Dickins      2009-12-14  2157  	tree_rmap_item =
8dd3557a52f0bc Hugh Dickins      2009-12-14  2158  		unstable_tree_search_insert(rmap_item, page, &tree_page);
31dbd01f314364 Izik Eidus        2009-09-21  2159  	if (tree_rmap_item) {
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2160  		bool split;
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2161  
8dd3557a52f0bc Hugh Dickins      2009-12-14  2162  		kpage = try_to_merge_two_pages(rmap_item, page,
8dd3557a52f0bc Hugh Dickins      2009-12-14  2163  						tree_rmap_item, tree_page);
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2164  		/*
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2165  		 * If both pages we tried to merge belong to the same compound
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2166  		 * page, then we actually ended up increasing the reference
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2167  		 * count of the same compound page twice, and split_huge_page
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2168  		 * failed.
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2169  		 * Here we set a flag if that happened, and we use it later to
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2170  		 * try split_huge_page again. Since we call put_page right
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2171  		 * afterwards, the reference count will be correct and
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2172  		 * split_huge_page should succeed.
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2173  		 */
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2174  		split = PageTransCompound(page)
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2175  			&& compound_head(page) == compound_head(tree_page);
8dd3557a52f0bc Hugh Dickins      2009-12-14  2176  		put_page(tree_page);
bc56620b493496 Hugh Dickins      2013-02-22  2177  		if (kpage) {
31dbd01f314364 Izik Eidus        2009-09-21  2178  			/*
bc56620b493496 Hugh Dickins      2013-02-22  2179  			 * The pages were successfully merged: insert new
bc56620b493496 Hugh Dickins      2013-02-22  2180  			 * node in the stable tree and add both rmap_items.
31dbd01f314364 Izik Eidus        2009-09-21  2181  			 */
5ad6468801d28c Hugh Dickins      2009-12-14  2182  			lock_page(kpage);
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2183  			stable_node = stable_tree_insert(kpage);
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2184  			if (stable_node) {
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2185  				stable_tree_append(tree_rmap_item, stable_node,
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2186  						   false);
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2187  				stable_tree_append(rmap_item, stable_node,
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2188  						   false);
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2189  			}
5ad6468801d28c Hugh Dickins      2009-12-14  2190  			unlock_page(kpage);
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2191  
31dbd01f314364 Izik Eidus        2009-09-21  2192  			/*
31dbd01f314364 Izik Eidus        2009-09-21  2193  			 * If we fail to insert the page into the stable tree,
31dbd01f314364 Izik Eidus        2009-09-21  2194  			 * we will have 2 virtual addresses that are pointing
31dbd01f314364 Izik Eidus        2009-09-21  2195  			 * to a ksm page left outside the stable tree,
31dbd01f314364 Izik Eidus        2009-09-21  2196  			 * in which case we need to break_cow on both.
31dbd01f314364 Izik Eidus        2009-09-21  2197  			 */
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2198  			if (!stable_node) {
8dd3557a52f0bc Hugh Dickins      2009-12-14  2199  				break_cow(tree_rmap_item);
8dd3557a52f0bc Hugh Dickins      2009-12-14  2200  				break_cow(rmap_item);
31dbd01f314364 Izik Eidus        2009-09-21  2201  			}
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2202  		} else if (split) {
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2203  			/*
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2204  			 * We are here if we tried to merge two pages and
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2205  			 * failed because they both belonged to the same
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2206  			 * compound page. We will split the page now, but no
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2207  			 * merging will take place.
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2208  			 * We do not want to add the cost of a full lock; if
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2209  			 * the page is locked, it is better to skip it and
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2210  			 * perhaps try again later.
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2211  			 */
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2212  			if (!trylock_page(page))
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2213  				return;
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2214  			split_huge_page(page);
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2215  			unlock_page(page);
31dbd01f314364 Izik Eidus        2009-09-21  2216  		}
31dbd01f314364 Izik Eidus        2009-09-21  2217  	}
31dbd01f314364 Izik Eidus        2009-09-21  2218  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org


^ permalink raw reply

* Re: [PATCH] platform: finally disallow IRQ0 in platform_get_irq() and its ilk
From: Andy Shevchenko @ 2022-01-05 10:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Marc Zyngier, Geert Uytterhoeven, Sergey Shtylyov,
	Rafael J. Wysocki, Linux Kernel Mailing List, Thomas Gleixner
In-Reply-To: <YdQnLuQseVhq40yd@kroah.com>

On Tue, Jan 4, 2022 at 2:08 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
> On Tue, Jan 04, 2022 at 10:48:00AM +0000, Marc Zyngier wrote:
> > On Tue, 04 Jan 2022 09:47:21 +0000,
> > Geert Uytterhoeven <geert@linux-m68k.org> wrote:

...

> > I think the end-goal is to never return 0. Either we return a valid
> > interrupt number, or we return an error. It should be the
> > responsibility of the caller to decide what they want to do in the
> > error case.
>
> As 0 still is a valid irq for some platforms (as mentioned above), then
> how is this ever going to be possible?

To avoid that we should first convert that SH case to use IRQ domains
instead of putting some arbitrary (HW dependent) values to IRQ
resources. When that is done it won't use vIRQ0 anymore. So, I agree
with Marc on that, except _optinal variants, but it doesn't contradict
the basic idea.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* [andrea-aa:main 44/48] mm/ksm.c:2134 cmp_and_merge_page() error: uninitialized symbol 'checksum'.
From: Dan Carpenter @ 2022-01-05 10:02 UTC (permalink / raw)
  To: kbuild-all

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

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/andrea/aa.git main
head:   2f1336124b54750df7ae428da9352e4d8091f31e
commit: fec43fa50ccf8365ae2a8d9f150970ab6ca42b18 [44/48] KSM: only attempt to merge with KSM pages if the payload doesn't change
config: i386-randconfig-m021-20211218 (https://download.01.org/0day-ci/archive/20211219/202112190517.NPcuhEOX-lkp(a)intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

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

smatch warnings:
mm/ksm.c:2134 cmp_and_merge_page() error: uninitialized symbol 'checksum'.

vim +/checksum +2134 mm/ksm.c

31dbd01f314364 Izik Eidus        2009-09-21  2059  static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
31dbd01f314364 Izik Eidus        2009-09-21  2060  {
4b22927f0cbd58 Kirill Tkhai      2017-10-03  2061  	struct mm_struct *mm = rmap_item->mm;
31dbd01f314364 Izik Eidus        2009-09-21  2062  	struct rmap_item *tree_rmap_item;
8dd3557a52f0bc Hugh Dickins      2009-12-14  2063  	struct page *tree_page = NULL;
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2064  	struct stable_node *stable_node;
8dd3557a52f0bc Hugh Dickins      2009-12-14  2065  	struct page *kpage;
31dbd01f314364 Izik Eidus        2009-09-21  2066  	unsigned int checksum;
31dbd01f314364 Izik Eidus        2009-09-21  2067  	int err;
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2068  	bool max_page_sharing_bypass = false;
31dbd01f314364 Izik Eidus        2009-09-21  2069  
4146d2d673e8d6 Hugh Dickins      2013-02-22  2070  	stable_node = page_stable_node(page);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2071  	if (stable_node) {
4146d2d673e8d6 Hugh Dickins      2013-02-22  2072  		if (stable_node->head != &migrate_nodes &&
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2073  		    get_kpfn_nid(READ_ONCE(stable_node->kpfn)) !=
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2074  		    NUMA(stable_node->nid)) {
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2075  			stable_node_dup_del(stable_node);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2076  			stable_node->head = &migrate_nodes;
4146d2d673e8d6 Hugh Dickins      2013-02-22  2077  			list_add(&stable_node->list, stable_node->head);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2078  		}
4146d2d673e8d6 Hugh Dickins      2013-02-22  2079  		if (stable_node->head != &migrate_nodes &&
4146d2d673e8d6 Hugh Dickins      2013-02-22  2080  		    rmap_item->head == stable_node)
4146d2d673e8d6 Hugh Dickins      2013-02-22  2081  			return;
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2082  		/*
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2083  		 * If it's a KSM fork, allow it to go over the sharing limit
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2084  		 * without warnings.
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2085  		 */
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2086  		if (!is_page_sharing_candidate(stable_node))
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2087  			max_page_sharing_bypass = true;
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2088  	} else {
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2089  		/*
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2090  		 * If the hash value of the page has changed from the last
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2091  		 * time we calculated it, this page is changing frequently:
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2092  		 * therefore we don't want to write protect it.
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2093  		 */
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2094  		checksum = calc_checksum(page);

"checksum" initialized here.  Not intialized for stable_node.

fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2095  		if (rmap_item->oldchecksum != checksum) {
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2096  			rmap_item->oldchecksum = checksum;
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2097  			remove_rmap_item_from_tree(rmap_item);
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2098  			return;
fec43fa50ccf83 Andrea Arcangeli  2021-11-23  2099  		}
4146d2d673e8d6 Hugh Dickins      2013-02-22  2100  	}
31dbd01f314364 Izik Eidus        2009-09-21  2101  
31dbd01f314364 Izik Eidus        2009-09-21  2102  	/* We first start with searching the page inside the stable tree */
62b61f611eb5e2 Hugh Dickins      2009-12-14  2103  	kpage = stable_tree_search(page);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2104  	if (kpage == page && rmap_item->head == stable_node) {
4146d2d673e8d6 Hugh Dickins      2013-02-22  2105  		put_page(kpage);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2106  		return;
4146d2d673e8d6 Hugh Dickins      2013-02-22  2107  	}
4146d2d673e8d6 Hugh Dickins      2013-02-22  2108  
4146d2d673e8d6 Hugh Dickins      2013-02-22  2109  	remove_rmap_item_from_tree(rmap_item);
4146d2d673e8d6 Hugh Dickins      2013-02-22  2110  
62b61f611eb5e2 Hugh Dickins      2009-12-14  2111  	if (kpage) {
2cee57d1b08877 Yang Shi          2019-03-05  2112  		if (PTR_ERR(kpage) == -EBUSY)
2cee57d1b08877 Yang Shi          2019-03-05  2113  			return;
2cee57d1b08877 Yang Shi          2019-03-05  2114  
08beca44dfb0ab Hugh Dickins      2009-12-14  2115  		err = try_to_merge_with_ksm_page(rmap_item, page, kpage);
31dbd01f314364 Izik Eidus        2009-09-21  2116  		if (!err) {
31dbd01f314364 Izik Eidus        2009-09-21  2117  			/*
31dbd01f314364 Izik Eidus        2009-09-21  2118  			 * The page was successfully merged:
31dbd01f314364 Izik Eidus        2009-09-21  2119  			 * add its rmap_item to the stable tree.
31dbd01f314364 Izik Eidus        2009-09-21  2120  			 */
5ad6468801d28c Hugh Dickins      2009-12-14  2121  			lock_page(kpage);
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2122  			stable_tree_append(rmap_item, page_stable_node(kpage),
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2123  					   max_page_sharing_bypass);
5ad6468801d28c Hugh Dickins      2009-12-14  2124  			unlock_page(kpage);
31dbd01f314364 Izik Eidus        2009-09-21  2125  		}
8dd3557a52f0bc Hugh Dickins      2009-12-14  2126  		put_page(kpage);
31dbd01f314364 Izik Eidus        2009-09-21  2127  		return;
31dbd01f314364 Izik Eidus        2009-09-21  2128  	}
31dbd01f314364 Izik Eidus        2009-09-21  2129  
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2130  	/*
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2131  	 * Same checksum as an empty page. We attempt to merge it with the
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2132  	 * appropriate zero page if the user enabled this via sysfs.
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2133  	 */
e86c59b1b12d0d Claudio Imbrenda  2017-02-24 @2134  	if (ksm_use_zero_pages && (checksum == zero_checksum)) {

uninitialized here.  Smatch cannot see how ksm_use_zero_pages and
stable_node are related.  (Neither can I but I have not looked at the
context).

e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2135  		struct vm_area_struct *vma;
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2136  
d8ed45c5dcd455 Michel Lespinasse 2020-06-08  2137  		mmap_read_lock(mm);
4b22927f0cbd58 Kirill Tkhai      2017-10-03  2138  		vma = find_mergeable_vma(mm, rmap_item->address);
56df70a63ed5d9 Muchun Song       2020-04-20  2139  		if (vma) {
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2140  			err = try_to_merge_one_page(vma, page,
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2141  					ZERO_PAGE(rmap_item->address));
56df70a63ed5d9 Muchun Song       2020-04-20  2142  		} else {
56df70a63ed5d9 Muchun Song       2020-04-20  2143  			/*
56df70a63ed5d9 Muchun Song       2020-04-20  2144  			 * If the vma is out of date, we do not need to
56df70a63ed5d9 Muchun Song       2020-04-20  2145  			 * continue.
56df70a63ed5d9 Muchun Song       2020-04-20  2146  			 */
56df70a63ed5d9 Muchun Song       2020-04-20  2147  			err = 0;
56df70a63ed5d9 Muchun Song       2020-04-20  2148  		}
d8ed45c5dcd455 Michel Lespinasse 2020-06-08  2149  		mmap_read_unlock(mm);
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2150  		/*
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2151  		 * In case of failure, the page was not really empty, so we
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2152  		 * need to continue. Otherwise we're done.
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2153  		 */
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2154  		if (!err)
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2155  			return;
e86c59b1b12d0d Claudio Imbrenda  2017-02-24  2156  	}
8dd3557a52f0bc Hugh Dickins      2009-12-14  2157  	tree_rmap_item =
8dd3557a52f0bc Hugh Dickins      2009-12-14  2158  		unstable_tree_search_insert(rmap_item, page, &tree_page);
31dbd01f314364 Izik Eidus        2009-09-21  2159  	if (tree_rmap_item) {
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2160  		bool split;
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2161  
8dd3557a52f0bc Hugh Dickins      2009-12-14  2162  		kpage = try_to_merge_two_pages(rmap_item, page,
8dd3557a52f0bc Hugh Dickins      2009-12-14  2163  						tree_rmap_item, tree_page);
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2164  		/*
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2165  		 * If both pages we tried to merge belong to the same compound
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2166  		 * page, then we actually ended up increasing the reference
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2167  		 * count of the same compound page twice, and split_huge_page
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2168  		 * failed.
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2169  		 * Here we set a flag if that happened, and we use it later to
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2170  		 * try split_huge_page again. Since we call put_page right
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2171  		 * afterwards, the reference count will be correct and
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2172  		 * split_huge_page should succeed.
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2173  		 */
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2174  		split = PageTransCompound(page)
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2175  			&& compound_head(page) == compound_head(tree_page);
8dd3557a52f0bc Hugh Dickins      2009-12-14  2176  		put_page(tree_page);
bc56620b493496 Hugh Dickins      2013-02-22  2177  		if (kpage) {
31dbd01f314364 Izik Eidus        2009-09-21  2178  			/*
bc56620b493496 Hugh Dickins      2013-02-22  2179  			 * The pages were successfully merged: insert new
bc56620b493496 Hugh Dickins      2013-02-22  2180  			 * node in the stable tree and add both rmap_items.
31dbd01f314364 Izik Eidus        2009-09-21  2181  			 */
5ad6468801d28c Hugh Dickins      2009-12-14  2182  			lock_page(kpage);
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2183  			stable_node = stable_tree_insert(kpage);
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2184  			if (stable_node) {
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2185  				stable_tree_append(tree_rmap_item, stable_node,
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2186  						   false);
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2187  				stable_tree_append(rmap_item, stable_node,
2c653d0ee2ae78 Andrea Arcangeli  2017-07-06  2188  						   false);
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2189  			}
5ad6468801d28c Hugh Dickins      2009-12-14  2190  			unlock_page(kpage);
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2191  
31dbd01f314364 Izik Eidus        2009-09-21  2192  			/*
31dbd01f314364 Izik Eidus        2009-09-21  2193  			 * If we fail to insert the page into the stable tree,
31dbd01f314364 Izik Eidus        2009-09-21  2194  			 * we will have 2 virtual addresses that are pointing
31dbd01f314364 Izik Eidus        2009-09-21  2195  			 * to a ksm page left outside the stable tree,
31dbd01f314364 Izik Eidus        2009-09-21  2196  			 * in which case we need to break_cow on both.
31dbd01f314364 Izik Eidus        2009-09-21  2197  			 */
7b6ba2c7d3baf8 Hugh Dickins      2009-12-14  2198  			if (!stable_node) {
8dd3557a52f0bc Hugh Dickins      2009-12-14  2199  				break_cow(tree_rmap_item);
8dd3557a52f0bc Hugh Dickins      2009-12-14  2200  				break_cow(rmap_item);
31dbd01f314364 Izik Eidus        2009-09-21  2201  			}
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2202  		} else if (split) {
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2203  			/*
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2204  			 * We are here if we tried to merge two pages and
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2205  			 * failed because they both belonged to the same
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2206  			 * compound page. We will split the page now, but no
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2207  			 * merging will take place.
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2208  			 * We do not want to add the cost of a full lock; if
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2209  			 * the page is locked, it is better to skip it and
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2210  			 * perhaps try again later.
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2211  			 */
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2212  			if (!trylock_page(page))
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2213  				return;
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2214  			split_huge_page(page);
77da2ba0648a4f Claudio Imbrenda  2018-04-05  2215  			unlock_page(page);
31dbd01f314364 Izik Eidus        2009-09-21  2216  		}
31dbd01f314364 Izik Eidus        2009-09-21  2217  	}
31dbd01f314364 Izik Eidus        2009-09-21  2218  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply

* Re: [Buildroot] [PATCH 1/1] package/avahi: add gobject-introspection optional dependency
From: Arnout Vandecappelle @ 2022-01-05 10:02 UTC (permalink / raw)
  To: Fabrice Fontaine, buildroot
In-Reply-To: <20200407175535.409309-1-fontaine.fabrice@gmail.com>



On 07/04/2020 19:55, Fabrice Fontaine wrote:
> Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
> ---
>   package/avahi/avahi.mk | 7 +++++++
>   1 file changed, 7 insertions(+)
> 
> diff --git a/package/avahi/avahi.mk b/package/avahi/avahi.mk
> index 73db37545f..3546979d83 100644
> --- a/package/avahi/avahi.mk
> +++ b/package/avahi/avahi.mk
> @@ -82,6 +82,13 @@ else
>   AVAHI_CONF_OPTS += --disable-dbus
>   endif
>   
> +ifeq ($(BR2_PACKAGE_GOBJECT_INTROSPECTION),y)
> +AVAHI_CONF_OPTS += --enable-introspection
> +AVAHI_DEPENDENCIES += gobject-introspection

  It later turned out that this fails when DBUS is enabled, and the solution is 
too ugly to apply [1]. Therefore, I marked this as Rejected.

  Regards,
  Arnout

[1] 
https://patchwork.ozlabs.org/project/buildroot/patch/20200813232351.1552307-1-aduskett@gmail.com/


> +else 
> +AVAHI_CONF_OPTS += --disable-introspection
> +endif
> +
>   ifeq ($(BR2_PACKAGE_LIBEVENT),y)
>   AVAHI_DEPENDENCIES += libevent
>   else
> 
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply

* [PATCH 2/2] spapr: Fix support of POWER5+ processors
From: Cédric Le Goater @ 2022-01-05  9:51 UTC (permalink / raw)
  To: qemu-ppc, qemu-devel
  Cc: Alexey Kardashevskiy, Cédric Le Goater, Greg Kurz,
	David Gibson
In-Reply-To: <20220105095142.3990430-1-clg@kaod.org>

POWER5+ (ISA v2.03) processors are supported by the pseries machine
but they do not have Altivec instructions. Do not advertise support
for it in the DT.

To be noted that this test is in contradiction with the assert in
cap_vsx_apply().

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/spapr.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3b5fd749be89..69c9e1c59f5e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -723,10 +723,12 @@ static void spapr_dt_cpu(CPUState *cs, void *fdt, int offset,
      *
      * Only CPUs for which we create core types in spapr_cpu_core.c
      * are possible, and all of those have VMX */
-    if (spapr_get_cap(spapr, SPAPR_CAP_VSX) != 0) {
-        _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 2)));
-    } else {
-        _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 1)));
+    if (env->insns_flags & PPC_ALTIVEC) {
+        if (spapr_get_cap(spapr, SPAPR_CAP_VSX) != 0) {
+            _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 2)));
+        } else {
+            _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 1)));
+        }
     }
 
     /* Advertise DFP (Decimal Floating Point) if available
-- 
2.31.1



^ permalink raw reply related

* Re: [PATCH 2/4] coresight: trbe: Work around the ignored system register writes
From: Suzuki K Poulose @ 2022-01-05 10:01 UTC (permalink / raw)
  To: Anshuman Khandual, linux-arm-kernel
  Cc: Catalin Marinas, Will Deacon, Mathieu Poirier, coresight,
	linux-doc, linux-kernel
In-Reply-To: <1641359159-22726-3-git-send-email-anshuman.khandual@arm.com>

Hi Anshuman

On 05/01/2022 05:05, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2064142 might fail to write
> into certain system registers after the TRBE has been disabled. Under some
> conditions after TRBE has been disabled, writes into certain TRBE registers
> TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
> ignored and not be effected.
> 
> Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
> just after the trace collection has stopped and before performing a system
> register write to one of the affected registers. This adds a new cpu errata
> in arm64 errata framework and also updates TRBE driver as required.
> 
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose@arm.com>
> Cc: coresight@lists.linaro.org
> Cc: linux-doc@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>   Documentation/arm64/silicon-errata.rst       |  2 +
>   arch/arm64/Kconfig                           | 18 +++++++
>   arch/arm64/kernel/cpu_errata.c               |  9 ++++
>   arch/arm64/tools/cpucaps                     |  1 +
>   drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
>   drivers/hwtracing/coresight/coresight-trbe.h |  8 ---
>   6 files changed, 68 insertions(+), 24 deletions(-)

I think it may be a good idea to split the patch into
two parts :

- arm64 kernel part. (cpucap defintions and detection)
- trbe driver part

So that it is easier to merge these series upstream to
avoid conflicts.

> 
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index 5342e895fb60..c9b30e6c2b6c 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -52,6 +52,8 @@ stable kernels.
>   | Allwinner      | A64/R18         | UNKNOWN1        | SUN50I_ERRATUM_UNKNOWN1     |
>   +----------------+-----------------+-----------------+-----------------------------+
>   +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
> ++----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index c4207cf9bb17..2105b68d88db 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -778,6 +778,24 @@ config ARM64_ERRATUM_2224489
>   
>   	  If unsure, say Y.
>   
> +config ARM64_ERRATUM_2064142
> +	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
> +	depends on CORESIGHT_TRBE
> +	default y
> +	help
> +	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
> +
> +	  Affected Cortex-A510 core might fail to write into system registers after the
> +	  TRBE has been disabled. Under some conditions after the TRBE has been disabled
> +	  writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1,
> +	  and TRBTRG_EL1 will be ignored and will not be effected.
> +
> +	  Work around this in the driver by executing TSB CSYNC and DSB after collection
> +	  is stopped and before performing a system register write to one of the affected
> +	  registers.
> +
> +	  If unsure, say Y.
> +
>   config CAVIUM_ERRATUM_22375
>   	bool "Cavium erratum 22375, 24313"
>   	default y
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 9e1c1aef9ebd..cbb7d5a9aee7 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -597,6 +597,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>   		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
>   		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
>   	},
> +#endif
> +#ifdef CONFIG_ARM64_ERRATUM_2064142
> +	{
> +		.desc = "ARM erratum 2064142",
> +		.capability = ARM64_WORKAROUND_2064142,
> +
> +		/* Cortex-A510 r0p0 - r0p2 */
> +		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
> +	},
>   #endif
>   	{
>   	}
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 870c39537dd0..fca3cb329e1d 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -55,6 +55,7 @@ WORKAROUND_1418040
>   WORKAROUND_1463225
>   WORKAROUND_1508412
>   WORKAROUND_1542419
> +WORKAROUND_2064142
>   WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>   WORKAROUND_TSB_FLUSH_FAILURE
>   WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 276862c07e32..ec24b62b2cec 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -91,10 +91,12 @@ struct trbe_buf {
>    */
>   #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
>   #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
> +#define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE	2
>   
>   static int trbe_errata_cpucaps[] = {
>   	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>   	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
> +	[TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,

super minor nit: TRBE_NEEDS_DRAIN_AFTER_DISABLE ?

>   	-1,		/* Sentinel, must be the last entry */
>   };
>   
> @@ -167,6 +169,11 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
>   	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
>   }
>   
> +static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
> +{

minor nit: trbe_needs_drain_after_disable() ?

Either ways, the patch looks good to me.

Suzuki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH mptcp-next v7 1/4] Squash to "mptcp: implement fastclose xmit path"
From: Matthieu Baerts @ 2022-01-05 10:01 UTC (permalink / raw)
  To: Geliang Tang; +Cc: mptcp
In-Reply-To: <20220105085043.GA3255@dhcp-10-157-36-190>

Hi Geliang,

On 05/01/2022 09:50, Geliang Tang wrote:
> On Thu, Dec 30, 2021 at 08:16:48PM +0100, Matthieu Baerts wrote:
>> From: Geliang Tang <geliang.tang@suse.com>
>>
>> MP_FAIL could be sent with RST or DSS, and FASTCLOSE can be sent with
>> RST too. So we should use a similar xmit logic for FASTCLOSE and
>> MP_FAIL in both mptcp_write_options() and mptcp_established_options*().
>>
>> Cc: Paolo Abeni <pabeni@redhat.com>
>> Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
>> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
>> Signed-off-by: Geliang Tang <geliang.tang@suse.com>
>> ---
>>  net/mptcp/options.c | 66 ++++++++++++++++++++++++++++-----------------
>>  1 file changed, 41 insertions(+), 25 deletions(-)
>>
>> diff --git a/net/mptcp/options.c b/net/mptcp/options.c
>> index c6726e8389ec..9d2c1c9edbe6 100644
>> --- a/net/mptcp/options.c
>> +++ b/net/mptcp/options.c
>> @@ -829,8 +829,12 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
>>  
>>  	if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) {
>>  		if (mptcp_established_options_fastclose(sk, &opt_size, remaining, opts) ||
>> -		    mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts) ||
>> -		    mptcp_established_options_rst(sk, skb, &opt_size, remaining, opts)) {
>> +		    mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) {
>> +			*size += opt_size;
>> +			remaining -= opt_size;
>> +		}
>> +		/* MP_RST can be used with MP_FASTCLOSE and MP_FAIL if there is room */
>> +		if (mptcp_established_options_rst(sk, skb, &opt_size, remaining, opts)) {
>>  			*size += opt_size;
>>  			remaining -= opt_size;
>>  		}
>> @@ -1257,21 +1261,7 @@ static u16 mptcp_make_csum(const struct mptcp_ext *mpext)
>>  void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
>>  			 struct mptcp_out_options *opts)
>>  {
>> -	if (unlikely(OPTION_MPTCP_FAIL & opts->suboptions)) {
>> -		const struct sock *ssk = (const struct sock *)tp;
>> -		struct mptcp_subflow_context *subflow;
>> -
>> -		subflow = mptcp_subflow_ctx(ssk);
>> -		subflow->send_mp_fail = 0;
>> -
>> -		*ptr++ = mptcp_option(MPTCPOPT_MP_FAIL,
>> -				      TCPOLEN_MPTCP_FAIL,
>> -				      0, 0);
>> -		put_unaligned_be64(opts->fail_seq, ptr);
>> -		ptr += 2;
>> -	}
> 
> Hi Matt,
> 
> Sorry, this patch doesn't work on my test. We write both DSS + MP_FAIL,
> but MP_FAIL is lost on the received side. Only DSS is received.
> 
> If we write MP_FAIL + DSS like the orignal code, MP_FAIL and DSS will be
> received correctly.
> 
> I haven't figured out why yet.
> 
> Could we just keep this MP_FAIL writting code still at the beginning of
> the function just like the orignal code did?

Thank you for having tested and reviewed the series!

Is this issue here fixed by your patch you sent a couple of minutes ago
(mptcp: fix a DSS option writting error)

That would make sense as the only thing I did was to send the MP_FAIL
after the DSS option.

Do you mind if I send a v8 series with your new fix the missing 'ptr +=
2;' below and have the code moving the writing of the MP_FAIL option
later in a dedicated commit?

> 
>> -
>> -	/* DSS, MPC, MPJ, ADD_ADDR, FASTCLOSE and RST are mutually exclusive,
>> +	/* DSS, MPC, MPJ, ADD_ADDR, FASTCLOSE and FAIL are mutually exclusive,
>>  	 * see mptcp_established_options*()
>>  	 */
>>  	if (likely(OPTION_MPTCP_DSS & opts->suboptions)) {
>> @@ -1328,6 +1318,10 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
>>  						   TCPOPT_NOP << 8 | TCPOPT_NOP, ptr);
>>  			}
>>  		}
>> +
>> +		/* We might need to add MP_FAIL options in rare cases */
>> +		if (unlikely(OPTION_MPTCP_FAIL & opts->suboptions))
>> +			goto mp_fail;
>>  	} else if (OPTIONS_MPTCP_MPC & opts->suboptions) {
>>  		u8 len, flag = MPTCP_CAP_HMAC_SHA256;
>>  
>> @@ -1460,19 +1454,41 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
>>  				ptr += 1;
>>  			}
>>  		}
>> -	} else if (unlikely(OPTION_MPTCP_RST & opts->suboptions)) {
>> -		/* RST is mutually exclusive with everything else */
>> -		*ptr++ = mptcp_option(MPTCPOPT_RST,
>> -				      TCPOLEN_MPTCP_RST,
>> -				      opts->reset_transient,
>> -				      opts->reset_reason);
>> -		return;
>>  	} else if (unlikely(OPTION_MPTCP_FASTCLOSE & opts->suboptions)) {
>> -		/* FASTCLOSE is mutually exclusive with everything else */
>> +		/* FASTCLOSE is mutually exclusive with others except RST */
>>  		*ptr++ = mptcp_option(MPTCPOPT_MP_FASTCLOSE,
>>  				      TCPOLEN_MPTCP_FASTCLOSE,
>>  				      0, 0);
>>  		put_unaligned_be64(opts->rcvr_key, ptr);
> 
> Here, 'ptr += 2;' is needed.

Good catch!

Note related to my modification but to "mptcp: implement fastclose xmit
path" so it should be in this squash-to patch!

Cheers,
Matt
-- 
Tessares | Belgium | Hybrid Access Solutions
www.tessares.net

^ permalink raw reply

* [LTP] [PATCH 0/6] Expand Cgroup shell library
From: Luke Nowakowski-Krijger @ 2022-01-05 10:00 UTC (permalink / raw)
  To: ltp

This patchset aims to expand the cgroup_lib shell library to simplify
and centralize the whole mounting and cleanup process that, with all the
different versions and mounting schemes, can get confusing and rather
redundant.

So the aim here is to centralize all the functionality to the already
existing cgroup C API which handles a lot of the corner cases and
complexity while still getting to use it from a shell environment which
some developers probably prefer to write their tests in. This also
seems important to make it easier to reconfigure the current tests
to work under cgroup v2 controllers, as well as for developers to write
tests for cgroup v2 controllers for which there doesen't seem to be very
much coverage at the moment.

Luke Nowakowski-Krijger (6):
  API/cgroup: Modify tst_cgroup_print_config for easier parsing and
    consumption
  API/cgroup: Add cgroup_find_root helper function
  API/cgroup: Add option for specific pid to tst_cgroup_opts
  API/cgroup: Implement tst_cgroup_load_config()
  tools: Implement tst_cgctl binary utility
  controllers: Expand cgroup_lib shell library

 include/tst_cgroup.h                       |   7 +-
 lib/tst_cgroup.c                           | 165 ++++++++++++++++++++-
 testcases/kernel/controllers/cgroup_lib.sh | 129 ++++++++++++++--
 tools/cgroup/Makefile                      |   7 +
 tools/cgroup/tst_cgctl.c                   |  69 +++++++++
 5 files changed, 355 insertions(+), 22 deletions(-)
 create mode 100644 tools/cgroup/Makefile
 create mode 100644 tools/cgroup/tst_cgctl.c

-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply

* [LTP] [PATCH 6/6] controllers: Expand cgroup_lib shell library
From: Luke Nowakowski-Krijger @ 2022-01-05 10:00 UTC (permalink / raw)
  To: ltp
In-Reply-To: <cover.1641376050.git.luke.nowakowskikrijger@canonical.com>

Expand the cgroup_lib library by using the tools/cgroup/tst_cgctl binary
utility to make calls to the Cgroup C API to simplify and centralize the
mounting and cleanup process of Cgroups.

Signed-off-by: Luke Nowakowski-Krijger <luke.nowakowskikrijger@canonical.com>
---
 testcases/kernel/controllers/cgroup_lib.sh | 129 ++++++++++++++++++---
 1 file changed, 113 insertions(+), 16 deletions(-)

diff --git a/testcases/kernel/controllers/cgroup_lib.sh b/testcases/kernel/controllers/cgroup_lib.sh
index 7918b5636..6ab201b95 100644
--- a/testcases/kernel/controllers/cgroup_lib.sh
+++ b/testcases/kernel/controllers/cgroup_lib.sh
@@ -5,22 +5,7 @@
 
 . tst_test.sh
 
-# Find mountpoint to given subsystem
-# get_cgroup_mountpoint SUBSYSTEM
-# RETURN: 0 if mountpoint found, otherwise 1
-get_cgroup_mountpoint()
-{
-	local subsystem=$1
-	local mntpoint
-
-	[ $# -eq 0 ] && tst_brk TBROK "get_cgroup_mountpoint: subsystem not defined"
-
-	mntpoint=$(grep cgroup /proc/mounts | grep -w $subsystem | awk '{ print $2 }')
-	[ -z "$mntpoint" ] && return 1
-
-	echo $mntpoint
-	return 0
-}
+_cgroup_state=
 
 # Check if given subsystem is supported and enabled
 # is_cgroup_subsystem_available_and_enabled SUBSYSTEM
@@ -37,3 +22,115 @@ is_cgroup_subsystem_available_and_enabled()
 
 	return 1
 }
+
+# Find mountpoint of the given controller
+# USAGE: cgroup_get_mountpoint CONTROLLER
+# RETURNS: Prints the mountpoint of the given controller
+# Must call cgroup_require before calling
+cgroup_get_mountpoint()
+{
+	local ctrl=$1
+	local mountpoint
+
+	[ $# -eq 0 ] && tst_brk TBROK "cgroup_get_mountpoint: controller not defined"
+	[ "$_cgroup_state" = "" ] && tst_brk TBROK "cgroup_get_mountpoint: No previous state found. Forgot to call cgroup_require?"
+
+	mountpoint=$(echo "$_cgroup_state" | grep -w "$ctrl" | awk '{ print $4 }')
+	echo "$mountpoint"
+
+	return 0
+}
+
+# Get the test path of a given controller that has been created by the cgroup C API
+# USAGE: cgroup_get_test_path CONTROLLER
+# RETURNS: Prints the path to the test direcory
+# Must call cgroup_require before calling
+cgroup_get_test_path()
+{
+	local ctrl="$1"
+	local mountpoint
+	local test_path
+
+	[ $# -eq 0 ] && tst_brk TBROK "cgroup_get_test_path: controller not defined"
+	[ "$_cgroup_state" = "" ] && tst_brk TBROK "cgroup_get_test_path: No previous state found. Forgot to call cgroup_require?"
+
+	mountpoint=$(cgroup_get_mountpoint "$ctrl")
+
+	test_path="$mountpoint/ltp/test-$$"
+
+	[ ! -d "$test_path" ] && tst_brk TBROK "cgroup_get_test_path: No test path found. Forgot to call cgroup_require?"
+
+	echo "$test_path"
+
+	return 0
+}
+
+# Gets the cgroup version of the given controller
+# USAGE: cgroup_get_version CONTROLLER
+# RETURNS: "V1" if version 1 and "V2" if version 2
+# Must call cgroup_require before calling
+cgroup_get_version()
+{
+	local ctrl="$1"
+
+	[ $# -eq 0 ] && tst_brk TBROK "cgroup_get_version: controller not defined"
+	[ "$_cgroup_state" = "" ] && tst_brk TBROK "cgroup_get_version: No previous state found. Forgot to call cgroup_require?"
+
+	version=$(echo "$_cgroup_state" | grep -w "$ctrl" | awk '{ print $2 }')
+	[ "$version" = "" ] && tst_brk TBROK "cgroup_get_version: Could not find controller $ctrl"
+
+	echo "$version"
+
+	return 0
+}
+
+# Cleans up any setup done by calling cgroup_require.
+# USAGE: cgroup_cleanup
+# Can be safely called even when no setup has been done
+cgroup_cleanup()
+{
+	[ "$_cgroup_state" = "" ] && return 0
+
+	tst_cgctl cleanup "$_cgroup_state"
+
+	return 0
+}
+
+# Get the task list of the given controller
+# USAGE: cgroup_get_task_list CONTROLLER
+# RETURNS: prints out "cgroup.procs" if version 2 otherwise "tasks"
+# Must call cgroup_require before calling
+cgroup_get_task_list()
+{
+	local ctrl="$1"
+	local version
+
+	version=$(cgroup_get_version "$ctrl")
+
+	if [ "$version" = "V2" ]; then
+		echo "cgroup.procs"
+	else
+		echo "tasks"
+	fi
+
+	return 0
+}
+
+# Mounts and configures the given controller
+# USAGE: cgroup_require CONTROLLER
+cgroup_require()
+{
+	local ctrl="$1"
+
+	[ $# -eq 0 ] && tst_brk TBROK "cgroup_require: controller not defined"
+
+	if ! is_cgroup_subsystem_available_and_enabled "$ctrl"; then
+		tst_brk TBROK "cgroup_require: Controller not available or not enabled"
+	fi
+
+	_cgroup_state=$(tst_cgctl require "$ctrl" $$)
+
+	[ "$_cgroup_state" = "" ] && tst_brk TBROK "cgroup_require: No state was set after call. Controller '$ctrl' maybe does not exist?"
+
+	return 0
+}
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related

* [LTP] [PATCH 5/6] tools: Implement tst_cgctl binary utility
From: Luke Nowakowski-Krijger @ 2022-01-05 10:00 UTC (permalink / raw)
  To: ltp
In-Reply-To: <cover.1641376050.git.luke.nowakowskikrijger@canonical.com>

Implement a binary utility that creates an interface to make calls to
the cgroup C API.

This will effectively allow shell scripts to make calls to the cgroup C
api.

Signed-off-by: Luke Nowakowski-Krijger <luke.nowakowskikrijger@canonical.com>
---
 tools/cgroup/Makefile    |  7 ++++
 tools/cgroup/tst_cgctl.c | 69 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100644 tools/cgroup/Makefile
 create mode 100644 tools/cgroup/tst_cgctl.c

diff --git a/tools/cgroup/Makefile b/tools/cgroup/Makefile
new file mode 100644
index 000000000..81810bf4d
--- /dev/null
+++ b/tools/cgroup/Makefile
@@ -0,0 +1,7 @@
+top_srcdir		?= ../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+MAKE_TARGETS	:= tst_cgctl
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
\ No newline at end of file
diff --git a/tools/cgroup/tst_cgctl.c b/tools/cgroup/tst_cgctl.c
new file mode 100644
index 000000000..ef20e7485
--- /dev/null
+++ b/tools/cgroup/tst_cgctl.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include "tst_cgroup.h"
+
+static int cgctl_require(const char *ctrl, int test_pid)
+{
+    struct tst_cgroup_opts opts;
+
+    memset(&opts, 0, sizeof(opts));
+    opts.test_pid = test_pid;
+
+    tst_cgroup_require(ctrl, &opts);
+    tst_cgroup_print_config();
+
+    return 0;
+}
+
+static int cgctl_cleanup(const char *config)
+{
+    tst_cgroup_scan();
+    tst_cgroup_load_config(config);
+    tst_cgroup_cleanup();
+
+    return 0;
+}
+
+static int cgctl_print(void)
+{
+    tst_cgroup_scan();
+    tst_cgroup_print_config();
+
+    return 0;
+}
+
+static int cgctl_process_cmd(int argc, char *argv[])
+{
+    int test_pid;
+    const char *cmd_name = argv[1];
+
+    if (!strcmp(cmd_name, "require")) {
+        test_pid = atoi(argv[3]);
+        if (!test_pid) {
+            fprintf(stderr, "tst_cgctl: Invalid test_pid '%s' given\n",
+                    argv[3]);
+            return 1;
+        }
+        return cgctl_require(argv[2], test_pid);
+    } else if (!strcmp(cmd_name, "cleanup")) {
+        return cgctl_cleanup(argv[2]);
+    } else if (!strcmp(cmd_name, "print")) {
+        return cgctl_print();
+    }
+
+    fprintf(stderr, "tst_cgctl: Unknown command '%s' given\n", cmd_name);
+    return 1;
+}
+
+int main(int argc, char *argv[])
+{
+    if (argc < 2 || argc > 4) {
+        fprintf(stderr, "tst_cgctl: Invalid number of arguements given");
+        return 1;
+    }
+
+    return cgctl_process_cmd(argc, argv);
+}
\ No newline at end of file
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related

* Re: [PATCH 2/4] coresight: trbe: Work around the ignored system register writes
From: Suzuki K Poulose @ 2022-01-05 10:01 UTC (permalink / raw)
  To: Anshuman Khandual, linux-arm-kernel
  Cc: Catalin Marinas, Will Deacon, Mathieu Poirier, coresight,
	linux-doc, linux-kernel
In-Reply-To: <1641359159-22726-3-git-send-email-anshuman.khandual@arm.com>

Hi Anshuman

On 05/01/2022 05:05, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2064142 might fail to write
> into certain system registers after the TRBE has been disabled. Under some
> conditions after TRBE has been disabled, writes into certain TRBE registers
> TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
> ignored and not be effected.
> 
> Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
> just after the trace collection has stopped and before performing a system
> register write to one of the affected registers. This adds a new cpu errata
> in arm64 errata framework and also updates TRBE driver as required.
> 
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose@arm.com>
> Cc: coresight@lists.linaro.org
> Cc: linux-doc@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>   Documentation/arm64/silicon-errata.rst       |  2 +
>   arch/arm64/Kconfig                           | 18 +++++++
>   arch/arm64/kernel/cpu_errata.c               |  9 ++++
>   arch/arm64/tools/cpucaps                     |  1 +
>   drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
>   drivers/hwtracing/coresight/coresight-trbe.h |  8 ---
>   6 files changed, 68 insertions(+), 24 deletions(-)

I think it may be a good idea to split the patch into
two parts :

- arm64 kernel part. (cpucap defintions and detection)
- trbe driver part

So that it is easier to merge these series upstream to
avoid conflicts.

> 
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index 5342e895fb60..c9b30e6c2b6c 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -52,6 +52,8 @@ stable kernels.
>   | Allwinner      | A64/R18         | UNKNOWN1        | SUN50I_ERRATUM_UNKNOWN1     |
>   +----------------+-----------------+-----------------+-----------------------------+
>   +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
> ++----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index c4207cf9bb17..2105b68d88db 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -778,6 +778,24 @@ config ARM64_ERRATUM_2224489
>   
>   	  If unsure, say Y.
>   
> +config ARM64_ERRATUM_2064142
> +	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
> +	depends on CORESIGHT_TRBE
> +	default y
> +	help
> +	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
> +
> +	  Affected Cortex-A510 core might fail to write into system registers after the
> +	  TRBE has been disabled. Under some conditions after the TRBE has been disabled
> +	  writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1,
> +	  and TRBTRG_EL1 will be ignored and will not be effected.
> +
> +	  Work around this in the driver by executing TSB CSYNC and DSB after collection
> +	  is stopped and before performing a system register write to one of the affected
> +	  registers.
> +
> +	  If unsure, say Y.
> +
>   config CAVIUM_ERRATUM_22375
>   	bool "Cavium erratum 22375, 24313"
>   	default y
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 9e1c1aef9ebd..cbb7d5a9aee7 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -597,6 +597,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>   		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
>   		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
>   	},
> +#endif
> +#ifdef CONFIG_ARM64_ERRATUM_2064142
> +	{
> +		.desc = "ARM erratum 2064142",
> +		.capability = ARM64_WORKAROUND_2064142,
> +
> +		/* Cortex-A510 r0p0 - r0p2 */
> +		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
> +	},
>   #endif
>   	{
>   	}
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 870c39537dd0..fca3cb329e1d 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -55,6 +55,7 @@ WORKAROUND_1418040
>   WORKAROUND_1463225
>   WORKAROUND_1508412
>   WORKAROUND_1542419
> +WORKAROUND_2064142
>   WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>   WORKAROUND_TSB_FLUSH_FAILURE
>   WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 276862c07e32..ec24b62b2cec 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -91,10 +91,12 @@ struct trbe_buf {
>    */
>   #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
>   #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
> +#define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE	2
>   
>   static int trbe_errata_cpucaps[] = {
>   	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>   	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
> +	[TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,

super minor nit: TRBE_NEEDS_DRAIN_AFTER_DISABLE ?

>   	-1,		/* Sentinel, must be the last entry */
>   };
>   
> @@ -167,6 +169,11 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
>   	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
>   }
>   
> +static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
> +{

minor nit: trbe_needs_drain_after_disable() ?

Either ways, the patch looks good to me.

Suzuki

^ permalink raw reply

* [LTP] [PATCH 4/6] API/cgroup: Implement tst_cgroup_load_config()
From: Luke Nowakowski-Krijger @ 2022-01-05 10:00 UTC (permalink / raw)
  To: ltp
In-Reply-To: <cover.1641376050.git.luke.nowakowskikrijger@canonical.com>

Implement tst_cgroup_load_config which consumes the state given by
tst_cgroup_print_config() to update the internal test state to reflect
the given config.

This allows for programs using the cgroup C API to load and reload
state, allowing functionality such as calling tst_cgroup_require and
tst_cgroup_cleanup to function properly between programs or between
invocations of a binary using the C API.

Signed-off-by: Luke Nowakowski-Krijger <luke.nowakowskikrijger@canonical.com>
---
 include/tst_cgroup.h |   4 +-
 lib/tst_cgroup.c     | 108 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/include/tst_cgroup.h b/include/tst_cgroup.h
index cfcc189ee..9785bf7b9 100644
--- a/include/tst_cgroup.h
+++ b/include/tst_cgroup.h
@@ -112,7 +112,9 @@ struct tst_cgroup_group;
 void tst_cgroup_scan(void);
 /* Print the config detected by tst_cgroup_scan */
 void tst_cgroup_print_config(void);
-
+/* Load the config printed by tst_cgroup_print_config() to update the
+ * the internal state of the test to the given config */
+void tst_cgroup_load_config(const char *const config);
 /* Ensure the specified controller is available in the test's default
  * CGroup, mounting/enabling it if necessary */
 void tst_cgroup_require(const char *const ctrl_name,
diff --git a/lib/tst_cgroup.c b/lib/tst_cgroup.c
index 1cec3e722..9b3c639fc 100644
--- a/lib/tst_cgroup.c
+++ b/lib/tst_cgroup.c
@@ -378,6 +378,114 @@ static struct cgroup_root *cgroup_find_root(const char *const mnt_path)
 	return root;
 }
 
+static int parse_ctrl_config(const char *const config_entry)
+{
+	char *token;
+	struct cgroup_ctrl *ctrl = NULL;
+	int we_require_it = 0;
+
+	if (!strcmp(CONFIG_CTRL_HEADER, config_entry))
+		return 0;
+
+	if (!strcmp(CONFIG_ROOT_HEADER, config_entry))
+		return 1;
+
+	for (token = strtok(config_entry, " "); token; token = strtok(NULL, " ")) {
+		if (!ctrl && !(ctrl = cgroup_find_ctrl(token)))
+			tst_brk(TBROK, "Could not find ctrl from config. Ctrls changing between calls?");
+
+		if (ctrl && !strcmp(token, CONFIG_CTRL_REQUIRED))
+			ctrl->we_require_it = 1;
+	}
+
+	return 0;
+}
+
+static int parse_root_config(char *config_entry)
+{
+	char *key;
+	char *value;
+	struct cgroup_root *root;
+
+	for (key = strtok(config_entry, " "); key; key = strtok(NULL, " ")) {
+		if (!(value = strchr(key, '='))) {
+			if (!(root = cgroup_find_root(key)))
+				tst_brk(TBROK, "Could not find root from config. Roots changing between calls?");
+
+			continue;
+		}
+
+		*value = '\0';
+		value = value + 1;
+
+		if (!strcmp(key, CONFIG_MOUNTROOT_KEY) && !strcmp(value, "yes")) {
+			root->we_mounted_it = 1;
+
+		} else if (!strcmp(key, CONFIG_LTPDIR_KEY) && !root->ltp_dir.dir_name) {
+			cgroup_dir_mk(&root->mnt_dir, cgroup_ltp_dir, &root->ltp_dir);
+			if (!strcmp(value, "yes"))
+				root->ltp_dir.we_created_it = 1;
+
+		} else if (!strcmp(key, CONFIG_DRAINDIR_KEY) && !root->drain_dir.dir_name) {
+			cgroup_dir_mk(&root->ltp_dir, cgroup_ltp_drain_dir, &root->drain_dir);
+			if (!strcmp(value, "yes"))
+				root->ltp_dir.we_created_it = 1;
+
+		} else if (!strcmp(key, CONFIG_TESTID_KEY) && strcmp(value, "NULL") &&
+				   !root->test_dir.dir_name) {
+			cgroup_dir_mk(&root->ltp_dir, value, &root->test_dir);
+			root->test_dir.we_created_it = 1;
+		}
+	}
+
+	return 0;
+}
+
+/* Load the test state configuration provided by tst_cgroup_print_config()
+ *
+ * This will reload some internal tst_cgroup state given by the config
+ * that might otherwise have been lost between calls or between different
+ * processes. In particular this is used by tools/cgroup/tst_cgctl to
+ * provide access to this C api to shell scripts.
+ *
+ * The config keeps track of the minimal state needed for tst_cgroup_cleanup
+ * to cleanup after a test and does not keep track of the creation of
+ * test cgroups that might be created through tst_cgroup_group_mk().
+ */
+void tst_cgroup_load_config(const char *const config)
+{
+	char temp_config[BUFSIZ];
+	char *curr_line;
+	char *next_line;
+
+	if (strlen(config) >= BUFSIZ)
+		tst_brk(TBROK, "Config has exceeded buffer size?");
+
+	strncpy(temp_config, config, BUFSIZ);
+
+	for (curr_line = &temp_config[0]; curr_line; curr_line = next_line + 1) {
+		next_line = strchr(curr_line, '\n');
+		if (next_line)
+			*next_line = '\0';
+
+		if (parse_ctrl_config(curr_line))
+			break;
+	}
+
+	for (curr_line = next_line + 1; curr_line; curr_line = next_line + 1) {
+		next_line = strchr(curr_line, '\n');
+		if (next_line)
+			*next_line = '\0';
+
+		parse_root_config(curr_line);
+		/* Bash will truncate the last newline that we are using to deliminate
+		 * the start and end of valid entries, so if we could not detect any more
+		 * newlines we assume that was our last entry. */
+		if (!next_line)
+			break;
+	}
+}
+
 /* Determine if a mounted cgroup hierarchy is unique and record it if so.
  *
  * For CGroups V2 this is very simple as there is only one
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related

* [LTP] [PATCH 3/6] API/cgroup: Add option for specific pid to tst_cgroup_opts
From: Luke Nowakowski-Krijger @ 2022-01-05 10:00 UTC (permalink / raw)
  To: ltp
In-Reply-To: <cover.1641376050.git.luke.nowakowskikrijger@canonical.com>

Add an option that would allow to create a test directory with a
specified pid, as opposed to the calling processes pid.

Signed-off-by: Luke Nowakowski-Krijger <luke.nowakowskikrijger@canonical.com>
---
 include/tst_cgroup.h | 3 +++
 lib/tst_cgroup.c     | 6 +++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/include/tst_cgroup.h b/include/tst_cgroup.h
index 632050e86..cfcc189ee 100644
--- a/include/tst_cgroup.h
+++ b/include/tst_cgroup.h
@@ -98,6 +98,9 @@ struct tst_cgroup_opts {
 	 * only indicates that we should mount V1 controllers if
 	 * nothing is present. By default we try to mount V2 first. */
 	int only_mount_v1:1;
+	/* Pass in a specific pid to create and identify the test
+	 * directory as opposed to the default pid of the calling process. */
+	int test_pid;
 };
 
 /* A Control Group in LTP's aggregated hierarchy */
diff --git a/lib/tst_cgroup.c b/lib/tst_cgroup.c
index b06ae6ab7..1cec3e722 100644
--- a/lib/tst_cgroup.c
+++ b/lib/tst_cgroup.c
@@ -713,7 +713,11 @@ mkdirs:
 
 	cgroup_dir_mk(&root->ltp_dir, cgroup_ltp_drain_dir, &root->drain_dir);
 
-	sprintf(cgroup_test_dir, "test-%d", getpid());
+	if (options->test_pid)
+		sprintf(cgroup_test_dir, "test-%d", options->test_pid);
+	else
+		sprintf(cgroup_test_dir, "test-%d", getpid());
+
 	cgroup_dir_mk(&root->ltp_dir, cgroup_test_dir, &root->test_dir);
 }
 
-- 
2.32.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related


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.