提交 8d36d9e2 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Some lwIP locking that fixes multithreaded issues

上级 726fa62d
...@@ -14,8 +14,10 @@ ...@@ -14,8 +14,10 @@
#include "types.h" #include "types.h"
#include "kernel.h" #include "kernel.h"
#include "queue.h" #include "queue.h"
#ifndef LWIP
#include "spinlock.h" #include "spinlock.h"
#include "condvar.h" #include "condvar.h"
#endif
#include "proc.h" #include "proc.h"
#include "fs.h" #include "fs.h"
#include "file.h" #include "file.h"
...@@ -61,7 +63,10 @@ void ...@@ -61,7 +63,10 @@ void
netrx(void *va, u16 len) netrx(void *va, u16 len)
{ {
extern void if_input(struct netif *netif, void *buf, u16 len); extern void if_input(struct netif *netif, void *buf, u16 len);
lwip_core_lock();
if_input(&nif, va, len); if_input(&nif, va, len);
lwip_core_unlock();
} }
static void __attribute__((noreturn)) static void __attribute__((noreturn))
...@@ -72,7 +77,9 @@ net_timer(void *x) ...@@ -72,7 +77,9 @@ net_timer(void *x)
for (;;) { for (;;) {
u64 cur = nsectime(); u64 cur = nsectime();
lwip_core_lock();
t->func(); t->func();
lwip_core_unlock();
acquire(&t->waitlk); acquire(&t->waitlk);
cv_sleepto(&t->waitcv, &t->waitlk, cur + t->nsec); cv_sleepto(&t->waitcv, &t->waitlk, cur + t->nsec);
release(&t->waitlk); release(&t->waitlk);
...@@ -134,10 +141,15 @@ initnet_worker(void *x) ...@@ -134,10 +141,15 @@ initnet_worker(void *x)
static struct timer_thread t_arp, t_tcpf, t_tcps, t_dhcpf, t_dhcpc; static struct timer_thread t_arp, t_tcpf, t_tcps, t_dhcpf, t_dhcpc;
volatile long tcpip_done = 0; volatile long tcpip_done = 0;
lwip_core_init();
lwip_core_lock();
tcpip_init(&tcpip_init_done, (void*)&tcpip_done); tcpip_init(&tcpip_init_done, (void*)&tcpip_done);
lwip_core_unlock();
while (!tcpip_done) while (!tcpip_done)
yield(); yield();
lwip_core_lock();
memset(&nif, 0, sizeof(nif)); memset(&nif, 0, sizeof(nif));
lwip_init(&nif, NULL, 0, 0, 0); lwip_init(&nif, NULL, 0, 0, 0);
...@@ -181,10 +193,12 @@ initnet_worker(void *x) ...@@ -181,10 +193,12 @@ initnet_worker(void *x)
(ip & 0x000000ff)); (ip & 0x000000ff));
} }
} }
lwip_core_unlock();
acquire(&lk); acquire(&lk);
cv_sleepto(&cv, &lk, nsectime() + 1000000000); cv_sleepto(&cv, &lk, nsectime() + 1000000000);
release(&lk); release(&lk);
lwip_core_lock();
} }
} }
...@@ -206,7 +220,11 @@ initnet(void) ...@@ -206,7 +220,11 @@ initnet(void)
long long
netsocket(int domain, int type, int protocol) netsocket(int domain, int type, int protocol)
{ {
return lwip_socket(domain, type, protocol); int r;
lwip_core_lock();
r = lwip_socket(domain, type, protocol);
lwip_core_unlock();
return r;
} }
long long
...@@ -222,7 +240,9 @@ netbind(int sock, void *xaddr, int xaddrlen) ...@@ -222,7 +240,9 @@ netbind(int sock, void *xaddr, int xaddrlen)
if (umemcpy(addr, xaddr, xaddrlen)) if (umemcpy(addr, xaddr, xaddrlen))
return -1; return -1;
lwip_core_lock();
r = lwip_bind(sock, addr, xaddrlen); r = lwip_bind(sock, addr, xaddrlen);
lwip_core_unlock();
kmfree(addr); kmfree(addr);
return r; return r;
} }
...@@ -230,7 +250,12 @@ netbind(int sock, void *xaddr, int xaddrlen) ...@@ -230,7 +250,12 @@ netbind(int sock, void *xaddr, int xaddrlen)
long long
netlisten(int sock, int backlog) netlisten(int sock, int backlog)
{ {
return lwip_listen(sock, backlog); int r;
lwip_core_lock();
r = lwip_listen(sock, backlog);
lwip_core_unlock();
return r;
} }
long long
...@@ -248,14 +273,18 @@ netaccept(int sock, void *xaddr, void *xaddrlen) ...@@ -248,14 +273,18 @@ netaccept(int sock, void *xaddr, void *xaddrlen)
if (addr == NULL) if (addr == NULL)
return -1; return -1;
lwip_core_lock();
ss = lwip_accept(sock, addr, &len); ss = lwip_accept(sock, addr, &len);
lwip_core_unlock();
if (ss < 0) { if (ss < 0) {
kmfree(addr); kmfree(addr);
return ss; return ss;
} }
if (kmemcpy(xaddrlen, &len, sizeof(len)) || kmemcpy(xaddr, addr, len)) { if (kmemcpy(xaddrlen, &len, sizeof(len)) || kmemcpy(xaddr, addr, len)) {
lwip_core_lock();
lwip_close(ss); lwip_close(ss);
lwip_core_unlock();
kmfree(addr); kmfree(addr);
return -1; return -1;
} }
...@@ -266,7 +295,9 @@ netaccept(int sock, void *xaddr, void *xaddrlen) ...@@ -266,7 +295,9 @@ netaccept(int sock, void *xaddr, void *xaddrlen)
void void
netclose(int sock) netclose(int sock)
{ {
lwip_core_lock();
lwip_close(sock); lwip_close(sock);
lwip_core_unlock();
} }
int int
...@@ -285,7 +316,9 @@ netwrite(int sock, char *ubuf, int len) ...@@ -285,7 +316,9 @@ netwrite(int sock, char *ubuf, int len)
kfree(kbuf); kfree(kbuf);
return -1; return -1;
} }
lwip_core_lock();
r = lwip_write(sock, kbuf, cc); r = lwip_write(sock, kbuf, cc);
lwip_core_unlock();
kfree(kbuf); kfree(kbuf);
return r; return r;
} }
...@@ -302,7 +335,9 @@ netread(int sock, char *ubuf, int len) ...@@ -302,7 +335,9 @@ netread(int sock, char *ubuf, int len)
return -1; return -1;
cc = MIN(len, PGSIZE); cc = MIN(len, PGSIZE);
lwip_core_lock();
r = lwip_read(sock, kbuf, cc); r = lwip_read(sock, kbuf, cc);
lwip_core_unlock();
if (r < 0) { if (r < 0) {
kfree(kbuf); kfree(kbuf);
return r; return r;
......
...@@ -27,4 +27,8 @@ typedef struct sys_sem { ...@@ -27,4 +27,8 @@ typedef struct sys_sem {
#define SYS_ARCH_NOWAIT 0xfffffffe #define SYS_ARCH_NOWAIT 0xfffffffe
extern void lwip_core_unlock(void);
extern void lwip_core_lock(void);
extern void lwip_core_init(void);
#endif #endif
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define LWIP_DHCP 1 #define LWIP_DHCP 1
#define LWIP_COMPAT_SOCKETS 0 #define LWIP_COMPAT_SOCKETS 0
#define LWIP_COMPAT_MUTEX 1 #define LWIP_COMPAT_MUTEX 1
#define SYS_LIGHTWEIGHT_PROT 1 #define SYS_LIGHTWEIGHT_PROT 0
#define LWIP_PROVIDE_ERRNO 1 #define LWIP_PROVIDE_ERRNO 1
#define MEM_ALIGNMENT 4 #define MEM_ALIGNMENT 4
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#if 0 #if 0
#define ETHARP_DEBUG LWIP_DBG_ON #define ETHARP_DEBUG LWIP_DBG_ON
#define NETIF_DEBUG LWIP_DBG_ON #define NETIF_DEBUG LWIP_DBG_ON
#define IP_DEBUG LWIP_DBG_ON
#define DHCP_DEBUG LWIP_DBG_ON #define DHCP_DEBUG LWIP_DBG_ON
#define UDP_DEBUG LWIP_DBG_ON #define UDP_DEBUG LWIP_DBG_ON
#define IP_DEBUG LWIP_DBG_ON #define IP_DEBUG LWIP_DBG_ON
......
...@@ -66,8 +66,11 @@ void ...@@ -66,8 +66,11 @@ void
sys_mbox_post(sys_mbox_t *mbox, void *msg) sys_mbox_post(sys_mbox_t *mbox, void *msg)
{ {
acquire(&mbox->s); acquire(&mbox->s);
while (mbox->head - mbox->tail == MBOXSLOTS) while (mbox->head - mbox->tail == MBOXSLOTS) {
lwip_core_unlock();
cv_sleep(&mbox->c, &mbox->s); cv_sleep(&mbox->c, &mbox->s);
lwip_core_lock();
}
mbox->msg[mbox->head % MBOXSLOTS] = msg; mbox->msg[mbox->head % MBOXSLOTS] = msg;
mbox->head++; mbox->head++;
cv_wakeup(&mbox->c); cv_wakeup(&mbox->c);
...@@ -96,9 +99,13 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) ...@@ -96,9 +99,13 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
r = SYS_ARCH_TIMEOUT; r = SYS_ARCH_TIMEOUT;
goto done; goto done;
} }
lwip_core_unlock();
cv_sleepto(&mbox->c, &mbox->s, to); cv_sleepto(&mbox->c, &mbox->s, to);
lwip_core_lock();
} else { } else {
lwip_core_unlock();
cv_sleep(&mbox->c, &mbox->s); cv_sleep(&mbox->c, &mbox->s);
lwip_core_lock();
} }
} }
r = nsectime()-start; r = nsectime()-start;
...@@ -181,9 +188,13 @@ sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) ...@@ -181,9 +188,13 @@ sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
r = SYS_ARCH_TIMEOUT; r = SYS_ARCH_TIMEOUT;
goto done; goto done;
} }
lwip_core_unlock();
cv_sleepto(&sem->c, &sem->s, to); cv_sleepto(&sem->c, &sem->s, to);
lwip_core_lock();
} else { } else {
lwip_core_unlock();
cv_sleep(&sem->c, &sem->s); cv_sleep(&sem->c, &sem->s);
lwip_core_lock();
} }
} }
r = nsectime()-start; r = nsectime()-start;
...@@ -195,48 +206,37 @@ done: ...@@ -195,48 +206,37 @@ done:
} }
// //
// protect // thread
// //
sys_prot_t struct lwip_thread {
sys_arch_protect(void) lwip_thread_fn thread;
{ void *arg;
sys_prot_t r; };
pushcli();
if (lwprot.cpu == mycpu())
r = lwprot.depth++;
else {
acquire(&lwprot.lk);
r = lwprot.depth++;
lwprot.cpu = mycpu();
}
popcli();
return r; static void
} lwip_thread(void *x)
void
sys_arch_unprotect(sys_prot_t pval)
{ {
if (lwprot.cpu != mycpu() || lwprot.depth == 0) struct lwip_thread *lt = x;
panic("sys_arch_unprotect"); lwip_core_lock();
lwprot.depth--; lt->thread(lt->arg);
if (lwprot.depth == 0) { lwip_core_unlock();
lwprot.cpu = NULL; kmfree(lt);
release(&lwprot.lk);
}
} }
//
// thread
//
sys_thread_t sys_thread_t
sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, sys_thread_new(const char *name, lwip_thread_fn thread, void *arg,
int stacksize, int prio) int stacksize, int prio)
{ {
struct lwip_thread *lt;
struct proc *p; struct proc *p;
p = threadalloc(thread, arg); lt = kmalloc(sizeof(*lt));
if (lt == NULL)
return NULL;
lt->thread = thread;
lt->arg = arg;
p = threadalloc(lwip_thread, lt);
if (p == NULL) if (p == NULL)
panic("lwip: sys_thread_new"); panic("lwip: sys_thread_new");
safestrcpy(p->name, name, sizeof(p->name)); safestrcpy(p->name, name, sizeof(p->name));
...@@ -255,6 +255,25 @@ sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, ...@@ -255,6 +255,25 @@ sys_thread_new(const char *name, lwip_thread_fn thread, void *arg,
void void
sys_init(void) sys_init(void)
{ {
initlock(&lwprot.lk, "lwIP lwprot");
} }
//
// serialization
//
void
lwip_core_unlock(void)
{
release(&lwprot.lk);
}
void
lwip_core_lock(void)
{
acquire(&lwprot.lk);
}
void
lwip_core_init(void)
{
initlock(&lwprot.lk, "lwIP lwprot");
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论