ng_ksocket ACCEPT lock related problem.
takawata at jp.freebsd.org
takawata at jp.freebsd.org
Sat Jan 3 10:46:42 PST 2004
Hi, I noticed ng_ksocket can listen for stream type connection
and wrote a test program like this, and it works as I expected,
but it also produced LoR problem etc. Is this known problem?
===Message
malloc() of "16" with the following non-sleepable locks held:
exclusive sleep mutex inp (tcpinp) r = 0 (0xc458aa68) locked @ netinet/tcp_input.c:653
exclusive sleep mutex tcp r = 0 (0xc067186c) locked @ netinet/tcp_usrreq.c:480
lock order reversal
1st 0xc458a84c inp (tcpinp) @ netinet/tcp_input.c:653
2nd 0xc067186c tcp (tcp) @ netinet/tcp_usrreq.c:621
Stack backtrace:
backtrace(c0600143,c067186c,c0605c04,c0605c04,c06072d9) at backtrace+0x17
witness_lock(c067186c,8,c06072d9,26d,0) at witness_lock+0x672
_mtx_lock_flags(c067186c,0,c06072d0,26d,0) at _mtx_lock_flags+0xba
tcp_usr_rcvd(c47f8b40,80,c05fc199,14b,3b9aca00) at tcp_usr_rcvd+0x30
soreceive(c47f8b40,0,d75bd9e4,d75bd9dc,0) at soreceive+0x8ef
ng_ksocket_incoming2(c486ab00,0,c47f8b40,4,c475d458) at ng_ksocket_incoming2+0x2
4f
ng_apply_item(c486ab00,c475d440,c48811ee,7d6,d75bda98) at ng_apply_item+0x4bf
ng_snd_item(c475d440,0,c04ce15c,c47f8b8c,c47f8b40) at ng_snd_item+0x779
ng_send_fn(c486ab00,0,c488aad0,c47f8b40,4) at ng_send_fn+0x1b7
ng_ksocket_incoming(c47f8b40,c486ab00,4,34,11800) at ng_ksocket_incoming+0x2f
sowakeup(c47f8b40,c47f8b8c,c0606902,444,5000) at sowakeup+0xa1
tcp_input(c1934400,14,c064b620,c0671474,246) at tcp_input+0x1327
ip_input(c1934400,0,c0605432,95,c0670d38) at ip_input+0x8e3
netisr_processqueue(c0670d38,0,c0605432,fd,c1915680) at netisr_processqueue+0x8e
swi_net(0,0,c05faa43,23a,c191c54c) at swi_net+0xa3
ithread_loop(c4367380,d75bdd48,c05fa8b1,311,0) at ithread_loop+0x192
fork_exit(c048e580,c4367380,d75bdd48) at fork_exit+0xb4
fork_trampoline() at fork_trampoline+0x8
--- trap 0x1, eip = 0, esp = 0xd75bdd7c, ebp = 0 ---
==
=======Sample server
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netgraph.h>
#include <netgraph/ng_message.h>
#include <netgraph/ng_ksocket.h>
struct {
int cs, ds;
}allinfo;
void in_read_handler(struct kevent *kev)
{
int len;
char buf[8192];
len = read(0, buf, sizeof(buf));
NgSendData(allinfo.ds, "slave0", buf, len);
}
void c_read_handler(struct kevent *kev)
{
struct ng_mesg *rep;
struct ng_ksocket_accept *acp;
u_char buffer[sizeof(struct ng_mesg)+ sizeof(u_int32_t) + SOCK_MAXADDRLEN];
char path[NG_PATHSIZ];
struct ngm_connect conn;
rep = (struct ng_mesg *) buffer;
if(NgRecvMsg(allinfo.cs, rep, sizeof(buffer) , path) < 0 ){
perror("RecvMsg");
return ;
}
printf("Path:%s\n", path);
printf("GENERIC: %x %d %d %x %x %x %s \n",
rep->header.version, rep->header.arglen,
rep->header.flags, rep->header.token, rep->header.typecookie,
rep->header.cmd, rep->header.cmdstr);
if((rep->header.typecookie == NGM_KSOCKET_COOKIE)&&
(rep->header.cmd == NGM_KSOCKET_ACCEPT)){
acp = (struct ng_ksocket_accept *) rep->data;
printf("ACCEPT: nodeid %x\n", acp->nodeid);
strcpy(conn.path, path);
sprintf(conn.ourhook, "slave%d", 0);
sprintf(conn.peerhook, "inet/stream/tcp", 0);
if(NgSendMsg(allinfo.cs, ".:", NGM_GENERIC_COOKIE, NGM_CONNECT,
&conn, sizeof(conn)) < 0){
perror("SendMsg");
return;
}
}
}
char notfound_msg[]="HTTP/1.1 404 NOT Found\n\n<html><title>Not Found</title><body> Not Found</body></html>";
void d_read_handler(struct kevent *kev)
{
char hook[NG_HOOKSIZ];
char buf[8192];
int len;
len = NgRecvData(allinfo.ds, buf, sizeof(buf), hook);
printf("%d Data from %s\n", len, hook);
if(len == 0){
printf("HEHE\n");
if(NgSendMsg(allinfo.cs, ".:", NGM_GENERIC_COOKIE, NGM_RMHOOK, hook, sizeof(struct ngm_rmhook)) < 0){
perror("RMHOOK");
return ;
}
if((NgSendMsg(allinfo.cs, "master0",
NGM_KSOCKET_COOKIE, NGM_KSOCKET_ACCEPT,
NULL, 0)) < 0){
perror("ACCEPT");
}
}
}
void d_write_handler(struct kevent *kev)
{
}
#define MAXID 16
typedef void (*kevhandler)(struct kevent *);
int main(int argc, char * argv[])
{
int id[MAXID];
int kq, error;
struct addrinfo hints, *res, *res0;
int i,inqueue,numlisten = 1;
struct kevent ev[4];
kevhandler evh;
struct ngm_mkpeer ngmkpeer;
struct sockaddr sa;
if((kq = kqueue()) < 0){
perror("kqueue");
exit(-1);
}
if(NgMkSockNode("test", &allinfo.cs, &allinfo.ds) == -1){
perror("NgMkSockNode");
}
EV_SET(&ev[0], allinfo.cs, EVFILT_READ, EV_ADD, 0, 0, c_read_handler);
EV_SET(&ev[1], allinfo.ds, EVFILT_READ, EV_ADD, 0, 0, d_read_handler);
EV_SET(&ev[2], 0, EVFILT_READ, EV_ADD, 0, 0, in_read_handler);
kevent(kq, ev, 3, NULL, 0, NULL);
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;
if((error = getaddrinfo(NULL, "http", &hints, &res0))){
errx(1, "%s", gai_strerror(error));
}
for(res = res0,i = 0; res && i < MAXID ; res = res->ai_next, i++){
snprintf(ngmkpeer.type, sizeof(ngmkpeer.type), "%s", "ksocket");
snprintf(ngmkpeer.ourhook, sizeof(ngmkpeer.ourhook), "master%d", i);
snprintf(ngmkpeer.peerhook, sizeof(ngmkpeer.peerhook),
"%d/%d/%d", res->ai_family, res->ai_socktype, res->ai_protocol);
if((id[i] = NgSendMsg(allinfo.cs, ".:",
NGM_GENERIC_COOKIE, NGM_MKPEER,
&ngmkpeer, sizeof(ngmkpeer))) < 0){
perror("NgSendMsg");
continue;
}
if((NgSendMsg(allinfo.cs, ngmkpeer.ourhook,
NGM_KSOCKET_COOKIE, NGM_KSOCKET_BIND,
res->ai_addr,
res->ai_addrlen)) < 0){
perror("NgSendMsg");
exit(-1);
}
if((NgSendMsg(allinfo.cs, ngmkpeer.ourhook,
NGM_KSOCKET_COOKIE, NGM_KSOCKET_LISTEN,
&numlisten,
sizeof(numlisten))) < 0){
perror("NgSendMsg");
exit(-1);
}
}
for(i = 0 ; i < numlisten; i++){
if((NgSendMsg(allinfo.cs, ngmkpeer.ourhook,
NGM_KSOCKET_COOKIE, NGM_KSOCKET_ACCEPT,
NULL,
0)) < 0){
perror("NgSendMsg");
exit(-1);
}
}
while(1){
inqueue = kevent(kq, NULL, 0, ev, 4, NULL);
printf("Inqueue %d\n", inqueue);
for(i=0; i < inqueue; i++){
evh = ev[i].udata;
if(evh!=NULL){
printf("%x\n", evh);
(evh)(&ev[i]);
}
}
printf("\n");
}
}
======
More information about the freebsd-hackers
mailing list