Jelajahi Sumber

🐞 fix(lwip/port/sys_arch): fix spinlock`s deadlock (#8208)

xqyjlj 1 tahun lalu
induk
melakukan
f806d6edd1
1 mengubah file dengan 22 tambahan dan 4 penghapusan
  1. 22 4
      components/net/lwip/port/sys_arch.c

+ 22 - 4
components/net/lwip/port/sys_arch.c

@@ -15,6 +15,7 @@
  * 2021-06-25     liuxianliang port to v2.0.3
  * 2022-01-18     Meco Man     remove v2.0.2
  * 2022-02-20     Meco Man     integrate v1.4.1 v2.0.3 and v2.1.2 porting layer
+ * 2023-10-31     xqyjlj       fix spinlock`s deadlock
  */
 
 #include <rtthread.h>
@@ -36,6 +37,12 @@
 #include <netif/ethernetif.h>
 #include <netif/etharp.h>
 
+#ifdef RT_USING_SMP
+static struct rt_mutex _mutex = {0};
+#else
+static RT_DEFINE_SPINLOCK(_spinlock);
+#endif
+
 /*
  * Initialize the ethernetif layer and set network interface device up
  */
@@ -58,6 +65,9 @@ int lwip_system_init(void)
         rt_kprintf("lwip system already init.\n");
         return 0;
     }
+#ifdef RT_USING_SMP
+    rt_mutex_init(&_mutex, "sys_arch", RT_IPC_FLAG_FIFO);
+#endif
 
     extern int eth_system_device_init_private(void);
     eth_system_device_init_private();
@@ -511,18 +521,26 @@ sys_thread_t sys_thread_new(const char    *name,
     return t;
 }
 
-static RT_DEFINE_SPINLOCK(_spinlock);
-
 sys_prot_t sys_arch_protect(void)
 {
+#ifdef RT_USING_SMP
+    rt_mutex_take(&_mutex, RT_WAITING_FOREVER);
+    return 0;
+#else
     rt_base_t level;
-    level = rt_spin_lock_irqsave(&_spinlock); /* disable interrupt */
+    level = rt_spin_lock_irqsave(&_spinlock);
     return level;
+#endif
 }
 
 void sys_arch_unprotect(sys_prot_t pval)
 {
-    rt_spin_unlock_irqrestore(&_spinlock, pval); /* enable interrupt */
+#ifdef RT_USING_SMP
+    RT_UNUSED(pval);
+    rt_mutex_release(&_mutex);
+#else
+    rt_spin_unlock_irqrestore(&_spinlock, pval);
+#endif
 }
 
 void sys_arch_assert(const char *file, int line)