[PATCH rtems-lwip 2/2] rtemslwip: Move ZynqMP servicing thread to core 0

Kinsey Moore kinsey.moore at oarcorp.com
Mon Jan 22 19:47:28 UTC 2024


There have been some SMP compatibility issues seen on ZynqMP systems,
even with the recent patch to manage the active pbuf pool. It was
confirmed with Xilinx that this driver was never intended to run with
multiple cores available even though lwIP has multi-core support and
there doesn't appear to be any mention of this limitation in public
documentation. This moves the ZynqMP hardware servicing thread to core 0
where the ISR server runs interrupt handlers.
---
 rtemslwip/common/sys_arch.c          | 40 ++++++++++++++++++++++++++++
 rtemslwip/include/arch/sys_arch.h    | 16 +++++++++++
 rtemslwip/zynqmp_cfc400x/netstart.c  | 10 +++++--
 rtemslwip/zynqmp_hardware/netstart.c | 10 +++++--
 rtemslwip/zynqmp_qemu/netstart.c     | 10 +++++--
 5 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/rtemslwip/common/sys_arch.c b/rtemslwip/common/sys_arch.c
index cfb25fd..365d030 100644
--- a/rtemslwip/common/sys_arch.c
+++ b/rtemslwip/common/sys_arch.c
@@ -296,6 +296,46 @@ sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stack_s
   return id;
 }
 
+sys_thread_t sys_thread_new_affinity(
+  const char *name,
+  lwip_thread_fn function,
+  void *arg,
+  int stack_size,
+  int prio,
+  cpu_set_t *set
+)
+{
+  rtems_id id;
+  rtems_status_code res;
+
+  res = rtems_task_create(
+    rtems_build_name(name[0], name[1], name[2], name[3]),
+    prio,
+    stack_size,
+    RTEMS_PREEMPT,
+    0,
+    &id
+    );
+
+  if (res != RTEMS_SUCCESSFUL) {
+    return 0;
+  }
+
+  res = rtems_task_set_affinity( id, sizeof( cpu_set_t ), set );
+
+  if (res != RTEMS_SUCCESSFUL) {
+    return 0;
+  }
+
+  res = rtems_task_start(id, (rtems_task_entry)function, (rtems_task_argument)arg);
+
+  if (res != RTEMS_SUCCESSFUL) {
+    rtems_task_delete(id);
+    return 0;
+  }
+  return id;
+}
+
 err_t
 sys_mutex_new(sys_mutex_t *mutex)
 {
diff --git a/rtemslwip/include/arch/sys_arch.h b/rtemslwip/include/arch/sys_arch.h
index 5fbdc73..c63d28b 100644
--- a/rtemslwip/include/arch/sys_arch.h
+++ b/rtemslwip/include/arch/sys_arch.h
@@ -117,4 +117,20 @@ sys_arch_data_sync_barier(void)
 #endif
 }
 
+/*
+ * This must match the definition in lwIP's lwip/sys.h
+ * It can't be included from there since this file is included there before the
+ * typedef.
+ */
+typedef void (*lwip_thread_fn)(void *arg);
+
+/* This is a thread creator that can be passed CPU affinity */
+sys_thread_t sys_thread_new_affinity(
+  const char *name,
+  lwip_thread_fn function,
+  void *arg,
+  int stack_size,
+  int prio,
+  cpu_set_t *set
+);
 #endif /* __ARCH_SYS_ARCH_H__ */
diff --git a/rtemslwip/zynqmp_cfc400x/netstart.c b/rtemslwip/zynqmp_cfc400x/netstart.c
index 237133d..e9e804f 100644
--- a/rtemslwip/zynqmp_cfc400x/netstart.c
+++ b/rtemslwip/zynqmp_cfc400x/netstart.c
@@ -37,6 +37,7 @@ int start_networking(
   unsigned char *mac_ethernet_address
 )
 {
+  cpu_set_t set;
   start_networking_shared();
 
   if ( !xemac_add(
@@ -54,12 +55,17 @@ int start_networking(
 
   netif_set_up( net_interface );
 
-  sys_thread_new(
+  CPU_ZERO( &set );
+  /* Move task to CPU 0 */
+  CPU_SET( 0, &set );
+
+  sys_thread_new_affinity(
     "xemacif_input_thread",
     ( void ( * )( void * ) )xemacif_input_thread,
     net_interface,
     1024,
-    DEFAULT_THREAD_PRIO
+    DEFAULT_THREAD_PRIO,
+    &set
   );
 
   return 0;
diff --git a/rtemslwip/zynqmp_hardware/netstart.c b/rtemslwip/zynqmp_hardware/netstart.c
index 5d97ab2..1b3867f 100644
--- a/rtemslwip/zynqmp_hardware/netstart.c
+++ b/rtemslwip/zynqmp_hardware/netstart.c
@@ -37,6 +37,7 @@ int start_networking(
   unsigned char *mac_ethernet_address
 )
 {
+  cpu_set_t set;
   start_networking_shared();
 
   if ( !xemac_add(
@@ -54,12 +55,17 @@ int start_networking(
 
   netif_set_up( net_interface );
 
-  sys_thread_new(
+  CPU_ZERO( &set );
+  /* Move task to CPU 0 */
+  CPU_SET( 0, &set );
+
+  sys_thread_new_affinity(
     "xemacif_input_thread",
     ( void ( * )( void * ) )xemacif_input_thread,
     net_interface,
     1024,
-    DEFAULT_THREAD_PRIO
+    DEFAULT_THREAD_PRIO,
+    &set
   );
 
   return 0;
diff --git a/rtemslwip/zynqmp_qemu/netstart.c b/rtemslwip/zynqmp_qemu/netstart.c
index 237133d..e9e804f 100644
--- a/rtemslwip/zynqmp_qemu/netstart.c
+++ b/rtemslwip/zynqmp_qemu/netstart.c
@@ -37,6 +37,7 @@ int start_networking(
   unsigned char *mac_ethernet_address
 )
 {
+  cpu_set_t set;
   start_networking_shared();
 
   if ( !xemac_add(
@@ -54,12 +55,17 @@ int start_networking(
 
   netif_set_up( net_interface );
 
-  sys_thread_new(
+  CPU_ZERO( &set );
+  /* Move task to CPU 0 */
+  CPU_SET( 0, &set );
+
+  sys_thread_new_affinity(
     "xemacif_input_thread",
     ( void ( * )( void * ) )xemacif_input_thread,
     net_interface,
     1024,
-    DEFAULT_THREAD_PRIO
+    DEFAULT_THREAD_PRIO,
+    &set
   );
 
   return 0;
-- 
2.39.2



More information about the devel mailing list