[BACK]Return to uipc_socket.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/kern/uipc_socket.c between version 1.177.4.4 and 1.178

version 1.177.4.4, 2011/08/08 19:45:57 version 1.178, 2008/12/07 20:58:46
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*-  /*-
  * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.   * Copyright (c) 2002, 2007, 2008 The NetBSD Foundation, Inc.
  * All rights reserved.   * All rights reserved.
  *   *
  * This code is derived from software contributed to The NetBSD Foundation   * This code is derived from software contributed to The NetBSD Foundation
  * by Jason R. Thorpe of Wasabi Systems, Inc, and by Andrew Doran.   * by Jason R. Thorpe of Wasabi Systems, Inc.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions   * modification, are permitted provided that the following conditions
Line 91  __KERNEL_RCSID(0, "$NetBSD$");
Line 91  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/kauth.h>  #include <sys/kauth.h>
 #include <sys/mutex.h>  #include <sys/mutex.h>
 #include <sys/condvar.h>  #include <sys/condvar.h>
 #include <sys/kthread.h>  
   
 #include <uvm/uvm.h>  #include <uvm/uvm.h>
   
Line 137  int sock_loan_thresh = 4096;
Line 136  int sock_loan_thresh = 4096;
 #endif  #endif
   
 static kmutex_t so_pendfree_lock;  static kmutex_t so_pendfree_lock;
 static struct mbuf *so_pendfree = NULL;  static struct mbuf *so_pendfree;
   
 #ifndef SOMAXKVA  #ifndef SOMAXKVA
 #define SOMAXKVA (16 * 1024 * 1024)  #define SOMAXKVA (16 * 1024 * 1024)
Line 148  static kcondvar_t socurkva_cv;
Line 147  static kcondvar_t socurkva_cv;
   
 #define SOCK_LOAN_CHUNK         65536  #define SOCK_LOAN_CHUNK         65536
   
 static void sopendfree_thread(void *);  static size_t sodopendfree(void);
 static kcondvar_t pendfree_thread_cv;  static size_t sodopendfreel(void);
 static lwp_t *sopendfree_lwp;  
   static void sysctl_kern_somaxkva_setup(void);
   static struct sysctllog *socket_sysctllog;
   
 static vsize_t  static vsize_t
 sokvareserve(struct socket *so, vsize_t len)  sokvareserve(struct socket *so, vsize_t len)
Line 159  sokvareserve(struct socket *so, vsize_t 
Line 160  sokvareserve(struct socket *so, vsize_t 
   
         mutex_enter(&so_pendfree_lock);          mutex_enter(&so_pendfree_lock);
         while (socurkva + len > somaxkva) {          while (socurkva + len > somaxkva) {
                   size_t freed;
   
                   /*
                    * try to do pendfree.
                    */
   
                   freed = sodopendfreel();
   
                   /*
                    * if some kva was freed, try again.
                    */
   
                   if (freed)
                           continue;
   
                 SOSEND_COUNTER_INCR(&sosend_kvalimit);                  SOSEND_COUNTER_INCR(&sosend_kvalimit);
                 error = cv_wait_sig(&socurkva_cv, &so_pendfree_lock);                  error = cv_wait_sig(&socurkva_cv, &so_pendfree_lock);
                 if (error) {                  if (error) {
Line 251  sodoloanfree(struct vm_page **pgs, void 
Line 267  sodoloanfree(struct vm_page **pgs, void 
         sokvafree(sva, len);          sokvafree(sva, len);
 }  }
   
   static size_t
   sodopendfree(void)
   {
           size_t rv;
   
           if (__predict_true(so_pendfree == NULL))
                   return 0;
   
           mutex_enter(&so_pendfree_lock);
           rv = sodopendfreel();
           mutex_exit(&so_pendfree_lock);
   
           return rv;
   }
   
 /*  /*
  * sopendfree_thread: free mbufs on "pendfree" list.   * sodopendfreel: free mbufs on "pendfree" list.
  * unlock and relock so_pendfree_lock when freeing mbufs.   * unlock and relock so_pendfree_lock when freeing mbufs.
    *
    * => called with so_pendfree_lock held.
  */   */
   
 static void  static size_t
 sopendfree_thread(void *v)  sodopendfreel(void)
 {  {
         struct mbuf *m, *next;          struct mbuf *m, *next;
         size_t rv;          size_t rv = 0;
   
         mutex_enter(&so_pendfree_lock);          KASSERT(mutex_owned(&so_pendfree_lock));
   
         for (;;) {          while (so_pendfree != NULL) {
                 rv = 0;                  m = so_pendfree;
                 while (so_pendfree != NULL) {                  so_pendfree = NULL;
                         m = so_pendfree;                  mutex_exit(&so_pendfree_lock);
                         so_pendfree = NULL;  
                         mutex_exit(&so_pendfree_lock);  
   
                         for (; m != NULL; m = next) {  
                                 next = m->m_next;  
                                 KASSERT((~m->m_flags & (M_EXT|M_EXT_PAGES)) == 0);  
                                 KASSERT(m->m_ext.ext_refcnt == 0);  
   
                                 rv += m->m_ext.ext_size;  
                                 sodoloanfree(m->m_ext.ext_pgs, m->m_ext.ext_buf,  
                                     m->m_ext.ext_size);  
                                 pool_cache_put(mb_cache, m);  
                         }  
   
                         mutex_enter(&so_pendfree_lock);                  for (; m != NULL; m = next) {
                           next = m->m_next;
                           KASSERT((~m->m_flags & (M_EXT|M_EXT_PAGES)) == 0);
                           KASSERT(m->m_ext.ext_refcnt == 0);
   
                           rv += m->m_ext.ext_size;
                           sodoloanfree(m->m_ext.ext_pgs, m->m_ext.ext_buf,
                               m->m_ext.ext_size);
                           pool_cache_put(mb_cache, m);
                 }                  }
                 if (rv)  
                         cv_broadcast(&socurkva_cv);                  mutex_enter(&so_pendfree_lock);
                 cv_wait(&pendfree_thread_cv, &so_pendfree_lock);  
         }          }
         panic("sopendfree_thread");  
         /* NOTREACHED */          return (rv);
 }  }
   
 void  void
Line 308  soloanfree(struct mbuf *m, void *buf, si
Line 335  soloanfree(struct mbuf *m, void *buf, si
         mutex_enter(&so_pendfree_lock);          mutex_enter(&so_pendfree_lock);
         m->m_next = so_pendfree;          m->m_next = so_pendfree;
         so_pendfree = m;          so_pendfree = m;
         cv_signal(&pendfree_thread_cv);          cv_broadcast(&socurkva_cv);
         mutex_exit(&so_pendfree_lock);          mutex_exit(&so_pendfree_lock);
 }  }
   
Line 378  sokva_reclaim_callback(struct callback_e
Line 405  sokva_reclaim_callback(struct callback_e
         KASSERT(ce == &sokva_reclaimerentry);          KASSERT(ce == &sokva_reclaimerentry);
         KASSERT(obj == NULL);          KASSERT(obj == NULL);
   
           sodopendfree();
         if (!vm_map_starved_p(kernel_map)) {          if (!vm_map_starved_p(kernel_map)) {
                 return CALLBACK_CHAIN_ABORT;                  return CALLBACK_CHAIN_ABORT;
         }          }
Line 395  getsombuf(struct socket *so, int type)
Line 423  getsombuf(struct socket *so, int type)
 }  }
   
 void  void
 soinit()  soinit(void)
 {  {
   
           sysctl_kern_somaxkva_setup();
   
         mutex_init(&so_pendfree_lock, MUTEX_DEFAULT, IPL_VM);          mutex_init(&so_pendfree_lock, MUTEX_DEFAULT, IPL_VM);
         softnet_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);          softnet_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
         cv_init(&socurkva_cv, "sokva");          cv_init(&socurkva_cv, "sokva");
         cv_init(&pendfree_thread_cv, "sopendfr");  
         soinit2();          soinit2();
   
   
         /* Set the initial adjusted socket buffer size. */          /* Set the initial adjusted socket buffer size. */
         if (sb_max_set(sb_max))          if (sb_max_set(sb_max))
                 panic("bad initial sb_max value: %lu", sb_max);                  panic("bad initial sb_max value: %lu", sb_max);
Line 412  soinit()
Line 441  soinit()
             &sokva_reclaimerentry, NULL, sokva_reclaim_callback);              &sokva_reclaimerentry, NULL, sokva_reclaim_callback);
 }  }
   
 void  
 soinit1(void)  
 {  
         int error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,  
             sopendfree_thread, NULL, &sopendfree_lwp, "sopendfree");  
         if (error)  
                 panic("soinit1 %d", error);  
 }  
   
 /*  /*
  * Socket operation routines.   * Socket operation routines.
  * These routines are called by the routines in   * These routines are called by the routines in
Line 654  soclose(struct socket *so)
Line 674  soclose(struct socket *so)
                         if ((so->so_state & SS_ISDISCONNECTING) && so->so_nbio)                          if ((so->so_state & SS_ISDISCONNECTING) && so->so_nbio)
                                 goto drop;                                  goto drop;
                         while (so->so_state & SS_ISCONNECTED) {                          while (so->so_state & SS_ISCONNECTED) {
                                 error = sowait(so, true, so->so_linger * hz);                                  error = sowait(so, so->so_linger * hz);
                                 if (error)                                  if (error)
                                         break;                                          break;
                         }                          }
Line 772  sodisconnect(struct socket *so)
Line 792  sodisconnect(struct socket *so)
                 error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,                  error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
                     NULL, NULL, NULL, NULL);                      NULL, NULL, NULL, NULL);
         }          }
           sodopendfree();
         return (error);          return (error);
 }  }
   
Line 803  sosend(struct socket *so, struct mbuf *a
Line 824  sosend(struct socket *so, struct mbuf *a
         int             error, s, dontroute, atomic;          int             error, s, dontroute, atomic;
   
         p = l->l_proc;          p = l->l_proc;
           sodopendfree();
         clen = 0;          clen = 0;
   
         /*          /*
Line 1071  soreceive(struct socket *so, struct mbuf
Line 1093  soreceive(struct socket *so, struct mbuf
         else          else
                 flags = 0;                  flags = 0;
   
           if ((flags & MSG_DONTWAIT) == 0)
                   sodopendfree();
   
         if (flags & MSG_OOB) {          if (flags & MSG_OOB) {
                 m = m_get(M_WAIT, MT_DATA);                  m = m_get(M_WAIT, MT_DATA);
                 solock(so);                  solock(so);
Line 1516  soshutdown(struct socket *so, int how)
Line 1541  soshutdown(struct socket *so, int how)
         return error;          return error;
 }  }
   
 int  
 sodrain(struct socket *so)  
 {  
         int error;  
   
         solock(so);  
         so->so_state |= SS_ISDRAINING;  
         cv_broadcast(&so->so_cv);  
         error = soshutdown(so, SHUT_RDWR);  
         sounlock(so);  
   
         return error;  
 }  
   
 void  void
 sorflush(struct socket *so)  sorflush(struct socket *so)
 {  {
Line 2023  sohasoutofband(struct socket *so)
Line 2034  sohasoutofband(struct socket *so)
 {  {
   
         fownsignal(so->so_pgid, SIGURG, POLL_PRI, POLLPRI|POLLRDBAND, so);          fownsignal(so->so_pgid, SIGURG, POLL_PRI, POLLPRI|POLLRDBAND, so);
         selnotify(&so->so_rcv.sb_sel, POLLPRI | POLLRDBAND, NOTE_SUBMIT);          selnotify(&so->so_rcv.sb_sel, POLLPRI | POLLRDBAND, 0);
 }  }
   
 static void  static void
Line 2254  sysctl_kern_somaxkva(SYSCTLFN_ARGS)
Line 2265  sysctl_kern_somaxkva(SYSCTLFN_ARGS)
         return (error);          return (error);
 }  }
   
 SYSCTL_SETUP(sysctl_kern_somaxkva_setup, "sysctl kern.somaxkva setup")  static void
   sysctl_kern_somaxkva_setup()
 {  {
   
         sysctl_createv(clog, 0, NULL, NULL,          KASSERT(socket_sysctllog == NULL);
           sysctl_createv(&socket_sysctllog, 0, NULL, NULL,
                        CTLFLAG_PERMANENT,                         CTLFLAG_PERMANENT,
                        CTLTYPE_NODE, "kern", NULL,                         CTLTYPE_NODE, "kern", NULL,
                        NULL, 0, NULL, 0,                         NULL, 0, NULL, 0,
                        CTL_KERN, CTL_EOL);                         CTL_KERN, CTL_EOL);
   
         sysctl_createv(clog, 0, NULL, NULL,          sysctl_createv(&socket_sysctllog, 0, NULL, NULL,
                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,                         CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                        CTLTYPE_INT, "somaxkva",                         CTLTYPE_INT, "somaxkva",
                        SYSCTL_DESCR("Maximum amount of kernel memory to be "                         SYSCTL_DESCR("Maximum amount of kernel memory to be "

Legend:
Removed from v.1.177.4.4  
changed lines
  Added in v.1.178

CVSweb <webmaster@jp.NetBSD.org>