00001
00002
00003
00004
00005
00006 #include <linux/config.h>
00007 #include <linux/compiler.h>
00008 #include <linux/init.h>
00009 #include <linux/mm.h>
00010 #include <linux/bootmem.h>
00011
00012 #include<irpdef.h>
00013 #include<npool_data.h>
00014 #include<ssdef.h>
00015 #include<system_data_cells.h>
00016 #include <exe_routines.h>
00017 #include <misc_routines.h>
00018 #include <mmg_routines.h>
00019 #include <internals.h>
00020 #include <ipldef.h>
00021
00022
00023
00024
00025 struct _myhead {
00026 struct _myhead * hd_l_flink;
00027 long hd_l_seq;
00028 };
00029
00030 struct mymap {
00031 unsigned long flink;
00032 unsigned long size;
00033 };
00034
00035 struct _npool_data npp_pool;
00036 struct _npool_data bap_pool;
00037 struct _lsthds npp_listheads;
00038 struct _lsthds bap_listheads;
00039
00040 void __init init_nonpaged_pool(void * pgdat, int size, struct _npool_data * pool, void ** start , void ** free) {
00041 struct mymap * mytmp;
00042
00043 *start=alloc_bootmem_node(pgdat,size);
00044 *start= (struct page *)(PAGE_OFFSET +
00045 MAP_ALIGN((unsigned long)(*start) - PAGE_OFFSET));
00046 *free= *start;
00047 struct _lsthds * l = pool->npool_ar_lsthds;
00048 l->lsthds_l_variablelist_unused=*free;
00049 mytmp=*start;
00050 mytmp->flink=0;
00051 mytmp->size=size;
00052 poison_packet(mytmp,size,1);
00053 }
00054
00055 void __init init_nonpaged(void *pgdat, unsigned long totalpages) {
00056 memset(&npp_pool, 0, sizeof(npp_pool));
00057 memset(&bap_pool, 0, sizeof(bap_pool));
00058 memset(&npp_listheads, 0, sizeof(npp_listheads));
00059 memset(&bap_listheads, 0, sizeof(npp_listheads));
00060 npp_pool.npool_ar_lsthds=&npp_listheads;
00061 bap_pool.npool_ar_lsthds=&bap_listheads;
00062 exe_gs_npp_npool=&npp_pool;
00063 exe_gs_bap_npool=&bap_pool;
00064 exe_gs_npp_base_lsthds=&npp_listheads;
00065 exe_gs_bap_base_lsthds=&bap_listheads;
00066
00067
00068
00069
00070 sgn_gl_npagedyn=totalpages<<(PAGE_SHIFT-2);
00071
00072 init_nonpaged_pool(pgdat, 2*1024*1024, exe_gs_bap_npool, &mmg$gq_bap, &exe$gq_bap_variable);
00073 init_nonpaged_pool(pgdat, totalpages<<(PAGE_SHIFT-2), exe_gs_npp_npool, &mmg$gl_npagedyn, &exe$gl_nonpaged);
00074
00075 #if 0
00076 void exe_reclaim_pool_gentle(void * pool);
00077 signed long long time=-10000000*60;
00078 exe_setimr(0, &time, exe$reclaim_pool_gentle, exe$gs_npp_npool, 0);
00079 #endif
00080 }
00081
00082
00083 int exe_alononpagvar (int reqsize, int *alosize_p, void **pool_p) {
00084
00085
00086 int sts=SS__NORMAL;
00087
00088 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00089 sts=exe_allocate(reqsize , &exe$gl_nonpaged, 0 , alosize_p, pool_p);
00090 vmsunlock(&SPIN_POOL, ipl);
00091
00092
00093
00094 if (sts==SS__NORMAL)
00095 return sts;
00096
00097 struct _npool_data * pooldata = exe_gs_npp_npool;
00098 struct _lsthds * lsthd = pooldata->npool_ar_lsthds;
00099 void * array = &lsthd->lsthds_q_listheads;
00100
00101 exe_reclaim_pool_aggressive(exe$gs_npp_npool);
00102 ipl = vmslock(&SPIN_POOL, IPL__POOL);
00103 sts=exe_allocate(reqsize , &exe$gl_nonpaged, 0 , alosize_p, pool_p);
00104 vmsunlock(&SPIN_POOL, ipl);
00105
00106 if (sts==SS__NORMAL)
00107 return sts;
00108
00109 sts=exe_extendpool(exe$gs_npp_npool);
00110 if (sts==SS__NORMAL) {
00111 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00112 sts=exe_allocate(reqsize , &exe$gl_nonpaged, 0 , alosize_p, pool_p);
00113 vmsunlock(&SPIN_POOL, ipl);
00114 }
00115
00116 if (sts==SS__NORMAL)
00117 return sts;
00118
00119 sts=exe_flushlists(exe$gs_npp_npool, reqsize);
00120
00121 if (sts==SS__NORMAL) {
00122 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00123 sts=exe_allocate(reqsize , &exe$gl_nonpaged, 0 , alosize_p, pool_p);
00124 vmsunlock(&SPIN_POOL, ipl);
00125 }
00126
00127 return sts;
00128 }
00129
00130 int exe_std_alononpaged (int reqsize, int *alosize_p, void **pool_p) {
00131 int sts=SS__NORMAL;
00132 #if 0
00133 if (reqsize<=srpsize) {
00134 if (rqempty(&ioc_gq_srpiq))
00135 goto var;
00136 int addr=remqti(&ioc_gq_srpiq,addr);
00137 *alosize_p=reqsize;
00138 *pool_p=addr;
00139 return sts;
00140 }
00141 if (reqsize<=irpsize) {
00142 if (rqempty(&ioc_gq_irpiq))
00143 goto var;
00144 int addr=remqti(&ioc_gq_irpiq,addr);
00145 *alosize_p=reqsize;
00146 *pool_p=addr;
00147 return sts;
00148 }
00149 if (reqsize >= lrpmin && reqsize<=srpsize) {
00150 if (rqempty(&ioc_gq_lrpiq))
00151 goto var;
00152 int addr=remqti(&ioc_gq_srpiq,addr);
00153 *alosize_p=reqsize;
00154 *pool_p=addr;
00155 return sts;
00156 }
00157 #endif
00158 if (reqsize&63)
00159 reqsize=((reqsize>>6)+1)<<6;
00160
00161 *alosize_p=reqsize;
00162
00163 struct _npool_data * pooldata = exe_gs_npp_npool;
00164 struct _lsthds * lsthd = pooldata->npool_ar_lsthds;
00165 struct _myhead * array = &lsthd->lsthds_q_listheads;
00166
00167 if (reqsize<=8192) {
00168 *pool_p = exe_lal_remove_first(&array[reqsize>>6]);
00169 if (*pool_p) {
00170 check_packet(*pool_p,reqsize,0);
00171 #if 0
00172 poison_packet(*pool_p,reqsize,0);
00173 #endif
00174 }
00175 }
00176
00177 if (0==*pool_p)
00178 sts = exe_alononpagvar(reqsize, alosize_p, pool_p);
00179
00180 return sts;
00181 }
00182
00183 int exe_std_deanonpgdsiz(void *pool, int size) {
00184
00185 #if 0
00186
00187
00188 if (mmg_gl_npagedyn<=pool && pool<=ioc$gl_lrpsplit) {
00189 struct _irp * irp = pool;
00190 if (irp->irp_w_size)
00191 panic("irp size\n");
00192 int sts=exe_deallocate(pool, exe$gl_nonpaged, irp->irp$w_size);
00193 return sts;
00194 }
00195
00196 if (ioc_gl_lrpsplit<=pool && pool<=ioc$gl_splitadr) {
00197 insqti(pool,&ioc_gl_lrpsplit);
00198 return SS__NORMAL;
00199 }
00200
00201 if (ioc_gl_splitadr<=pool && pool<=ioc$gl_srpsplit) {
00202 insqti(pool,&ioc_gl_splitadr);
00203 return SS__NORMAL;
00204 }
00205
00206 if (ioc_gl_srpsplit<=pool && pool<=(ioc$gl_srpsplit+4*512*srpsize)) {
00207 insqti(pool,&ioc_gl_srpsplit);
00208 return SS__NORMAL;
00209 }
00210
00211 return 0;
00212 #endif
00213
00214 if (size&63)
00215 size=((size>>6)+1)<<6;
00216
00217 if (size==0 || (size&63))
00218 panic("size size %x\n",size);
00219
00220 struct _npool_data * pooldata = exe_gs_npp_npool;
00221 struct _lsthds * lsthd = pooldata->npool_ar_lsthds;
00222 struct _myhead * array = &lsthd->lsthds_q_listheads;
00223
00224 if (size<=8192) {
00225 poison_packet(pool,size,1);
00226 exe_lal_insert_first(pool, &array[size>>6]);
00227 } else {
00228 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00229 int sts=exe_deallocate(pool, exe$gl_nonpaged, size);
00230 vmsunlock(&SPIN_POOL, ipl);
00231 }
00232 return SS__NORMAL;
00233 }
00234
00235 int exe_std_deanonpaged (void *pool) {
00236 struct _irp * irp = pool;
00237 return exe_std_deanonpgdsiz(pool, irp->irp$w_size);
00238 }
00239
00240 int exe_flushlists(void * pool, int size) {
00241
00242 struct _npool_data * pooldata = pool;
00243 struct _lsthds * lsthd = pooldata->npool_ar_lsthds;
00244 void * array = &lsthd->lsthds_q_listheads;
00245 void * listhead=array;
00246 void * basepool=lsthd->lsthds_l_variablelist_unused;
00247
00248 struct _myhead * hd = array;
00249
00250 int i=size>>6;
00251
00252 for(;i<129;i++) {
00253 void * ret = exe_lal_remove_first(&hd[i]);
00254 if (ret==0)
00255 break;
00256 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00257 exe_deallocate(ret, basepool, 64*i);
00258 vmsunlock(&SPIN_POOL, ipl);
00259 }
00260 }
00261