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 "../afs/param.h" /* Should be always first */
13 #include "../afs/sysincludes.h" /* Standard vendor system headers */
14 #include "../afs/afsincludes.h" /* Afs-based standard headers */
15 #include "../afs/afs_stats.h" /* afs statistics */
18 #include "sys/lockl.h"
19 #include "sys/sleep.h"
20 #include "sys/syspest.h"
21 #include "sys/lock_def.h"
22 /*lock_t osi_fsplock = LOCK_AVAIL;*/
24 afs_lock_t osi_fsplock;
29 static struct osi_packet {
30 struct osi_packet *next;
31 } *freePacketList = 0, *freeSmallList, *freeMediumList;
32 afs_lock_t osi_flplock;
35 afs_int32 afs_preallocs = 512; /* Reserve space for all small allocs! */
36 void osi_AllocMoreSSpace(preallocs)
37 register afs_int32 preallocs;
42 p = (char *) afs_osi_Alloc(AFS_SMALLOCSIZ * preallocs);
44 pin(p, AFS_SMALLOCSIZ * preallocs); /* XXXX */
46 for (i=0; i < preallocs; i++, p += AFS_SMALLOCSIZ) {
48 *p = '\0'; /* page fault it in. */
50 osi_FreeSmallSpace((char *) p);
52 afs_stats_cmperf.SmallBlocksAlloced += preallocs;
53 afs_stats_cmperf.SmallBlocksActive += preallocs;
58 /* free space allocated by AllocLargeSpace. Also called by mclput when freeing
59 * a packet allocated by osi_NetReceive. */
62 osi_FreeLargeSpace(void *adata)
67 AFS_STATCNT(osi_FreeLargeSpace);
68 afs_stats_cmperf.LargeBlocksActive--;
69 MObtainWriteLock(&osi_flplock,322);
70 ((struct osi_packet *)adata)->next = freePacketList;
71 freePacketList = adata;
72 MReleaseWriteLock(&osi_flplock);
76 osi_FreeSmallSpace(void *adata)
79 #if defined(AFS_AIX32_ENV)
82 #if defined(AFS_HPUX_ENV)
88 AFS_STATCNT(osi_FreeSmallSpace);
89 afs_stats_cmperf.SmallBlocksActive--;
90 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
91 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
93 MObtainWriteLock(&osi_fsplock,323);
95 ((struct osi_packet *)adata)->next = freeSmallList;
96 freeSmallList = adata;
97 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
98 splx(x); /*unlockl(&osi_fsplock);*/
100 MReleaseWriteLock(&osi_fsplock);
104 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
105 osi_AllocMoreMSpace(preallocs)
106 register afs_int32 preallocs;
111 p = (char *) afs_osi_Alloc(AFS_MDALLOCSIZ * preallocs);
113 pin(p, AFS_MDALLOCSIZ * preallocs); /* XXXX */
115 for (i=0; i < preallocs; i++, p += AFS_MDALLOCSIZ) {
117 *p = '\0'; /* page fault it in. */
119 osi_FreeMediumSpace((char *) p);
121 afs_stats_cmperf.MediumBlocksAlloced += preallocs;
122 afs_stats_cmperf.MediumBlocksActive += preallocs;
126 void *osi_AllocMediumSpace(size_t size)
128 register struct osi_packet *tp;
129 #if defined(AFS_AIX32_ENV)
132 #if defined(AFS_HPUX_ENV)
136 afs_stats_cmperf.MediumBlocksActive++;
140 if ( tp ) freeMediumList = tp->next;
143 osi_AllocMoreMSpace(AFS_MALLOC_LOW_WATER);
150 osi_FreeMediumSpace(void *adata)
153 #if defined(AFS_AIX32_ENV)
156 #if defined(AFS_HPUX_ENV)
160 afs_stats_cmperf.MediumBlocksActive--;
162 ((struct osi_packet *)adata)->next = freeMediumList;
163 freeMediumList = adata;
166 #endif /* defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV) */
169 /* allocate space for sender */
170 void *osi_AllocLargeSpace(size_t size)
172 register struct osi_packet *tp;
176 AFS_STATCNT(osi_AllocLargeSpace);
177 if (size > AFS_LRALLOCSIZ)
178 osi_Panic("osi_AllocLargeSpace: size=%d\n", size);
179 afs_stats_cmperf.LargeBlocksActive++;
180 if (!freePacketList) {
183 afs_stats_cmperf.LargeBlocksAlloced++;
184 p = (char *) afs_osi_Alloc(AFS_LRALLOCSIZ);
187 * Need to pin this memory since under heavy conditions this memory
188 * could be swapped out; the problem is that we could inside rx where
189 * interrupts are disabled and thus we would panic if we don't pin it.
191 pin(p, AFS_LRALLOCSIZ);
195 MObtainWriteLock(&osi_flplock,324);
197 if ( tp ) freePacketList = tp->next;
198 MReleaseWriteLock(&osi_flplock);
202 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
204 * XXX We could have used a macro around osi_AllocSmallSpace but it's
205 * probably better like this so that we can remove this at some point.
207 char *osi_AllocSmall(size, morespace)
208 register afs_int32 morespace; /* 1 - means we called at splnet level */
209 register afs_int32 size;
211 register struct osi_packet *tp;
212 #if defined(AFS_AIX32_ENV)
215 #if defined(AFS_HPUX_ENV)
221 AFS_STATCNT(osi_AllocSmallSpace);
222 if (size > AFS_SMALLOCSIZ) osi_Panic("osi_AllocSmall, size=%d", size);
224 ((afs_stats_cmperf.SmallBlocksAlloced - afs_stats_cmperf.SmallBlocksActive)
225 <= AFS_SALLOC_LOW_WATER))
227 osi_AllocMoreSSpace(AFS_SALLOC_LOW_WATER * 2);
229 afs_stats_cmperf.SmallBlocksActive++;
230 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
231 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
233 MObtainWriteLock(&osi_fsplock,325);
236 if ( tp ) freeSmallList = tp->next;
237 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
238 splx(x); /*unlockl(&osi_fsplock);*/
240 MReleaseWriteLock(&osi_fsplock);
247 register struct osi_packet *adata; {
248 #if defined(AFS_AIX32_ENV)
251 #if defined(AFS_HPUX_ENV)
255 AFS_STATCNT(osi_FreeSmallSpace);
256 afs_stats_cmperf.SmallBlocksActive--;
257 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
258 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
260 MObtainWriteLock(&osi_fsplock,326);
262 adata->next = freeSmallList;
263 freeSmallList = adata;
264 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
265 splx(x); /*unlockl(&osi_fsplock);*/
267 MReleaseWriteLock(&osi_fsplock);
271 #endif /* AFS_AIX32_ENV || AFS_HPUX_ENV */
273 /* allocate space for sender */
274 void *osi_AllocSmallSpace(size_t size)
276 register struct osi_packet *tp;
277 #if defined(AFS_AIX32_ENV)
280 #if defined(AFS_HPUX_ENV)
284 AFS_STATCNT(osi_AllocSmallSpace);
285 if (size > AFS_SMALLOCSIZ) osi_Panic("osi_AllocSmallS: size=%d\n", size);
287 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
289 * We're running out of free blocks (< 50); get some more ourselves so that
290 * when we don't run out of them when called under splnet() (from rx);
292 if (((afs_stats_cmperf.SmallBlocksAlloced - afs_stats_cmperf.SmallBlocksActive)
293 <= AFS_SALLOC_LOW_WATER) || !freeSmallList) {
294 osi_AllocMoreSSpace(AFS_SALLOC_LOW_WATER * 2);
297 if (!freeSmallList) {
298 afs_stats_cmperf.SmallBlocksAlloced++;
299 afs_stats_cmperf.SmallBlocksActive++;
300 return afs_osi_Alloc(AFS_SMALLOCSIZ);
303 afs_stats_cmperf.SmallBlocksActive++;
304 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
305 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
307 MObtainWriteLock(&osi_fsplock,327);
310 if ( tp ) freeSmallList = tp->next;
311 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
312 splx(x); /*unlockl(&osi_fsplock);*/
314 MReleaseWriteLock(&osi_fsplock);
321 void shutdown_osinet()
323 extern int afs_cold_shutdown;
325 AFS_STATCNT(shutdown_osinet);
326 if (afs_cold_shutdown) {
327 struct osi_packet *tp;
329 while (tp = freePacketList) {
330 freePacketList = tp->next;
331 afs_osi_Free(tp, AFS_LRALLOCSIZ);
333 unpin(tp, AFS_LRALLOCSIZ);
337 while (tp = freeSmallList) {
338 freeSmallList = tp->next;
339 afs_osi_Free(tp, AFS_SMALLOCSIZ);
341 unpin(tp, AFS_SMALLOCSIZ);
345 #ifndef AFS_AIX32_ENV
346 LOCK_INIT(&osi_fsplock, "osi_fsplock");
348 LOCK_INIT(&osi_flplock, "osi_flplock");