#include <afsconfig.h>
#include "afs/param.h"
-RCSID("$Header$");
+RCSID
+ ("$Header$");
#include "afs/sysincludes.h" /* Standard vendor system headers */
#include "afsincludes.h" /* Afs-based standard headers */
-#include "afs/afs_stats.h" /* afs statistics */
+#include "afs/afs_stats.h" /* afs statistics */
+
+
#ifdef AFS_AIX41_ENV
#include "sys/lockl.h"
#include "sys/syspest.h"
#include "sys/lock_def.h"
/*lock_t osi_fsplock = LOCK_AVAIL;*/
-#else
-afs_lock_t osi_fsplock;
#endif
+afs_lock_t osi_fsplock;
+
static struct osi_packet {
struct osi_packet *next;
-} *freePacketList = 0, *freeSmallList, *freeMediumList;
+} *freePacketList = NULL, *freeSmallList;
afs_lock_t osi_flplock;
+static char memZero; /* address of 0 bytes for kmem_alloc */
+
+struct osimem {
+ struct osimem *next;
+};
-afs_int32 afs_preallocs = 512; /* Reserve space for all small allocs! */
-void osi_AllocMoreSSpace(register afs_int32 preallocs)
+
+void *
+afs_osi_Alloc(size_t x)
{
- register int i;
- char *p;
+#if !defined(AFS_LINUX20_ENV) && !defined(AFS_FBSD_ENV)
+ register struct osimem *tm = NULL;
+ register int size;
+#endif
- p = (char *) afs_osi_Alloc(AFS_SMALLOCSIZ * preallocs);
-#ifdef KERNEL_HAVE_PIN
- pin(p, AFS_SMALLOCSIZ * preallocs); /* XXXX */
+ AFS_STATCNT(osi_Alloc);
+ /* 0-length allocs may return NULL ptr from AFS_KALLOC, so we special-case
+ * things so that NULL returned iff an error occurred */
+ if (x == 0)
+ return &memZero;
+
+ AFS_STATS(afs_stats_cmperf.OutStandingAllocs++);
+ AFS_STATS(afs_stats_cmperf.OutStandingMemUsage += x);
+#ifdef AFS_LINUX20_ENV
+ return osi_linux_alloc(x, 1);
+#elif defined(AFS_FBSD_ENV)
+ return osi_fbsd_alloc(x, 1);
+#else
+ size = x;
+ tm = (struct osimem *)AFS_KALLOC(size);
+#ifdef AFS_SUN5_ENV
+ if (!tm)
+ osi_Panic("osi_Alloc: Couldn't allocate %d bytes; out of memory!\n",
+ size);
#endif
- for (i=0; i < preallocs; i++, p += AFS_SMALLOCSIZ) {
-#ifdef AFS_AIX32_ENV
- *p = '\0'; /* page fault it in. */
+ return (void *)tm;
#endif
- osi_FreeSmallSpace((char *) p);
- }
- afs_stats_cmperf.SmallBlocksAlloced += preallocs;
- afs_stats_cmperf.SmallBlocksActive += preallocs;
+}
+
+#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
+
+void *
+afs_osi_Alloc_NoSleep(size_t x)
+{
+ register struct osimem *tm;
+ register int size;
+
+ AFS_STATCNT(osi_Alloc);
+ /* 0-length allocs may return NULL ptr from AFS_KALLOC, so we special-case
+ * things so that NULL returned iff an error occurred */
+ if (x == 0)
+ return &memZero;
+
+ size = x;
+ AFS_STATS(afs_stats_cmperf.OutStandingAllocs++);
+ AFS_STATS(afs_stats_cmperf.OutStandingMemUsage += x);
+ tm = (struct osimem *)AFS_KALLOC_NOSLEEP(size);
+ return (void *)tm;
+}
+
+#endif /* SUN || SGI */
+
+void
+afs_osi_Free(void *x, size_t asize)
+{
+ AFS_STATCNT(osi_Free);
+ if (x == &memZero)
+ return; /* check for putting memZero back */
+
+ AFS_STATS(afs_stats_cmperf.OutStandingAllocs--);
+ AFS_STATS(afs_stats_cmperf.OutStandingMemUsage -= asize);
+#if defined(AFS_LINUX20_ENV)
+ osi_linux_free(x);
+#elif defined(AFS_FBSD_ENV)
+ osi_fbsd_free(x);
+#else
+ AFS_KFREE((struct osimem *)x, asize);
+#endif
+}
+
+void
+afs_osi_FreeStr(char *x)
+{
+ afs_osi_Free(x, strlen(x) + 1);
}
/* free space allocated by AllocLargeSpace. Also called by mclput when freeing
* a packet allocated by osi_NetReceive. */
-void osi_FreeLargeSpace(void *adata)
+void
+osi_FreeLargeSpace(void *adata)
{
AFS_ASSERT_GLOCK();
AFS_STATCNT(osi_FreeLargeSpace);
afs_stats_cmperf.LargeBlocksActive--;
- MObtainWriteLock(&osi_flplock,322);
+ MObtainWriteLock(&osi_flplock, 322);
((struct osi_packet *)adata)->next = freePacketList;
freePacketList = adata;
MReleaseWriteLock(&osi_flplock);
}
-void osi_FreeSmallSpace(void *adata)
+void
+osi_FreeSmallSpace(void *adata)
{
-#if defined(AFS_AIX32_ENV)
- int x;
-#endif
-#if defined(AFS_HPUX_ENV)
- ulong_t x;
-#endif
-
AFS_ASSERT_GLOCK();
AFS_STATCNT(osi_FreeSmallSpace);
afs_stats_cmperf.SmallBlocksActive--;
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
- x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
-#else
- MObtainWriteLock(&osi_fsplock,323);
-#endif
+ MObtainWriteLock(&osi_fsplock, 323);
((struct osi_packet *)adata)->next = freeSmallList;
freeSmallList = adata;
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
- splx(x); /*unlockl(&osi_fsplock);*/
-#else
MReleaseWriteLock(&osi_fsplock);
-#endif
-}
-
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
-osi_AllocMoreMSpace(register afs_int32 preallocs)
-{
- register int i;
- char *p;
-
- p = (char *) afs_osi_Alloc(AFS_MDALLOCSIZ * preallocs);
-#ifdef KERNEL_HAVE_PIN
- pin(p, AFS_MDALLOCSIZ * preallocs); /* XXXX */
-#endif
- for (i=0; i < preallocs; i++, p += AFS_MDALLOCSIZ) {
-#ifdef AFS_AIX32_ENV
- *p = '\0'; /* page fault it in. */
-#endif
- osi_FreeMediumSpace((char *) p);
- }
- afs_stats_cmperf.MediumBlocksAlloced += preallocs;
- afs_stats_cmperf.MediumBlocksActive += preallocs;
-}
-
-
-void *osi_AllocMediumSpace(size_t size)
-{
- register struct osi_packet *tp;
-#if defined(AFS_AIX32_ENV)
- int x;
-#endif
-#if defined(AFS_HPUX_ENV)
- ulong_t x;
-#endif
-
- afs_stats_cmperf.MediumBlocksActive++;
- retry:
- x = splnet();
- tp = freeMediumList;
- if ( tp ) freeMediumList = tp->next;
- splx(x);
- if (!tp) {
- osi_AllocMoreMSpace(AFS_MALLOC_LOW_WATER);
- goto retry;
- }
- return tp;
-}
-
-void osi_FreeMediumSpace(void *adata)
-{
-
-#if defined(AFS_AIX32_ENV)
- int x;
-#endif
-#if defined(AFS_HPUX_ENV)
- ulong_t x;
-#endif
-
- afs_stats_cmperf.MediumBlocksActive--;
- x = splnet();
- ((struct osi_packet *)adata)->next = freeMediumList;
- freeMediumList = adata;
- splx(x);
}
-#endif /* defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV) */
/* allocate space for sender */
-void *osi_AllocLargeSpace(size_t size)
+void *
+osi_AllocLargeSpace(size_t size)
{
register struct osi_packet *tp;
AFS_STATCNT(osi_AllocLargeSpace);
if (size > AFS_LRALLOCSIZ)
- osi_Panic("osi_AllocLargeSpace: size=%d\n", size);
+ osi_Panic("osi_AllocLargeSpace: size=%d\n", (int)size);
afs_stats_cmperf.LargeBlocksActive++;
if (!freePacketList) {
char *p;
afs_stats_cmperf.LargeBlocksAlloced++;
- p = (char *) afs_osi_Alloc(AFS_LRALLOCSIZ);
+ p = (char *)afs_osi_Alloc(AFS_LRALLOCSIZ);
#ifdef KERNEL_HAVE_PIN
/*
* Need to pin this memory since under heavy conditions this memory
- * could be swapped out; the problem is that we could inside rx where
- * interrupts are disabled and thus we would panic if we don't pin it.
- */
- pin(p, AFS_LRALLOCSIZ);
+ * could be swapped out; the problem is that we could inside rx where
+ * interrupts are disabled and thus we would panic if we don't pin it.
+ */
+ pin(p, AFS_LRALLOCSIZ);
#endif
return p;
}
- MObtainWriteLock(&osi_flplock,324);
+ MObtainWriteLock(&osi_flplock, 324);
tp = freePacketList;
- if ( tp ) freePacketList = tp->next;
+ if (tp)
+ freePacketList = tp->next;
MReleaseWriteLock(&osi_flplock);
- return (char *) tp;
+ return (char *)tp;
}
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
-/*
- * XXX We could have used a macro around osi_AllocSmallSpace but it's
- * probably better like this so that we can remove this at some point.
- */
-/* morespace 1 - means we called at splnet level */
-char *osi_AllocSmall(register afs_int32 size, register afs_int32 morespace)
-{
- register struct osi_packet *tp;
-#if defined(AFS_AIX32_ENV)
- int x;
-#endif
-#if defined(AFS_HPUX_ENV)
- ulong_t x;
-#endif
-
- AFS_ASSERT_GLOCK();
-
- AFS_STATCNT(osi_AllocSmallSpace);
- if (size > AFS_SMALLOCSIZ) osi_Panic("osi_AllocSmall, size=%d", size);
- if ((!morespace &&
- ((afs_stats_cmperf.SmallBlocksAlloced - afs_stats_cmperf.SmallBlocksActive)
- <= AFS_SALLOC_LOW_WATER))
- || !freeSmallList) {
- osi_AllocMoreSSpace(AFS_SALLOC_LOW_WATER * 2);
- }
- afs_stats_cmperf.SmallBlocksActive++;
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
- x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
-#else
- MObtainWriteLock(&osi_fsplock,325);
-#endif
- tp = freeSmallList;
- if ( tp ) freeSmallList = tp->next;
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
- splx(x); /*unlockl(&osi_fsplock);*/
-#else
- MReleaseWriteLock(&osi_fsplock);
-#endif
-
- return (char *) tp;
-}
-
-int osi_FreeSmall(register struct osi_packet *adata)
-{
-#if defined(AFS_AIX32_ENV)
- int x;
-#endif
-#if defined(AFS_HPUX_ENV)
- ulong_t x;
-#endif
-
- AFS_STATCNT(osi_FreeSmallSpace);
- afs_stats_cmperf.SmallBlocksActive--;
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
- x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
-#else
- MObtainWriteLock(&osi_fsplock,326);
-#endif
- adata->next = freeSmallList;
- freeSmallList = adata;
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
- splx(x); /*unlockl(&osi_fsplock);*/
-#else
- MReleaseWriteLock(&osi_fsplock);
-#endif
- return 0;
-}
-#endif /* AFS_AIX32_ENV || AFS_HPUX_ENV */
/* allocate space for sender */
-void *osi_AllocSmallSpace(size_t size)
+void *
+osi_AllocSmallSpace(size_t size)
{
register struct osi_packet *tp;
-#if defined(AFS_AIX32_ENV)
- int x;
-#endif
-#if defined(AFS_HPUX_ENV)
- ulong_t x;
-#endif
AFS_STATCNT(osi_AllocSmallSpace);
- if (size > AFS_SMALLOCSIZ) osi_Panic("osi_AllocSmallS: size=%d\n", size);
-
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
- /*
- * We're running out of free blocks (< 50); get some more ourselves so that
- * when we don't run out of them when called under splnet() (from rx);
- */
- if (((afs_stats_cmperf.SmallBlocksAlloced - afs_stats_cmperf.SmallBlocksActive)
- <= AFS_SALLOC_LOW_WATER) || !freeSmallList) {
- osi_AllocMoreSSpace(AFS_SALLOC_LOW_WATER * 2);
- }
-#else
+ if (size > AFS_SMALLOCSIZ)
+ osi_Panic("osi_AllocSmallS: size=%d\n", (int)size);
+
if (!freeSmallList) {
afs_stats_cmperf.SmallBlocksAlloced++;
afs_stats_cmperf.SmallBlocksActive++;
- return afs_osi_Alloc(AFS_SMALLOCSIZ);
- }
+ tp = afs_osi_Alloc(AFS_SMALLOCSIZ);
+#ifdef KERNEL_HAVE_PIN
+ pin((char *)tp, AFS_SMALLOCSIZ);
#endif
+ return (char *)tp;
+ }
afs_stats_cmperf.SmallBlocksActive++;
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
- x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
-#else
- MObtainWriteLock(&osi_fsplock,327);
-#endif
+ MObtainWriteLock(&osi_fsplock, 327);
tp = freeSmallList;
- if ( tp ) freeSmallList = tp->next;
-#if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
- splx(x); /*unlockl(&osi_fsplock);*/
-#else
+ if (tp)
+ freeSmallList = tp->next;
MReleaseWriteLock(&osi_fsplock);
-#endif
- return (char *) tp;
+ return (char *)tp;
}
-void shutdown_osinet(void)
-{
- extern int afs_cold_shutdown;
-
- AFS_STATCNT(shutdown_osinet);
- if (afs_cold_shutdown) {
- struct osi_packet *tp;
+void
+shutdown_osinet(void)
+{
+ AFS_STATCNT(shutdown_osinet);
+ if (afs_cold_shutdown) {
+ struct osi_packet *tp;
- while ((tp = freePacketList)) {
- freePacketList = tp->next;
- afs_osi_Free(tp, AFS_LRALLOCSIZ);
+ while ((tp = freePacketList)) {
+ freePacketList = tp->next;
+ afs_osi_Free(tp, AFS_LRALLOCSIZ);
#ifdef KERNEL_HAVE_PIN
- unpin(tp, AFS_LRALLOCSIZ);
+ unpin(tp, AFS_LRALLOCSIZ);
#endif
- }
+ }
- while ((tp = freeSmallList)) {
- freeSmallList = tp->next;
- afs_osi_Free(tp, AFS_SMALLOCSIZ);
+ while ((tp = freeSmallList)) {
+ freeSmallList = tp->next;
+ afs_osi_Free(tp, AFS_SMALLOCSIZ);
#ifdef KERNEL_HAVE_PIN
- unpin(tp, AFS_SMALLOCSIZ);
+ unpin(tp, AFS_SMALLOCSIZ);
#endif
+ }
+ LOCK_INIT(&osi_fsplock, "osi_fsplock");
+ LOCK_INIT(&osi_flplock, "osi_flplock");
+ }
+ if (afs_stats_cmperf.LargeBlocksActive ||
+ afs_stats_cmperf.SmallBlocksActive)
+ {
+ afs_warn("WARNING: not all blocks freed: large %d small %d\n",
+ afs_stats_cmperf.LargeBlocksActive,
+ afs_stats_cmperf.SmallBlocksActive);
}
- afs_preallocs = 512;
-#ifndef AFS_AIX32_ENV
- LOCK_INIT(&osi_fsplock, "osi_fsplock");
-#endif
- LOCK_INIT(&osi_flplock, "osi_flplock");
- }
}