linux-updates-20060309
[openafs.git] / src / afs / afs_osi_alloc.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 #include <afsconfig.h>
11 #include "afs/param.h"
12
13 RCSID
14     ("$Header$");
15
16
17
18 #include "afs/sysincludes.h"    /* Standard vendor system headers */
19 #include "afsincludes.h"        /* Afs-based standard headers */
20 #include "afs/afs_stats.h"      /* afs statistics */
21
22 #ifndef AFS_FBSD_ENV
23
24 #ifdef AFS_AIX41_ENV
25 #include "sys/lockl.h"
26 #include "sys/sleep.h"
27 #include "sys/syspest.h"
28 #include "sys/lock_def.h"
29 /*lock_t osi_fsplock = LOCK_AVAIL;*/
30 #endif
31
32 afs_lock_t osi_fsplock;
33
34
35
36 static struct osi_packet {
37     struct osi_packet *next;
38 } *freePacketList = NULL, *freeSmallList;
39 afs_lock_t osi_flplock;
40
41
42 /* free space allocated by AllocLargeSpace.  Also called by mclput when freeing
43  * a packet allocated by osi_NetReceive. */
44
45 void
46 osi_FreeLargeSpace(void *adata)
47 {
48
49     AFS_ASSERT_GLOCK();
50
51     AFS_STATCNT(osi_FreeLargeSpace);
52     afs_stats_cmperf.LargeBlocksActive--;
53     MObtainWriteLock(&osi_flplock, 322);
54     ((struct osi_packet *)adata)->next = freePacketList;
55     freePacketList = adata;
56     MReleaseWriteLock(&osi_flplock);
57 }
58
59 void
60 osi_FreeSmallSpace(void *adata)
61 {
62
63     AFS_ASSERT_GLOCK();
64
65     AFS_STATCNT(osi_FreeSmallSpace);
66     afs_stats_cmperf.SmallBlocksActive--;
67     MObtainWriteLock(&osi_fsplock, 323);
68     ((struct osi_packet *)adata)->next = freeSmallList;
69     freeSmallList = adata;
70     MReleaseWriteLock(&osi_fsplock);
71 }
72
73
74 /* allocate space for sender */
75 void *
76 osi_AllocLargeSpace(size_t size)
77 {
78     register struct osi_packet *tp;
79
80     AFS_ASSERT_GLOCK();
81
82     AFS_STATCNT(osi_AllocLargeSpace);
83     if (size > AFS_LRALLOCSIZ)
84         osi_Panic("osi_AllocLargeSpace: size=%d\n", size);
85     afs_stats_cmperf.LargeBlocksActive++;
86     if (!freePacketList) {
87         char *p;
88
89         afs_stats_cmperf.LargeBlocksAlloced++;
90         p = (char *)afs_osi_Alloc(AFS_LRALLOCSIZ);
91 #ifdef  KERNEL_HAVE_PIN
92         /*
93          * Need to pin this memory since under heavy conditions this memory
94          * could be swapped out; the problem is that we could inside rx where
95          * interrupts are disabled and thus we would panic if we don't pin it.
96          */
97         pin(p, AFS_LRALLOCSIZ);
98 #endif
99         return p;
100     }
101     MObtainWriteLock(&osi_flplock, 324);
102     tp = freePacketList;
103     if (tp)
104         freePacketList = tp->next;
105     MReleaseWriteLock(&osi_flplock);
106     return (char *)tp;
107 }
108
109
110 /* allocate space for sender */
111 void *
112 osi_AllocSmallSpace(size_t size)
113 {
114     register struct osi_packet *tp;
115
116     AFS_STATCNT(osi_AllocSmallSpace);
117     if (size > AFS_SMALLOCSIZ)
118         osi_Panic("osi_AllocSmallS: size=%d\n", size);
119
120     if (!freeSmallList) {
121         afs_stats_cmperf.SmallBlocksAlloced++;
122         afs_stats_cmperf.SmallBlocksActive++;
123         return afs_osi_Alloc(AFS_SMALLOCSIZ);
124     }
125     afs_stats_cmperf.SmallBlocksActive++;
126     MObtainWriteLock(&osi_fsplock, 327);
127     tp = freeSmallList;
128     if (tp)
129         freeSmallList = tp->next;
130     MReleaseWriteLock(&osi_fsplock);
131     return (char *)tp;
132 }
133
134
135
136 void
137 shutdown_osinet(void)
138 {
139     extern int afs_cold_shutdown;
140
141     AFS_STATCNT(shutdown_osinet);
142     if (afs_cold_shutdown) {
143         struct osi_packet *tp;
144
145         while ((tp = freePacketList)) {
146             freePacketList = tp->next;
147             afs_osi_Free(tp, AFS_LRALLOCSIZ);
148 #ifdef  KERNEL_HAVE_PIN
149             unpin(tp, AFS_LRALLOCSIZ);
150 #endif
151         }
152
153         while ((tp = freeSmallList)) {
154             freeSmallList = tp->next;
155             afs_osi_Free(tp, AFS_SMALLOCSIZ);
156 #ifdef  KERNEL_HAVE_PIN
157             unpin(tp, AFS_SMALLOCSIZ);
158 #endif
159         }
160         LOCK_INIT(&osi_fsplock, "osi_fsplock");
161         LOCK_INIT(&osi_flplock, "osi_flplock");
162     }
163 }
164 #endif