~ubuntu-branches/ubuntu/hardy/ndiswrapper/hardy

« back to all changes in this revision

Viewing changes to driver/wrapmem.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-12-07 20:42:35 UTC
  • mfrom: (1.2.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20071207204235-s43f889d3h1u6vrl
Tags: 1.50-1ubuntu1
* Merge with Debian; remaining changes:
  - Build for lpia.
  - debian/control:
    + Update description to point out that the kernel source package is
      not required with the standard Ubuntu kernel.
    + Change the Maintainer address.
  - debian/control:
    + Drop ndiswrapper-source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
 
25
25
static struct nt_list allocs;
26
26
static struct nt_list slack_allocs;
27
 
static NT_SPIN_LOCK alloc_lock;
 
27
static spinlock_t alloc_lock;
28
28
 
29
29
struct vmem_block {
30
30
        struct nt_list list;
70
70
{
71
71
        struct slack_alloc_info *info;
72
72
        unsigned int flags;
73
 
        KIRQL irql;
74
73
 
75
74
        ENTER4("size = %lu", (unsigned long)size);
76
75
 
77
 
        if (current_irql() < DISPATCH_LEVEL)
 
76
        if (irql_gfp() & GFP_ATOMIC)
 
77
                flags = GFP_ATOMIC;
 
78
        else
78
79
                flags = GFP_KERNEL;
79
 
        else
80
 
                flags = GFP_ATOMIC;
81
80
        info = kmalloc(size + sizeof(*info), flags);
82
81
        if (!info)
83
82
                return NULL;
84
83
        info->size = size;
85
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
 
84
        spin_lock_bh(&alloc_lock);
86
85
        InsertTailList(&slack_allocs, &info->list);
87
 
        nt_spin_unlock_irql(&alloc_lock, irql);
 
86
        spin_unlock_bh(&alloc_lock);
88
87
#ifdef ALLOC_DEBUG
89
88
        atomic_add(size, &alloc_sizes[ALLOC_TYPE_SLACK]);
90
89
#endif
96
95
void slack_kfree(void *ptr)
97
96
{
98
97
        struct slack_alloc_info *info;
99
 
        KIRQL irql;
100
98
 
101
99
        ENTER4("%p", ptr);
102
100
        info = ptr - sizeof(*info);
103
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
 
101
        spin_lock_bh(&alloc_lock);
104
102
        RemoveEntryList(&info->list);
105
 
        nt_spin_unlock_irql(&alloc_lock, irql);
 
103
        spin_unlock_bh(&alloc_lock);
106
104
#ifdef ALLOC_DEBUG
107
105
        atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]);
108
106
#endif
114
112
void *wrap_kmalloc(size_t size, unsigned flags, const char *file, int line)
115
113
{
116
114
        struct alloc_info *info;
117
 
#if ALLOC_DEBUG > 1
118
 
        KIRQL irql;
119
 
#endif
120
115
 
121
116
        info = kmalloc(size + sizeof(*info), flags);
122
117
        if (!info)
123
118
                return NULL;
124
119
        if (flags & GFP_ATOMIC)
125
 
                info->type = ALLOC_TYPE_ATOMIC;
 
120
                info->type = ALLOC_TYPE_KMALLOC_ATOMIC;
126
121
        else
127
 
                info->type = ALLOC_TYPE_NON_ATOMIC;
 
122
                info->type = ALLOC_TYPE_KMALLOC_NON_ATOMIC;
128
123
        info->size = size;
129
124
        atomic_add(size, &alloc_sizes[info->type]);
130
125
#if ALLOC_DEBUG > 1
133
128
#if ALLOC_DEBUG > 2
134
129
        info->tag = 0;
135
130
#endif
136
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
 
131
        spin_lock_bh(&alloc_lock);
137
132
        InsertTailList(&allocs, &info->list);
138
 
        nt_spin_unlock_irql(&alloc_lock, irql);
 
133
        spin_unlock_bh(&alloc_lock);
139
134
#endif
 
135
        TRACE4("%p", info + 1);
140
136
        return (info + 1);
141
137
}
142
138
 
 
139
void *wrap_kzalloc(size_t size, unsigned flags, const char *file, int line)
 
140
{
 
141
        void *ptr = wrap_kmalloc(size, flags, file, line);
 
142
        if (ptr)
 
143
                memset(ptr, 0, size);
 
144
        return ptr;
 
145
}
 
146
 
143
147
void wrap_kfree(void *ptr)
144
148
{
145
149
        struct alloc_info *info;
146
 
#if ALLOC_DEBUG > 1
147
 
        KIRQL irql;
148
 
#endif
149
150
 
 
151
        TRACE4("%p", ptr);
 
152
        if (!ptr)
 
153
                return;
150
154
        info = ptr - sizeof(*info);
151
155
        atomic_sub(info->size, &alloc_sizes[info->type]);
152
156
#if ALLOC_DEBUG > 1
153
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
 
157
        spin_lock_bh(&alloc_lock);
154
158
        RemoveEntryList(&info->list);
155
 
        nt_spin_unlock_irql(&alloc_lock, irql);
156
 
        if (!(info->type == ALLOC_TYPE_ATOMIC ||
157
 
              info->type == ALLOC_TYPE_NON_ATOMIC))
 
159
        spin_unlock_bh(&alloc_lock);
 
160
        if (!(info->type == ALLOC_TYPE_KMALLOC_ATOMIC ||
 
161
              info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC))
158
162
                WARNING("invliad type: %d", info->type);
159
163
#endif
160
164
        kfree(info);
163
167
void *wrap_vmalloc(unsigned long size, const char *file, int line)
164
168
{
165
169
        struct alloc_info *info;
166
 
#if ALLOC_DEBUG > 1
167
 
        KIRQL irql;
168
 
#endif
169
170
 
170
171
        info = vmalloc(size + sizeof(*info));
171
172
        if (!info)
172
173
                return NULL;
173
 
        info->type = ALLOC_TYPE_VMALLOC;
 
174
        info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC;
174
175
        info->size = size;
175
176
        atomic_add(size, &alloc_sizes[info->type]);
176
177
#if ALLOC_DEBUG > 1
179
180
#if ALLOC_DEBUG > 2
180
181
        info->tag = 0;
181
182
#endif
182
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
 
183
        spin_lock_bh(&alloc_lock);
183
184
        InsertTailList(&allocs, &info->list);
184
 
        nt_spin_unlock_irql(&alloc_lock, irql);
 
185
        spin_unlock_bh(&alloc_lock);
185
186
#endif
186
187
        return (info + 1);
187
188
}
190
191
                    const char *file, int line)
191
192
{
192
193
        struct alloc_info *info;
193
 
#if ALLOC_DEBUG > 1
194
 
        KIRQL irql;
195
 
#endif
196
194
 
197
195
        info = __vmalloc(size + sizeof(*info), gfp_mask, prot);
198
196
        if (!info)
199
197
                return NULL;
200
 
        info->type = ALLOC_TYPE_VMALLOC;
 
198
        if (gfp_mask & GFP_ATOMIC)
 
199
                info->type = ALLOC_TYPE_VMALLOC_ATOMIC;
 
200
        else
 
201
                info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC;
201
202
        info->size = size;
202
203
        atomic_add(size, &alloc_sizes[info->type]);
203
204
#if ALLOC_DEBUG > 1
206
207
#if ALLOC_DEBUG > 2
207
208
        info->tag = 0;
208
209
#endif
209
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
 
210
        spin_lock_bh(&alloc_lock);
210
211
        InsertTailList(&allocs, &info->list);
211
 
        nt_spin_unlock_irql(&alloc_lock, irql);
 
212
        spin_unlock_bh(&alloc_lock);
212
213
#endif
213
214
        return (info + 1);
214
215
}
216
217
void wrap_vfree(void *ptr)
217
218
{
218
219
        struct alloc_info *info;
219
 
#if ALLOC_DEBUG > 1
220
 
        KIRQL irql;
221
 
#endif
222
220
 
223
221
        info = ptr - sizeof(*info);
224
222
        atomic_sub(info->size, &alloc_sizes[info->type]);
225
223
#if ALLOC_DEBUG > 1
226
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
 
224
        spin_lock_bh(&alloc_lock);
227
225
        RemoveEntryList(&info->list);
228
 
        nt_spin_unlock_irql(&alloc_lock, irql);
229
 
        if (info->type != ALLOC_TYPE_VMALLOC)
 
226
        spin_unlock_bh(&alloc_lock);
 
227
        if (!(info->type == ALLOC_TYPE_VMALLOC_ATOMIC ||
 
228
              info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC))
230
229
                WARNING("invliad type: %d", info->type);
231
230
#endif
232
231
        vfree(info);
236
235
                       const char *file, int line)
237
236
{
238
237
        struct alloc_info *info;
239
 
#if ALLOC_DEBUG > 1
240
 
        KIRQL irql;
241
 
#endif
242
238
 
243
239
        size += sizeof(*info);
244
240
        info = (struct alloc_info *)__get_free_pages(flags, get_order(size));
253
249
#if ALLOC_DEBUG > 2
254
250
        info->tag = 0;
255
251
#endif
256
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
 
252
        spin_lock_bh(&alloc_lock);
257
253
        InsertTailList(&allocs, &info->list);
258
 
        nt_spin_unlock_irql(&alloc_lock, irql);
 
254
        spin_unlock_bh(&alloc_lock);
259
255
#endif
260
256
        return info + 1;
261
257
}
263
259
void wrap_free_pages(unsigned long ptr, int order)
264
260
{
265
261
        struct alloc_info *info;
266
 
#if ALLOC_DEBUG > 1
267
 
        KIRQL irql;
268
 
#endif
269
262
 
270
263
        info = (void *)ptr - sizeof(*info);
271
264
        atomic_sub(info->size, &alloc_sizes[info->type]);
272
265
#if ALLOC_DEBUG > 1
273
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
 
266
        spin_lock_bh(&alloc_lock);
274
267
        RemoveEntryList(&info->list);
275
 
        nt_spin_unlock_irql(&alloc_lock, irql);
 
268
        spin_unlock_bh(&alloc_lock);
276
269
        if (info->type != ALLOC_TYPE_PAGES)
277
270
                WARNING("invliad type: %d", info->type);
278
271
#endif
316
309
        InitializeListHead(&allocs);
317
310
        InitializeListHead(&slack_allocs);
318
311
        InitializeListHead(&vmem_list);
319
 
        nt_spin_lock_init(&alloc_lock);
 
312
        spin_lock_init(&alloc_lock);
320
313
        return 0;
321
314
}
322
315
 
324
317
{
325
318
        enum alloc_type type;
326
319
        struct nt_list *ent;
327
 
        KIRQL irql;
328
320
 
329
321
        /* free all pointers on the slack list */
330
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
331
 
        while ((ent = RemoveHeadList(&slack_allocs))) {
 
322
        while (1) {
332
323
                struct slack_alloc_info *info;
 
324
                spin_lock_bh(&alloc_lock);
 
325
                ent = RemoveHeadList(&slack_allocs);
 
326
                spin_unlock_bh(&alloc_lock);
 
327
                if (!ent)
 
328
                        break;
333
329
                info = container_of(ent, struct slack_alloc_info, list);
334
330
#ifdef ALLOC_DEBUG
335
331
                atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]);
336
332
#endif
337
333
                kfree(info);
338
334
        }
339
 
        nt_spin_unlock_irql(&alloc_lock, irql);
340
335
        type = 0;
341
336
#ifdef ALLOC_DEBUG
342
337
        for (type = 0; type < ALLOC_TYPE_MAX; type++) {
346
341
        }
347
342
 
348
343
#if ALLOC_DEBUG > 1
349
 
        irql = nt_spin_lock_irql(&alloc_lock, DISPATCH_LEVEL);
350
 
        while ((ent = RemoveHeadList(&allocs))) {
 
344
        while (1) {
351
345
                struct alloc_info *info;
 
346
 
 
347
                spin_lock_bh(&alloc_lock);
 
348
                ent = RemoveHeadList(&allocs);
 
349
                spin_unlock_bh(&alloc_lock);
 
350
                if (!ent)
 
351
                        break;
352
352
                info = container_of(ent, struct alloc_info, list);
353
353
                atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]);
354
354
                WARNING("%p in %d of size %zu allocated at %s(%d) "
361
361
                        , info->tag
362
362
#endif
363
363
                        );
364
 
                if (info->type == ALLOC_TYPE_ATOMIC ||
365
 
                    info->type == ALLOC_TYPE_NON_ATOMIC)
 
364
                if (info->type == ALLOC_TYPE_KMALLOC_ATOMIC ||
 
365
                    info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC)
366
366
                        kfree(info);
367
 
                else if (info->type == ALLOC_TYPE_VMALLOC)
 
367
                else if (info->type == ALLOC_TYPE_VMALLOC_ATOMIC ||
 
368
                         info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC)
368
369
                        vfree(info);
 
370
                else if (info->type == ALLOC_TYPE_PAGES)
 
371
                        free_pages((unsigned long)info, get_order(info->size));
369
372
                else
370
373
                        WARNING("invalid type: %d; not freed", info->type);
371
 
 
372
374
        }
373
 
        nt_spin_unlock_irql(&alloc_lock, irql);
374
375
#endif
375
376
#endif
376
377
        return;