2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include "../afs/param.h"
17 #include "../afs/sysincludes.h" /* Standard vendor system headers */
18 #include "../afs/afsincludes.h" /* Afs-based standard headers */
19 #include "../afs/afs_stats.h" /* afs statistics */
22 #include "sys/lockl.h"
23 #include "sys/sleep.h"
24 #include "sys/syspest.h"
25 #include "sys/lock_def.h"
26 /*lock_t osi_fsplock = LOCK_AVAIL;*/
28 afs_lock_t osi_fsplock;
33 static struct osi_packet {
34 struct osi_packet *next;
35 } *freePacketList = 0, *freeSmallList, *freeMediumList;
36 afs_lock_t osi_flplock;
39 afs_int32 afs_preallocs = 512; /* Reserve space for all small allocs! */
40 void osi_AllocMoreSSpace(preallocs)
41 register afs_int32 preallocs;
46 p = (char *) afs_osi_Alloc(AFS_SMALLOCSIZ * preallocs);
48 pin(p, AFS_SMALLOCSIZ * preallocs); /* XXXX */
50 for (i=0; i < preallocs; i++, p += AFS_SMALLOCSIZ) {
52 *p = '\0'; /* page fault it in. */
54 osi_FreeSmallSpace((char *) p);
56 afs_stats_cmperf.SmallBlocksAlloced += preallocs;
57 afs_stats_cmperf.SmallBlocksActive += preallocs;
62 /* free space allocated by AllocLargeSpace. Also called by mclput when freeing
63 * a packet allocated by osi_NetReceive. */
66 osi_FreeLargeSpace(void *adata)
71 AFS_STATCNT(osi_FreeLargeSpace);
72 afs_stats_cmperf.LargeBlocksActive--;
73 MObtainWriteLock(&osi_flplock,322);
74 ((struct osi_packet *)adata)->next = freePacketList;
75 freePacketList = adata;
76 MReleaseWriteLock(&osi_flplock);
80 osi_FreeSmallSpace(void *adata)
83 #if defined(AFS_AIX32_ENV)
86 #if defined(AFS_HPUX_ENV)
92 AFS_STATCNT(osi_FreeSmallSpace);
93 afs_stats_cmperf.SmallBlocksActive--;
94 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
95 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
97 MObtainWriteLock(&osi_fsplock,323);
99 ((struct osi_packet *)adata)->next = freeSmallList;
100 freeSmallList = adata;
101 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
102 splx(x); /*unlockl(&osi_fsplock);*/
104 MReleaseWriteLock(&osi_fsplock);
108 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
109 osi_AllocMoreMSpace(preallocs)
110 register afs_int32 preallocs;
115 p = (char *) afs_osi_Alloc(AFS_MDALLOCSIZ * preallocs);
117 pin(p, AFS_MDALLOCSIZ * preallocs); /* XXXX */
119 for (i=0; i < preallocs; i++, p += AFS_MDALLOCSIZ) {
121 *p = '\0'; /* page fault it in. */
123 osi_FreeMediumSpace((char *) p);
125 afs_stats_cmperf.MediumBlocksAlloced += preallocs;
126 afs_stats_cmperf.MediumBlocksActive += preallocs;
130 void *osi_AllocMediumSpace(size_t size)
132 register struct osi_packet *tp;
133 #if defined(AFS_AIX32_ENV)
136 #if defined(AFS_HPUX_ENV)
140 afs_stats_cmperf.MediumBlocksActive++;
144 if ( tp ) freeMediumList = tp->next;
147 osi_AllocMoreMSpace(AFS_MALLOC_LOW_WATER);
154 osi_FreeMediumSpace(void *adata)
157 #if defined(AFS_AIX32_ENV)
160 #if defined(AFS_HPUX_ENV)
164 afs_stats_cmperf.MediumBlocksActive--;
166 ((struct osi_packet *)adata)->next = freeMediumList;
167 freeMediumList = adata;
170 #endif /* defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV) */
173 /* allocate space for sender */
174 void *osi_AllocLargeSpace(size_t size)
176 register struct osi_packet *tp;
180 AFS_STATCNT(osi_AllocLargeSpace);
181 if (size > AFS_LRALLOCSIZ)
182 osi_Panic("osi_AllocLargeSpace: size=%d\n", size);
183 afs_stats_cmperf.LargeBlocksActive++;
184 if (!freePacketList) {
187 afs_stats_cmperf.LargeBlocksAlloced++;
188 p = (char *) afs_osi_Alloc(AFS_LRALLOCSIZ);
191 * Need to pin this memory since under heavy conditions this memory
192 * could be swapped out; the problem is that we could inside rx where
193 * interrupts are disabled and thus we would panic if we don't pin it.
195 pin(p, AFS_LRALLOCSIZ);
199 MObtainWriteLock(&osi_flplock,324);
201 if ( tp ) freePacketList = tp->next;
202 MReleaseWriteLock(&osi_flplock);
206 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
208 * XXX We could have used a macro around osi_AllocSmallSpace but it's
209 * probably better like this so that we can remove this at some point.
211 char *osi_AllocSmall(size, morespace)
212 register afs_int32 morespace; /* 1 - means we called at splnet level */
213 register afs_int32 size;
215 register struct osi_packet *tp;
216 #if defined(AFS_AIX32_ENV)
219 #if defined(AFS_HPUX_ENV)
225 AFS_STATCNT(osi_AllocSmallSpace);
226 if (size > AFS_SMALLOCSIZ) osi_Panic("osi_AllocSmall, size=%d", size);
228 ((afs_stats_cmperf.SmallBlocksAlloced - afs_stats_cmperf.SmallBlocksActive)
229 <= AFS_SALLOC_LOW_WATER))
231 osi_AllocMoreSSpace(AFS_SALLOC_LOW_WATER * 2);
233 afs_stats_cmperf.SmallBlocksActive++;
234 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
235 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
237 MObtainWriteLock(&osi_fsplock,325);
240 if ( tp ) freeSmallList = tp->next;
241 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
242 splx(x); /*unlockl(&osi_fsplock);*/
244 MReleaseWriteLock(&osi_fsplock);
251 register struct osi_packet *adata; {
252 #if defined(AFS_AIX32_ENV)
255 #if defined(AFS_HPUX_ENV)
259 AFS_STATCNT(osi_FreeSmallSpace);
260 afs_stats_cmperf.SmallBlocksActive--;
261 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
262 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
264 MObtainWriteLock(&osi_fsplock,326);
266 adata->next = freeSmallList;
267 freeSmallList = adata;
268 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
269 splx(x); /*unlockl(&osi_fsplock);*/
271 MReleaseWriteLock(&osi_fsplock);
275 #endif /* AFS_AIX32_ENV || AFS_HPUX_ENV */
277 /* allocate space for sender */
278 void *osi_AllocSmallSpace(size_t size)
280 register struct osi_packet *tp;
281 #if defined(AFS_AIX32_ENV)
284 #if defined(AFS_HPUX_ENV)
288 AFS_STATCNT(osi_AllocSmallSpace);
289 if (size > AFS_SMALLOCSIZ) osi_Panic("osi_AllocSmallS: size=%d\n", size);
291 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
293 * We're running out of free blocks (< 50); get some more ourselves so that
294 * when we don't run out of them when called under splnet() (from rx);
296 if (((afs_stats_cmperf.SmallBlocksAlloced - afs_stats_cmperf.SmallBlocksActive)
297 <= AFS_SALLOC_LOW_WATER) || !freeSmallList) {
298 osi_AllocMoreSSpace(AFS_SALLOC_LOW_WATER * 2);
301 if (!freeSmallList) {
302 afs_stats_cmperf.SmallBlocksAlloced++;
303 afs_stats_cmperf.SmallBlocksActive++;
304 return afs_osi_Alloc(AFS_SMALLOCSIZ);
307 afs_stats_cmperf.SmallBlocksActive++;
308 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
309 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
311 MObtainWriteLock(&osi_fsplock,327);
314 if ( tp ) freeSmallList = tp->next;
315 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
316 splx(x); /*unlockl(&osi_fsplock);*/
318 MReleaseWriteLock(&osi_fsplock);
325 void shutdown_osinet()
327 extern int afs_cold_shutdown;
329 AFS_STATCNT(shutdown_osinet);
330 if (afs_cold_shutdown) {
331 struct osi_packet *tp;
333 while (tp = freePacketList) {
334 freePacketList = tp->next;
335 afs_osi_Free(tp, AFS_LRALLOCSIZ);
337 unpin(tp, AFS_LRALLOCSIZ);
341 while (tp = freeSmallList) {
342 freeSmallList = tp->next;
343 afs_osi_Free(tp, AFS_SMALLOCSIZ);
345 unpin(tp, AFS_SMALLOCSIZ);
349 #ifndef AFS_AIX32_ENV
350 LOCK_INIT(&osi_fsplock, "osi_fsplock");
352 LOCK_INIT(&osi_flplock, "osi_flplock");