git: f2978460c7fd - main - LinuxKPI: tasklet add (*callback) support

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Tue, 08 Nov 2022 18:18:17 UTC
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=f2978460c7fd5d90837843cbe8edf86a2df4a922

commit f2978460c7fd5d90837843cbe8edf86a2df4a922
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-10-30 17:20:11 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2022-11-08 18:14:17 +0000

    LinuxKPI: tasklet add (*callback) support
    
    In addition to (*func) tasklet also seems to have a (*callback) with
    a different argument.  Add support for this and add tasklet_setup()
    as well for support in more drivers.
    
    The from_tasklet() definition is duplicated in the tree; hide it there
    under #ifndef to avoid a re-definition.  People should generally add
    LinuxKPI bits to linuxkpi rather than private files if they also rely
    on other LinuxKPI bits.
    
    X-MFC:          DO NOT MFC, space allocated by drivers not us.
    Reviewed by:    emaste
    Differential Revision: https://reviews.freebsd.org/D37216
---
 sys/compat/linuxkpi/common/include/linux/interrupt.h |  9 +++++++++
 sys/compat/linuxkpi/common/src/linux_tasklet.c       | 20 +++++++++++++++++++-
 sys/dev/irdma/fbsd_kcompat.h                         |  2 ++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/interrupt.h b/sys/compat/linuxkpi/common/include/linux/interrupt.h
index d44b813ada8d..4c914a7b45a1 100644
--- a/sys/compat/linuxkpi/common/include/linux/interrupt.h
+++ b/sys/compat/linuxkpi/common/include/linux/interrupt.h
@@ -134,7 +134,9 @@ irq_set_affinity_hint(int vector, cpumask_t *mask)
 /*
  * LinuxKPI tasklet support
  */
+struct tasklet_struct;
 typedef void tasklet_func_t(unsigned long);
+typedef void tasklet_callback_t(struct tasklet_struct *);
 
 struct tasklet_struct {
 	TAILQ_ENTRY(tasklet_struct) entry;
@@ -143,6 +145,8 @@ struct tasklet_struct {
 	volatile u_int tasklet_state;
 	atomic_t count;
 	unsigned long data;
+	tasklet_callback_t *callback;
+	bool use_callback;
 };
 
 #define	DECLARE_TASKLET(_name, _func, _data)	\
@@ -150,6 +154,11 @@ struct tasklet_struct _name = { .func = (_func), .data = (_data) }
 
 #define	tasklet_hi_schedule(t)	tasklet_schedule(t)
 
+/* Some other compat code in the tree has this defined as well. */
+#define	from_tasklet(_dev, _t, _field)		\
+    container_of(_t, typeof(*(_dev)), _field)
+
+void tasklet_setup(struct tasklet_struct *, tasklet_callback_t *);
 extern void tasklet_schedule(struct tasklet_struct *);
 extern void tasklet_kill(struct tasklet_struct *);
 extern void tasklet_init(struct tasklet_struct *, tasklet_func_t *,
diff --git a/sys/compat/linuxkpi/common/src/linux_tasklet.c b/sys/compat/linuxkpi/common/src/linux_tasklet.c
index 26e7bb75cf19..d6e20a63c579 100644
--- a/sys/compat/linuxkpi/common/src/linux_tasklet.c
+++ b/sys/compat/linuxkpi/common/src/linux_tasklet.c
@@ -85,7 +85,10 @@ tasklet_handler(void *arg)
 				/* reset executing state */
 				TASKLET_ST_SET(ts, TASKLET_ST_EXEC);
 
-				ts->func(ts->data);
+				if (ts->use_callback)
+					ts->callback(ts);
+				else
+					ts->func(ts->data);
 
 			} while (TASKLET_ST_CMPSET(ts, TASKLET_ST_EXEC,
 			        TASKLET_ST_IDLE) == 0);
@@ -149,9 +152,24 @@ tasklet_init(struct tasklet_struct *ts,
 	ts->entry.tqe_prev = NULL;
 	ts->entry.tqe_next = NULL;
 	ts->func = func;
+	ts->callback = NULL;
 	ts->data = data;
 	atomic_set_int(&ts->tasklet_state, TASKLET_ST_IDLE);
 	atomic_set(&ts->count, 0);
+	ts->use_callback = false;
+}
+
+void
+tasklet_setup(struct tasklet_struct *ts, tasklet_callback_t *c)
+{
+	ts->entry.tqe_prev = NULL;
+	ts->entry.tqe_next = NULL;
+	ts->func = NULL;
+	ts->callback = c;
+	ts->data = 0;
+	atomic_set_int(&ts->tasklet_state, TASKLET_ST_IDLE);
+	atomic_set(&ts->count, 0);
+	ts->use_callback = true;
 }
 
 void
diff --git a/sys/dev/irdma/fbsd_kcompat.h b/sys/dev/irdma/fbsd_kcompat.h
index 179229d6be03..a6e3941440f8 100644
--- a/sys/dev/irdma/fbsd_kcompat.h
+++ b/sys/dev/irdma/fbsd_kcompat.h
@@ -44,8 +44,10 @@
 	tasklet_init((tasklet), (TASKLET_FUNC_TYPE)(callback),		\
 		      (TASKLET_DATA_TYPE)(tasklet))
 
+#ifndef from_tasklet
 #define from_tasklet(var, callback_tasklet, tasklet_fieldname) \
 	container_of(callback_tasklet, typeof(*var), tasklet_fieldname)
+#endif
 
 #define IRDMA_SET_RDMA_OBJ_SIZE(ib_struct, drv_struct, member)    \
 	(sizeof(struct drv_struct) +                              \