diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 1999-05-27 18:03:50 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 1999-05-27 18:03:50 +0000 |
commit | 11cdbebd585380dfd5b030612158b083cee50ad4 (patch) | |
tree | 253d3364167c767795bd846f99be919dec373dc2 /c/src/exec/libnetworking/rtems | |
parent | Split out the routine rtems_assoc_name_bad(). (diff) | |
download | rtems-11cdbebd585380dfd5b030612158b083cee50ad4.tar.bz2 |
Patch from Eric Norum <eric@pollux.usask.ca> to eliminate a panic when the
network stack runs out of mbufs.
Diffstat (limited to 'c/src/exec/libnetworking/rtems')
-rw-r--r-- | c/src/exec/libnetworking/rtems/rtems_glue.c | 127 |
1 files changed, 85 insertions, 42 deletions
diff --git a/c/src/exec/libnetworking/rtems/rtems_glue.c b/c/src/exec/libnetworking/rtems/rtems_glue.c index d8ec0a1ec4..8ef1626906 100644 --- a/c/src/exec/libnetworking/rtems/rtems_glue.c +++ b/c/src/exec/libnetworking/rtems/rtems_glue.c @@ -126,25 +126,47 @@ rtems_bsdnet_free (void *addr, int type) /* * Do the initializations required by the BSD code - * FIXME: Maybe we should use a different memory allocation scheme that - * would let us share space between mbufs and mbuf clusters. - * For now, we'll just take the easy way out! */ static void bsd_init () { + int i; + char *p; + /* - * Set up mbuf data strutures - * Cluster allocation *must* come first -- see comment on kmem_malloc(). + * Set up mbuf cluster data strutures */ - m_clalloc (nmbclusters, M_DONTWAIT); + p = malloc ((nmbclusters*MCLBYTES)+MCLBYTES-1); + p = (char *)(((unsigned long)p + (MCLBYTES-1)) & ~(MCLBYTES-1)); + if (p == NULL) + rtems_panic ("Can't get network cluster memory."); + mbutl = (struct mbuf *)p; + for (i = 0; i < nmbclusters; i++) { + ((union mcluster *)p)->mcl_next = mclfree; + mclfree = (union mcluster *)p; + p += MCLBYTES; + mbstat.m_clfree++; + } + mbstat.m_clusters = nmbclusters; mclrefcnt = malloc (nmbclusters); if (mclrefcnt == NULL) - rtems_panic ("No memory for mbuf cluster reference counts."); + rtems_panic ("Can't get mbuf cluster reference counts memory."); memset (mclrefcnt, '\0', nmbclusters); - m_mballoc (nmbuf, M_DONTWAIT); - mbstat.m_mtypes[MT_FREE] = nmbuf; + /* + * Set up mbuf data structures + */ + + p = malloc(nmbuf * MSIZE); + if (p == NULL) + rtems_panic ("Can't get network memory."); + for (i = 0; i < nmbuf; i++) { + ((struct mbuf *)p)->m_next = mmbfree; + mmbfree = (struct mbuf *)p; + p += MSIZE; + } + mbstat.m_mbufs = nmbuf; + mbstat.m_mtypes[MT_FREE] = nmbuf; /* * Set up domains @@ -663,41 +685,8 @@ rtems_bsdnet_log (int priority, const char *fmt, ...) } /* - * Hack alert: kmem_malloc `knows' that its - * first invocation is to get mbuf clusters! - */ -int mb_map_full; -vm_map_t mb_map; -vm_offset_t -kmem_malloc (vm_map_t *map, vm_size_t size, boolean_t waitflag) -{ - void *p; - - /* - * Can't get memory if we're already running. - */ - if (networkDaemonTid) { - if (waitflag == M_WAITOK) - rtems_panic ( -"Network mbuf space can not be enlarged after rtems_bsdnet_initialize() has\n" -"returned. Enlarge the initial mbuf/cluster size in rtems_bsdnet_config."); - return 0; - } - -#define ROUNDSIZE 2048 - p = malloc (size+ROUNDSIZE); - p = (void *)((unsigned long)p & ~(ROUNDSIZE-1)); - if ((p == NULL) && (waitflag == M_WAITOK)) - rtems_panic ("Can't get initial network memory!"); - if (mbutl == NULL) - mbutl = p; - return (vm_offset_t)p; -} - -/* * IP header checksum routine for processors which don't have an inline version */ - u_int in_cksum_hdr (const void *ip) { @@ -926,3 +915,57 @@ rtems_bsdnet_parse_driver_name (const struct rtems_bsdnet_ifconfig *config, char printf ("Bad network driver name `%s'", config->name); return -1; } + +/* + * Handle requests for more network memory + * XXX: Another possibility would be to use a semaphore here with + * a release in the mbuf free macro. I have chosen this `polling' + * approach because: + * 1) It is simpler. + * 2) It adds no complexity to the free macro. + * 3) Running out of mbufs should be a rare + * condition -- predeployment testing of + * an application should indicate the + * required mbuf pool size. + * XXX: Should there be a panic if a task is stuck in the loop for + * more than a minute or so? + */ +int +m_mballoc (int nmb, int nowait) +{ + if (nowait) + return 0; + m_reclaim (); + if (mmbfree == NULL) { + mbstat.m_wait++; + do { + rtems_bsdnet_semaphore_release (); + rtems_task_wake_after (1); + rtems_bsdnet_semaphore_obtain (); + } while (mmbfree == NULL); + } + else { + mbstat.m_drops++; + } + return 1; +} + +int +m_clalloc(ncl, nowait) +{ + if (nowait) + return 0; + m_reclaim (); + if (mclfree == NULL) { + mbstat.m_wait++; + do { + rtems_bsdnet_semaphore_release (); + rtems_task_wake_after (1); + rtems_bsdnet_semaphore_obtain (); + } while (mclfree == NULL); + } + else { + mbstat.m_drops++; + } + return 1; +} |