File:  [DragonFly] / src / sys / net / netisr.c
Revision 1.8: download - view: text, annotated - select for diffs
Sat Mar 6 01:58:54 2004 UTC (10 years, 1 month ago) by hsu
Branches: MAIN
CVS tags: HEAD
Dispatch upper-half protocol request handling.

    1: /*-
    2:  * Copyright (c) 2003 Jeffrey Hsu
    3:  * Copyright (c) 2003 Jonathan Lemon
    4:  * Copyright (c) 2003 Matthew Dillon
    5:  *
    6:  * $DragonFly: src/sys/net/netisr.c,v 1.8 2004/03/06 01:58:54 hsu Exp $
    7:  */
    8: 
    9: #include <sys/param.h>
   10: #include <sys/systm.h>
   11: #include <sys/kernel.h>
   12: #include <sys/malloc.h>
   13: #include <sys/msgport.h>
   14: #include <sys/msgport2.h>
   15: #include <sys/proc.h>
   16: #include <sys/interrupt.h>
   17: #include <sys/socket.h>
   18: #include <sys/sysctl.h>
   19: #include <net/if.h>
   20: #include <net/if_var.h>
   21: #include <net/netisr.h>
   22: #include <machine/cpufunc.h>
   23: #include <machine/ipl.h>
   24: 
   25: static struct netisr netisrs[NETISR_MAX];
   26: 
   27: /* Per-CPU thread to handle any protocol.  */
   28: struct thread netisr_cpu[MAXCPU];
   29: 
   30: static void
   31: netisr_init(void)
   32: {
   33:     int i;
   34: 
   35:     /* Create default per-cpu threads for generic protocol handling. */
   36:     for (i = 0; i < ncpus; ++i)
   37: 	lwkt_create(netmsg_service_loop, NULL, NULL, &netisr_cpu[i], 0, i,
   38: 	    "netisr_cpu %d", i);
   39: }
   40: 
   41: SYSINIT(netisr, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, netisr_init, NULL);
   42: 
   43: void
   44: netmsg_service_loop(void *arg)
   45: {
   46:     struct netmsg *msg;
   47: 
   48:     while ((msg = lwkt_waitport(&curthread->td_msgport, NULL))) {
   49: 	msg->nm_handler(msg);
   50: 	if (msg->nm_lmsg.ms_flags & MSGF_ASYNC)
   51: 	    free(msg, M_LWKTMSG);
   52:     }
   53: }
   54: 
   55: /*
   56:  * Call the netisr directly.
   57:  * Queueing may be done in the msg port layer at its discretion.
   58:  */
   59: void
   60: netisr_dispatch(int num, struct mbuf *m)
   61: {
   62:     /* just queue it for now XXX JH */
   63:     netisr_queue(num, m);
   64: }
   65: 
   66: /*
   67:  * Same as netisr_dispatch(), but always queue.
   68:  * This is either used in places where we are not confident that
   69:  * direct dispatch is possible, or where queueing is required.
   70:  */
   71: int
   72: netisr_queue(int num, struct mbuf *m)
   73: {
   74:     struct netisr *ni;
   75:     struct netmsg_packet *pmsg;
   76:     lwkt_port_t port;
   77: 
   78:     KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
   79: 	("netisr_queue: bad isr %d", num));
   80: 
   81:     ni = &netisrs[num];
   82:     if (ni->ni_handler == NULL) {
   83: 	printf("netisr_queue: unregistered isr %d\n", num);
   84: 	return (EIO);
   85:     }
   86: 
   87:     if (!(port = ni->ni_mport(m)))
   88: 	return (EIO);
   89: 
   90:     /* use better message allocation system with limits later XXX JH */
   91:     if (!(pmsg = malloc(sizeof(struct netmsg_packet), M_LWKTMSG, M_NOWAIT)))
   92: 	return (ENOBUFS);
   93: 
   94:     lwkt_initmsg(&pmsg->nm_lmsg, port, CMD_NETMSG_NEWPKT);
   95:     pmsg->nm_packet = m;
   96:     pmsg->nm_handler = ni->ni_handler;
   97:     lwkt_sendmsg(port, &pmsg->nm_lmsg);
   98:     return (0);
   99: }
  100: 
  101: void
  102: netisr_register(int num, lwkt_portfn_t mportfn, netisr_fn_t handler)
  103: {
  104:     KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
  105: 	("netisr_register: bad isr %d", num));
  106: 
  107:     netisrs[num].ni_mport = mportfn;
  108:     netisrs[num].ni_handler = handler;
  109: }
  110: 
  111: int
  112: netisr_unregister(int num)
  113: {
  114:     KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
  115: 	("unregister_netisr: bad isr number: %d\n", num));
  116: 
  117:     /* XXX JH */
  118:     return (0);
  119: }
  120: 
  121: /*
  122:  * Return message port for default handler thread on CPU 0.
  123:  */
  124: lwkt_port_t
  125: cpu0_portfn(struct mbuf *m)
  126: {
  127:     return (&netisr_cpu[0].td_msgport);
  128: }
  129: 
  130: /* ARGSUSED */
  131: lwkt_port_t
  132: cpu0_soport(struct socket *so __unused, struct sockaddr *nam __unused)
  133: {
  134:     return (&netisr_cpu[0].td_msgport);
  135: }
  136: 
  137: /*
  138:  * This function is used to call the netisr handler from the appropriate
  139:  * netisr thread for polling and other purposes.
  140:  */
  141: void
  142: schednetisr(int num)
  143: {
  144:     struct netisr *ni = &netisrs[num];
  145:     struct netmsg *pmsg;
  146:     lwkt_port_t port = &netisr_cpu[0].td_msgport;
  147: 
  148:     KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
  149: 	("schednetisr: bad isr %d", num));
  150: 
  151:     if (!(pmsg = malloc(sizeof(struct netmsg), M_LWKTMSG, M_NOWAIT)))
  152: 	return;
  153: 
  154:     lwkt_initmsg(&pmsg->nm_lmsg, port, CMD_NETMSG_POLL);
  155:     pmsg->nm_handler = ni->ni_handler;
  156:     lwkt_sendmsg(port, &pmsg->nm_lmsg);
  157: }