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

Some lwIP locking that fixes multithreaded issues

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