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(register afs_int32 preallocs)
45 p = (char *) afs_osi_Alloc(AFS_SMALLOCSIZ * preallocs);
46 #ifdef KERNEL_HAVE_PIN
47 pin(p, AFS_SMALLOCSIZ * preallocs); /* XXXX */
49 for (i=0; i < preallocs; i++, p += AFS_SMALLOCSIZ) {
51 *p = '\0'; /* page fault it in. */
53 osi_FreeSmallSpace((char *) p);
55 afs_stats_cmperf.SmallBlocksAlloced += preallocs;
56 afs_stats_cmperf.SmallBlocksActive += preallocs;
61 /* free space allocated by AllocLargeSpace. Also called by mclput when freeing
62 * a packet allocated by osi_NetReceive. */
64 void osi_FreeLargeSpace(void *adata)
69 AFS_STATCNT(osi_FreeLargeSpace);
70 afs_stats_cmperf.LargeBlocksActive--;
71 MObtainWriteLock(&osi_flplock,322);
72 ((struct osi_packet *)adata)->next = freePacketList;
73 freePacketList = adata;
74 MReleaseWriteLock(&osi_flplock);
77 void osi_FreeSmallSpace(void *adata)
80 #if defined(AFS_AIX32_ENV)
83 #if defined(AFS_HPUX_ENV)
89 AFS_STATCNT(osi_FreeSmallSpace);
90 afs_stats_cmperf.SmallBlocksActive--;
91 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
92 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
94 MObtainWriteLock(&osi_fsplock,323);
96 ((struct osi_packet *)adata)->next = freeSmallList;
97 freeSmallList = adata;
98 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
99 splx(x); /*unlockl(&osi_fsplock);*/
101 MReleaseWriteLock(&osi_fsplock);
105 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
106 osi_AllocMoreMSpace(register afs_int32 preallocs)
111 p = (char *) afs_osi_Alloc(AFS_MDALLOCSIZ * preallocs);
112 #ifdef KERNEL_HAVE_PIN
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);
149 void osi_FreeMediumSpace(void *adata)
152 #if defined(AFS_AIX32_ENV)
155 #if defined(AFS_HPUX_ENV)
159 afs_stats_cmperf.MediumBlocksActive--;
161 ((struct osi_packet *)adata)->next = freeMediumList;
162 freeMediumList = adata;
165 #endif /* defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV) */
168 /* allocate space for sender */
169 void *osi_AllocLargeSpace(size_t size)
171 register struct osi_packet *tp;
175 AFS_STATCNT(osi_AllocLargeSpace);
176 if (size > AFS_LRALLOCSIZ)
177 osi_Panic("osi_AllocLargeSpace: size=%d\n", size);
178 afs_stats_cmperf.LargeBlocksActive++;
179 if (!freePacketList) {
182 afs_stats_cmperf.LargeBlocksAlloced++;
183 p = (char *) afs_osi_Alloc(AFS_LRALLOCSIZ);
184 #ifdef KERNEL_HAVE_PIN
186 * Need to pin this memory since under heavy conditions this memory
187 * could be swapped out; the problem is that we could inside rx where
188 * interrupts are disabled and thus we would panic if we don't pin it.
190 pin(p, AFS_LRALLOCSIZ);
194 MObtainWriteLock(&osi_flplock,324);
196 if ( tp ) freePacketList = tp->next;
197 MReleaseWriteLock(&osi_flplock);
201 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
203 * XXX We could have used a macro around osi_AllocSmallSpace but it's
204 * probably better like this so that we can remove this at some point.
206 /* morespace 1 - means we called at splnet level */
207 char *osi_AllocSmall(register afs_int32 size, register afs_int32 morespace)
209 register struct osi_packet *tp;
210 #if defined(AFS_AIX32_ENV)
213 #if defined(AFS_HPUX_ENV)
219 AFS_STATCNT(osi_AllocSmallSpace);
220 if (size > AFS_SMALLOCSIZ) osi_Panic("osi_AllocSmall, size=%d", size);
222 ((afs_stats_cmperf.SmallBlocksAlloced - afs_stats_cmperf.SmallBlocksActive)
223 <= AFS_SALLOC_LOW_WATER))
225 osi_AllocMoreSSpace(AFS_SALLOC_LOW_WATER * 2);
227 afs_stats_cmperf.SmallBlocksActive++;
228 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
229 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
231 MObtainWriteLock(&osi_fsplock,325);
234 if ( tp ) freeSmallList = tp->next;
235 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
236 splx(x); /*unlockl(&osi_fsplock);*/
238 MReleaseWriteLock(&osi_fsplock);
244 int osi_FreeSmall(register struct osi_packet *adata)
246 #if defined(AFS_AIX32_ENV)
249 #if defined(AFS_HPUX_ENV)
253 AFS_STATCNT(osi_FreeSmallSpace);
254 afs_stats_cmperf.SmallBlocksActive--;
255 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
256 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
258 MObtainWriteLock(&osi_fsplock,326);
260 adata->next = freeSmallList;
261 freeSmallList = adata;
262 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
263 splx(x); /*unlockl(&osi_fsplock);*/
265 MReleaseWriteLock(&osi_fsplock);
269 #endif /* AFS_AIX32_ENV || AFS_HPUX_ENV */
271 /* allocate space for sender */
272 void *osi_AllocSmallSpace(size_t size)
274 register struct osi_packet *tp;
275 #if defined(AFS_AIX32_ENV)
278 #if defined(AFS_HPUX_ENV)
282 AFS_STATCNT(osi_AllocSmallSpace);
283 if (size > AFS_SMALLOCSIZ) osi_Panic("osi_AllocSmallS: size=%d\n", size);
285 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
287 * We're running out of free blocks (< 50); get some more ourselves so that
288 * when we don't run out of them when called under splnet() (from rx);
290 if (((afs_stats_cmperf.SmallBlocksAlloced - afs_stats_cmperf.SmallBlocksActive)
291 <= AFS_SALLOC_LOW_WATER) || !freeSmallList) {
292 osi_AllocMoreSSpace(AFS_SALLOC_LOW_WATER * 2);
295 if (!freeSmallList) {
296 afs_stats_cmperf.SmallBlocksAlloced++;
297 afs_stats_cmperf.SmallBlocksActive++;
298 return afs_osi_Alloc(AFS_SMALLOCSIZ);
301 afs_stats_cmperf.SmallBlocksActive++;
302 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
303 x = splnet(); /*lockl(&osi_fsplock, LOCK_SHORT);*/
305 MObtainWriteLock(&osi_fsplock,327);
308 if ( tp ) freeSmallList = tp->next;
309 #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV)
310 splx(x); /*unlockl(&osi_fsplock);*/
312 MReleaseWriteLock(&osi_fsplock);
319 void shutdown_osinet(void)
321 extern int afs_cold_shutdown;
323 AFS_STATCNT(shutdown_osinet);
324 if (afs_cold_shutdown) {
325 struct osi_packet *tp;
327 while ((tp = freePacketList)) {
328 freePacketList = tp->next;
329 afs_osi_Free(tp, AFS_LRALLOCSIZ);
330 #ifdef KERNEL_HAVE_PIN
331 unpin(tp, AFS_LRALLOCSIZ);
335 while ((tp = freeSmallList)) {
336 freeSmallList = tp->next;
337 afs_osi_Free(tp, AFS_SMALLOCSIZ);
338 #ifdef KERNEL_HAVE_PIN
339 unpin(tp, AFS_SMALLOCSIZ);
343 #ifndef AFS_AIX32_ENV
344 LOCK_INIT(&osi_fsplock, "osi_fsplock");
346 LOCK_INIT(&osi_flplock, "osi_flplock");