Contents of /trunk/kernel26-magellan/patches-2.6.20-r5/0111-2.6.20.11-all-fixes.patch
Parent Directory | Revision Log
Revision 177 -
(show annotations)
(download)
Wed May 9 17:12:59 2007 UTC (17 years, 4 months ago) by niro
File size: 64264 byte(s)
Wed May 9 17:12:59 2007 UTC (17 years, 4 months ago) by niro
File size: 64264 byte(s)
-linux-2.6.20.11
1 | diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S |
2 | index 2c5b5cc..8143c95 100644 |
3 | --- a/arch/i386/boot/video.S |
4 | +++ b/arch/i386/boot/video.S |
5 | @@ -571,6 +571,16 @@ setr1: lodsw |
6 | jmp _m_s |
7 | |
8 | check_vesa: |
9 | +#ifdef CONFIG_FIRMWARE_EDID |
10 | + leaw modelist+1024, %di |
11 | + movw $0x4f00, %ax |
12 | + int $0x10 |
13 | + cmpw $0x004f, %ax |
14 | + jnz setbad |
15 | + |
16 | + movw 4(%di), %ax |
17 | + movw %ax, vbe_version |
18 | +#endif |
19 | leaw modelist+1024, %di |
20 | subb $VIDEO_FIRST_VESA>>8, %bh |
21 | movw %bx, %cx # Get mode information structure |
22 | @@ -1945,6 +1955,9 @@ store_edid: |
23 | rep |
24 | stosl |
25 | |
26 | + cmpw $0x0200, vbe_version # only do EDID on >= VBE2.0 |
27 | + jl no_edid |
28 | + |
29 | pushw %es # save ES |
30 | xorw %di, %di # Report Capability |
31 | pushw %di |
32 | @@ -1987,6 +2000,7 @@ do_restore: .byte 0 # Screen contents altered during mode change |
33 | svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes |
34 | graphic_mode: .byte 0 # Graphic mode with a linear frame buffer |
35 | dac_size: .byte 6 # DAC bit depth |
36 | +vbe_version: .word 0 # VBE bios version |
37 | |
38 | # Status messages |
39 | keymsg: .ascii "Press <RETURN> to see video modes available, " |
40 | diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c |
41 | index 2e7f142..7aca0f3 100644 |
42 | --- a/arch/sparc64/kernel/pci_iommu.c |
43 | +++ b/arch/sparc64/kernel/pci_iommu.c |
44 | @@ -64,7 +64,7 @@ static void __iommu_flushall(struct pci_iommu *iommu) |
45 | #define IOPTE_IS_DUMMY(iommu, iopte) \ |
46 | ((iopte_val(*iopte) & IOPTE_PAGE) == (iommu)->dummy_page_pa) |
47 | |
48 | -static void inline iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte) |
49 | +static inline void iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte) |
50 | { |
51 | unsigned long val = iopte_val(*iopte); |
52 | |
53 | diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c |
54 | index 01d6d86..14f78fb 100644 |
55 | --- a/arch/sparc64/kernel/sbus.c |
56 | +++ b/arch/sparc64/kernel/sbus.c |
57 | @@ -24,48 +24,25 @@ |
58 | |
59 | #include "iommu_common.h" |
60 | |
61 | -/* These should be allocated on an SMP_CACHE_BYTES |
62 | - * aligned boundary for optimal performance. |
63 | - * |
64 | - * On SYSIO, using an 8K page size we have 1GB of SBUS |
65 | - * DMA space mapped. We divide this space into equally |
66 | - * sized clusters. We allocate a DMA mapping from the |
67 | - * cluster that matches the order of the allocation, or |
68 | - * if the order is greater than the number of clusters, |
69 | - * we try to allocate from the last cluster. |
70 | - */ |
71 | - |
72 | -#define NCLUSTERS 8UL |
73 | -#define ONE_GIG (1UL * 1024UL * 1024UL * 1024UL) |
74 | -#define CLUSTER_SIZE (ONE_GIG / NCLUSTERS) |
75 | -#define CLUSTER_MASK (CLUSTER_SIZE - 1) |
76 | -#define CLUSTER_NPAGES (CLUSTER_SIZE >> IO_PAGE_SHIFT) |
77 | #define MAP_BASE ((u32)0xc0000000) |
78 | |
79 | +struct sbus_iommu_arena { |
80 | + unsigned long *map; |
81 | + unsigned int hint; |
82 | + unsigned int limit; |
83 | +}; |
84 | + |
85 | struct sbus_iommu { |
86 | -/*0x00*/spinlock_t lock; |
87 | + spinlock_t lock; |
88 | |
89 | -/*0x08*/iopte_t *page_table; |
90 | -/*0x10*/unsigned long strbuf_regs; |
91 | -/*0x18*/unsigned long iommu_regs; |
92 | -/*0x20*/unsigned long sbus_control_reg; |
93 | + struct sbus_iommu_arena arena; |
94 | |
95 | -/*0x28*/volatile unsigned long strbuf_flushflag; |
96 | + iopte_t *page_table; |
97 | + unsigned long strbuf_regs; |
98 | + unsigned long iommu_regs; |
99 | + unsigned long sbus_control_reg; |
100 | |
101 | - /* If NCLUSTERS is ever decresed to 4 or lower, |
102 | - * you must increase the size of the type of |
103 | - * these counters. You have been duly warned. -DaveM |
104 | - */ |
105 | -/*0x30*/struct { |
106 | - u16 next; |
107 | - u16 flush; |
108 | - } alloc_info[NCLUSTERS]; |
109 | - |
110 | - /* The lowest used consistent mapping entry. Since |
111 | - * we allocate consistent maps out of cluster 0 this |
112 | - * is relative to the beginning of closter 0. |
113 | - */ |
114 | -/*0x50*/u32 lowest_consistent_map; |
115 | + volatile unsigned long strbuf_flushflag; |
116 | }; |
117 | |
118 | /* Offsets from iommu_regs */ |
119 | @@ -91,19 +68,6 @@ static void __iommu_flushall(struct sbus_iommu *iommu) |
120 | tag += 8UL; |
121 | } |
122 | upa_readq(iommu->sbus_control_reg); |
123 | - |
124 | - for (entry = 0; entry < NCLUSTERS; entry++) { |
125 | - iommu->alloc_info[entry].flush = |
126 | - iommu->alloc_info[entry].next; |
127 | - } |
128 | -} |
129 | - |
130 | -static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) |
131 | -{ |
132 | - while (npages--) |
133 | - upa_writeq(base + (npages << IO_PAGE_SHIFT), |
134 | - iommu->iommu_regs + IOMMU_FLUSH); |
135 | - upa_readq(iommu->sbus_control_reg); |
136 | } |
137 | |
138 | /* Offsets from strbuf_regs */ |
139 | @@ -156,178 +120,115 @@ static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long |
140 | base, npages); |
141 | } |
142 | |
143 | -static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) |
144 | +/* Based largely upon the ppc64 iommu allocator. */ |
145 | +static long sbus_arena_alloc(struct sbus_iommu *iommu, unsigned long npages) |
146 | { |
147 | - iopte_t *iopte, *limit, *first, *cluster; |
148 | - unsigned long cnum, ent, nent, flush_point, found; |
149 | - |
150 | - cnum = 0; |
151 | - nent = 1; |
152 | - while ((1UL << cnum) < npages) |
153 | - cnum++; |
154 | - if(cnum >= NCLUSTERS) { |
155 | - nent = 1UL << (cnum - NCLUSTERS); |
156 | - cnum = NCLUSTERS - 1; |
157 | - } |
158 | - iopte = iommu->page_table + (cnum * CLUSTER_NPAGES); |
159 | - |
160 | - if (cnum == 0) |
161 | - limit = (iommu->page_table + |
162 | - iommu->lowest_consistent_map); |
163 | - else |
164 | - limit = (iopte + CLUSTER_NPAGES); |
165 | - |
166 | - iopte += ((ent = iommu->alloc_info[cnum].next) << cnum); |
167 | - flush_point = iommu->alloc_info[cnum].flush; |
168 | - |
169 | - first = iopte; |
170 | - cluster = NULL; |
171 | - found = 0; |
172 | - for (;;) { |
173 | - if (iopte_val(*iopte) == 0UL) { |
174 | - found++; |
175 | - if (!cluster) |
176 | - cluster = iopte; |
177 | + struct sbus_iommu_arena *arena = &iommu->arena; |
178 | + unsigned long n, i, start, end, limit; |
179 | + int pass; |
180 | + |
181 | + limit = arena->limit; |
182 | + start = arena->hint; |
183 | + pass = 0; |
184 | + |
185 | +again: |
186 | + n = find_next_zero_bit(arena->map, limit, start); |
187 | + end = n + npages; |
188 | + if (unlikely(end >= limit)) { |
189 | + if (likely(pass < 1)) { |
190 | + limit = start; |
191 | + start = 0; |
192 | + __iommu_flushall(iommu); |
193 | + pass++; |
194 | + goto again; |
195 | } else { |
196 | - /* Used cluster in the way */ |
197 | - cluster = NULL; |
198 | - found = 0; |
199 | + /* Scanned the whole thing, give up. */ |
200 | + return -1; |
201 | } |
202 | + } |
203 | |
204 | - if (found == nent) |
205 | - break; |
206 | - |
207 | - iopte += (1 << cnum); |
208 | - ent++; |
209 | - if (iopte >= limit) { |
210 | - iopte = (iommu->page_table + (cnum * CLUSTER_NPAGES)); |
211 | - ent = 0; |
212 | - |
213 | - /* Multiple cluster allocations must not wrap */ |
214 | - cluster = NULL; |
215 | - found = 0; |
216 | + for (i = n; i < end; i++) { |
217 | + if (test_bit(i, arena->map)) { |
218 | + start = i + 1; |
219 | + goto again; |
220 | } |
221 | - if (ent == flush_point) |
222 | - __iommu_flushall(iommu); |
223 | - if (iopte == first) |
224 | - goto bad; |
225 | } |
226 | |
227 | - /* ent/iopte points to the last cluster entry we're going to use, |
228 | - * so save our place for the next allocation. |
229 | - */ |
230 | - if ((iopte + (1 << cnum)) >= limit) |
231 | - ent = 0; |
232 | - else |
233 | - ent = ent + 1; |
234 | - iommu->alloc_info[cnum].next = ent; |
235 | - if (ent == flush_point) |
236 | - __iommu_flushall(iommu); |
237 | - |
238 | - /* I've got your streaming cluster right here buddy boy... */ |
239 | - return cluster; |
240 | - |
241 | -bad: |
242 | - printk(KERN_EMERG "sbus: alloc_streaming_cluster of npages(%ld) failed!\n", |
243 | - npages); |
244 | - return NULL; |
245 | + for (i = n; i < end; i++) |
246 | + __set_bit(i, arena->map); |
247 | + |
248 | + arena->hint = end; |
249 | + |
250 | + return n; |
251 | } |
252 | |
253 | -static void free_streaming_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages) |
254 | +static void sbus_arena_free(struct sbus_iommu_arena *arena, unsigned long base, unsigned long npages) |
255 | { |
256 | - unsigned long cnum, ent, nent; |
257 | - iopte_t *iopte; |
258 | + unsigned long i; |
259 | |
260 | - cnum = 0; |
261 | - nent = 1; |
262 | - while ((1UL << cnum) < npages) |
263 | - cnum++; |
264 | - if(cnum >= NCLUSTERS) { |
265 | - nent = 1UL << (cnum - NCLUSTERS); |
266 | - cnum = NCLUSTERS - 1; |
267 | - } |
268 | - ent = (base & CLUSTER_MASK) >> (IO_PAGE_SHIFT + cnum); |
269 | - iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT); |
270 | - do { |
271 | - iopte_val(*iopte) = 0UL; |
272 | - iopte += 1 << cnum; |
273 | - } while(--nent); |
274 | - |
275 | - /* If the global flush might not have caught this entry, |
276 | - * adjust the flush point such that we will flush before |
277 | - * ever trying to reuse it. |
278 | - */ |
279 | -#define between(X,Y,Z) (((Z) - (Y)) >= ((X) - (Y))) |
280 | - if (between(ent, iommu->alloc_info[cnum].next, iommu->alloc_info[cnum].flush)) |
281 | - iommu->alloc_info[cnum].flush = ent; |
282 | -#undef between |
283 | + for (i = base; i < (base + npages); i++) |
284 | + __clear_bit(i, arena->map); |
285 | } |
286 | |
287 | -/* We allocate consistent mappings from the end of cluster zero. */ |
288 | -static iopte_t *alloc_consistent_cluster(struct sbus_iommu *iommu, unsigned long npages) |
289 | +static void sbus_iommu_table_init(struct sbus_iommu *iommu, unsigned int tsbsize) |
290 | { |
291 | - iopte_t *iopte; |
292 | + unsigned long tsbbase, order, sz, num_tsb_entries; |
293 | |
294 | - iopte = iommu->page_table + (1 * CLUSTER_NPAGES); |
295 | - while (iopte > iommu->page_table) { |
296 | - iopte--; |
297 | - if (!(iopte_val(*iopte) & IOPTE_VALID)) { |
298 | - unsigned long tmp = npages; |
299 | + num_tsb_entries = tsbsize / sizeof(iopte_t); |
300 | |
301 | - while (--tmp) { |
302 | - iopte--; |
303 | - if (iopte_val(*iopte) & IOPTE_VALID) |
304 | - break; |
305 | - } |
306 | - if (tmp == 0) { |
307 | - u32 entry = (iopte - iommu->page_table); |
308 | + /* Setup initial software IOMMU state. */ |
309 | + spin_lock_init(&iommu->lock); |
310 | |
311 | - if (entry < iommu->lowest_consistent_map) |
312 | - iommu->lowest_consistent_map = entry; |
313 | - return iopte; |
314 | - } |
315 | - } |
316 | + /* Allocate and initialize the free area map. */ |
317 | + sz = num_tsb_entries / 8; |
318 | + sz = (sz + 7UL) & ~7UL; |
319 | + iommu->arena.map = kzalloc(sz, GFP_KERNEL); |
320 | + if (!iommu->arena.map) { |
321 | + prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); |
322 | + prom_halt(); |
323 | + } |
324 | + iommu->arena.limit = num_tsb_entries; |
325 | + |
326 | + /* Now allocate and setup the IOMMU page table itself. */ |
327 | + order = get_order(tsbsize); |
328 | + tsbbase = __get_free_pages(GFP_KERNEL, order); |
329 | + if (!tsbbase) { |
330 | + prom_printf("IOMMU: Error, gfp(tsb) failed.\n"); |
331 | + prom_halt(); |
332 | } |
333 | - return NULL; |
334 | + iommu->page_table = (iopte_t *)tsbbase; |
335 | + memset(iommu->page_table, 0, tsbsize); |
336 | } |
337 | |
338 | -static void free_consistent_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages) |
339 | +static inline iopte_t *alloc_npages(struct sbus_iommu *iommu, unsigned long npages) |
340 | { |
341 | - iopte_t *iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT); |
342 | + long entry; |
343 | |
344 | - if ((iopte - iommu->page_table) == iommu->lowest_consistent_map) { |
345 | - iopte_t *walk = iopte + npages; |
346 | - iopte_t *limit; |
347 | + entry = sbus_arena_alloc(iommu, npages); |
348 | + if (unlikely(entry < 0)) |
349 | + return NULL; |
350 | |
351 | - limit = iommu->page_table + CLUSTER_NPAGES; |
352 | - while (walk < limit) { |
353 | - if (iopte_val(*walk) != 0UL) |
354 | - break; |
355 | - walk++; |
356 | - } |
357 | - iommu->lowest_consistent_map = |
358 | - (walk - iommu->page_table); |
359 | - } |
360 | + return iommu->page_table + entry; |
361 | +} |
362 | |
363 | - while (npages--) |
364 | - *iopte++ = __iopte(0UL); |
365 | +static inline void free_npages(struct sbus_iommu *iommu, dma_addr_t base, unsigned long npages) |
366 | +{ |
367 | + sbus_arena_free(&iommu->arena, base >> IO_PAGE_SHIFT, npages); |
368 | } |
369 | |
370 | void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma_addr) |
371 | { |
372 | - unsigned long order, first_page, flags; |
373 | struct sbus_iommu *iommu; |
374 | iopte_t *iopte; |
375 | + unsigned long flags, order, first_page; |
376 | void *ret; |
377 | int npages; |
378 | |
379 | - if (size <= 0 || sdev == NULL || dvma_addr == NULL) |
380 | - return NULL; |
381 | - |
382 | size = IO_PAGE_ALIGN(size); |
383 | order = get_order(size); |
384 | if (order >= 10) |
385 | return NULL; |
386 | + |
387 | first_page = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); |
388 | if (first_page == 0UL) |
389 | return NULL; |
390 | @@ -336,108 +237,121 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma |
391 | iommu = sdev->bus->iommu; |
392 | |
393 | spin_lock_irqsave(&iommu->lock, flags); |
394 | - iopte = alloc_consistent_cluster(iommu, size >> IO_PAGE_SHIFT); |
395 | - if (iopte == NULL) { |
396 | - spin_unlock_irqrestore(&iommu->lock, flags); |
397 | + iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT); |
398 | + spin_unlock_irqrestore(&iommu->lock, flags); |
399 | + |
400 | + if (unlikely(iopte == NULL)) { |
401 | free_pages(first_page, order); |
402 | return NULL; |
403 | } |
404 | |
405 | - /* Ok, we're committed at this point. */ |
406 | - *dvma_addr = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT); |
407 | + *dvma_addr = (MAP_BASE + |
408 | + ((iopte - iommu->page_table) << IO_PAGE_SHIFT)); |
409 | ret = (void *) first_page; |
410 | npages = size >> IO_PAGE_SHIFT; |
411 | + first_page = __pa(first_page); |
412 | while (npages--) { |
413 | - *iopte++ = __iopte(IOPTE_VALID | IOPTE_CACHE | IOPTE_WRITE | |
414 | - (__pa(first_page) & IOPTE_PAGE)); |
415 | + iopte_val(*iopte) = (IOPTE_VALID | IOPTE_CACHE | |
416 | + IOPTE_WRITE | |
417 | + (first_page & IOPTE_PAGE)); |
418 | + iopte++; |
419 | first_page += IO_PAGE_SIZE; |
420 | } |
421 | - iommu_flush(iommu, *dvma_addr, size >> IO_PAGE_SHIFT); |
422 | - spin_unlock_irqrestore(&iommu->lock, flags); |
423 | |
424 | return ret; |
425 | } |
426 | |
427 | void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_addr_t dvma) |
428 | { |
429 | - unsigned long order, npages; |
430 | struct sbus_iommu *iommu; |
431 | - |
432 | - if (size <= 0 || sdev == NULL || cpu == NULL) |
433 | - return; |
434 | + iopte_t *iopte; |
435 | + unsigned long flags, order, npages; |
436 | |
437 | npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; |
438 | iommu = sdev->bus->iommu; |
439 | + iopte = iommu->page_table + |
440 | + ((dvma - MAP_BASE) >> IO_PAGE_SHIFT); |
441 | + |
442 | + spin_lock_irqsave(&iommu->lock, flags); |
443 | + |
444 | + free_npages(iommu, dvma - MAP_BASE, npages); |
445 | |
446 | - spin_lock_irq(&iommu->lock); |
447 | - free_consistent_cluster(iommu, dvma, npages); |
448 | - iommu_flush(iommu, dvma, npages); |
449 | - spin_unlock_irq(&iommu->lock); |
450 | + spin_unlock_irqrestore(&iommu->lock, flags); |
451 | |
452 | order = get_order(size); |
453 | if (order < 10) |
454 | free_pages((unsigned long)cpu, order); |
455 | } |
456 | |
457 | -dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int dir) |
458 | +dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t sz, int direction) |
459 | { |
460 | - struct sbus_iommu *iommu = sdev->bus->iommu; |
461 | - unsigned long npages, pbase, flags; |
462 | - iopte_t *iopte; |
463 | - u32 dma_base, offset; |
464 | - unsigned long iopte_bits; |
465 | + struct sbus_iommu *iommu; |
466 | + iopte_t *base; |
467 | + unsigned long flags, npages, oaddr; |
468 | + unsigned long i, base_paddr; |
469 | + u32 bus_addr, ret; |
470 | + unsigned long iopte_protection; |
471 | + |
472 | + iommu = sdev->bus->iommu; |
473 | |
474 | - if (dir == SBUS_DMA_NONE) |
475 | + if (unlikely(direction == SBUS_DMA_NONE)) |
476 | BUG(); |
477 | |
478 | - pbase = (unsigned long) ptr; |
479 | - offset = (u32) (pbase & ~IO_PAGE_MASK); |
480 | - size = (IO_PAGE_ALIGN(pbase + size) - (pbase & IO_PAGE_MASK)); |
481 | - pbase = (unsigned long) __pa(pbase & IO_PAGE_MASK); |
482 | + oaddr = (unsigned long)ptr; |
483 | + npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); |
484 | + npages >>= IO_PAGE_SHIFT; |
485 | |
486 | spin_lock_irqsave(&iommu->lock, flags); |
487 | - npages = size >> IO_PAGE_SHIFT; |
488 | - iopte = alloc_streaming_cluster(iommu, npages); |
489 | - if (iopte == NULL) |
490 | - goto bad; |
491 | - dma_base = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT); |
492 | - npages = size >> IO_PAGE_SHIFT; |
493 | - iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE; |
494 | - if (dir != SBUS_DMA_TODEVICE) |
495 | - iopte_bits |= IOPTE_WRITE; |
496 | - while (npages--) { |
497 | - *iopte++ = __iopte(iopte_bits | (pbase & IOPTE_PAGE)); |
498 | - pbase += IO_PAGE_SIZE; |
499 | - } |
500 | - npages = size >> IO_PAGE_SHIFT; |
501 | + base = alloc_npages(iommu, npages); |
502 | spin_unlock_irqrestore(&iommu->lock, flags); |
503 | |
504 | - return (dma_base | offset); |
505 | + if (unlikely(!base)) |
506 | + BUG(); |
507 | |
508 | -bad: |
509 | - spin_unlock_irqrestore(&iommu->lock, flags); |
510 | - BUG(); |
511 | - return 0; |
512 | + bus_addr = (MAP_BASE + |
513 | + ((base - iommu->page_table) << IO_PAGE_SHIFT)); |
514 | + ret = bus_addr | (oaddr & ~IO_PAGE_MASK); |
515 | + base_paddr = __pa(oaddr & IO_PAGE_MASK); |
516 | + |
517 | + iopte_protection = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE; |
518 | + if (direction != SBUS_DMA_TODEVICE) |
519 | + iopte_protection |= IOPTE_WRITE; |
520 | + |
521 | + for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE) |
522 | + iopte_val(*base) = iopte_protection | base_paddr; |
523 | + |
524 | + return ret; |
525 | } |
526 | |
527 | -void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, int direction) |
528 | +void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction) |
529 | { |
530 | struct sbus_iommu *iommu = sdev->bus->iommu; |
531 | - u32 dma_base = dma_addr & IO_PAGE_MASK; |
532 | - unsigned long flags; |
533 | + iopte_t *base; |
534 | + unsigned long flags, npages, i; |
535 | + |
536 | + if (unlikely(direction == SBUS_DMA_NONE)) |
537 | + BUG(); |
538 | + |
539 | + npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); |
540 | + npages >>= IO_PAGE_SHIFT; |
541 | + base = iommu->page_table + |
542 | + ((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT); |
543 | |
544 | - size = (IO_PAGE_ALIGN(dma_addr + size) - dma_base); |
545 | + bus_addr &= IO_PAGE_MASK; |
546 | |
547 | spin_lock_irqsave(&iommu->lock, flags); |
548 | - free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); |
549 | - sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT, direction); |
550 | + sbus_strbuf_flush(iommu, bus_addr, npages, direction); |
551 | + for (i = 0; i < npages; i++) |
552 | + iopte_val(base[i]) = 0UL; |
553 | + free_npages(iommu, bus_addr - MAP_BASE, npages); |
554 | spin_unlock_irqrestore(&iommu->lock, flags); |
555 | } |
556 | |
557 | #define SG_ENT_PHYS_ADDRESS(SG) \ |
558 | (__pa(page_address((SG)->page)) + (SG)->offset) |
559 | |
560 | -static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, int nelems, unsigned long iopte_bits) |
561 | +static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, |
562 | + int nused, int nelems, unsigned long iopte_protection) |
563 | { |
564 | struct scatterlist *dma_sg = sg; |
565 | struct scatterlist *sg_end = sg + nelems; |
566 | @@ -462,7 +376,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, in |
567 | for (;;) { |
568 | unsigned long tmp; |
569 | |
570 | - tmp = (unsigned long) SG_ENT_PHYS_ADDRESS(sg); |
571 | + tmp = SG_ENT_PHYS_ADDRESS(sg); |
572 | len = sg->length; |
573 | if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) { |
574 | pteval = tmp & IO_PAGE_MASK; |
575 | @@ -478,7 +392,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, in |
576 | sg++; |
577 | } |
578 | |
579 | - pteval = ((pteval & IOPTE_PAGE) | iopte_bits); |
580 | + pteval = iopte_protection | (pteval & IOPTE_PAGE); |
581 | while (len > 0) { |
582 | *iopte++ = __iopte(pteval); |
583 | pteval += IO_PAGE_SIZE; |
584 | @@ -509,103 +423,111 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, in |
585 | } |
586 | } |
587 | |
588 | -int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int dir) |
589 | +int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction) |
590 | { |
591 | - struct sbus_iommu *iommu = sdev->bus->iommu; |
592 | - unsigned long flags, npages; |
593 | - iopte_t *iopte; |
594 | + struct sbus_iommu *iommu; |
595 | + unsigned long flags, npages, iopte_protection; |
596 | + iopte_t *base; |
597 | u32 dma_base; |
598 | struct scatterlist *sgtmp; |
599 | int used; |
600 | - unsigned long iopte_bits; |
601 | - |
602 | - if (dir == SBUS_DMA_NONE) |
603 | - BUG(); |
604 | |
605 | /* Fast path single entry scatterlists. */ |
606 | - if (nents == 1) { |
607 | - sg->dma_address = |
608 | + if (nelems == 1) { |
609 | + sglist->dma_address = |
610 | sbus_map_single(sdev, |
611 | - (page_address(sg->page) + sg->offset), |
612 | - sg->length, dir); |
613 | - sg->dma_length = sg->length; |
614 | + (page_address(sglist->page) + sglist->offset), |
615 | + sglist->length, direction); |
616 | + sglist->dma_length = sglist->length; |
617 | return 1; |
618 | } |
619 | |
620 | - npages = prepare_sg(sg, nents); |
621 | + iommu = sdev->bus->iommu; |
622 | + |
623 | + if (unlikely(direction == SBUS_DMA_NONE)) |
624 | + BUG(); |
625 | + |
626 | + npages = prepare_sg(sglist, nelems); |
627 | |
628 | spin_lock_irqsave(&iommu->lock, flags); |
629 | - iopte = alloc_streaming_cluster(iommu, npages); |
630 | - if (iopte == NULL) |
631 | - goto bad; |
632 | - dma_base = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT); |
633 | + base = alloc_npages(iommu, npages); |
634 | + spin_unlock_irqrestore(&iommu->lock, flags); |
635 | + |
636 | + if (unlikely(base == NULL)) |
637 | + BUG(); |
638 | + |
639 | + dma_base = MAP_BASE + |
640 | + ((base - iommu->page_table) << IO_PAGE_SHIFT); |
641 | |
642 | /* Normalize DVMA addresses. */ |
643 | - sgtmp = sg; |
644 | - used = nents; |
645 | + used = nelems; |
646 | |
647 | + sgtmp = sglist; |
648 | while (used && sgtmp->dma_length) { |
649 | sgtmp->dma_address += dma_base; |
650 | sgtmp++; |
651 | used--; |
652 | } |
653 | - used = nents - used; |
654 | + used = nelems - used; |
655 | |
656 | - iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE; |
657 | - if (dir != SBUS_DMA_TODEVICE) |
658 | - iopte_bits |= IOPTE_WRITE; |
659 | + iopte_protection = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE; |
660 | + if (direction != SBUS_DMA_TODEVICE) |
661 | + iopte_protection |= IOPTE_WRITE; |
662 | + |
663 | + fill_sg(base, sglist, used, nelems, iopte_protection); |
664 | |
665 | - fill_sg(iopte, sg, used, nents, iopte_bits); |
666 | #ifdef VERIFY_SG |
667 | - verify_sglist(sg, nents, iopte, npages); |
668 | + verify_sglist(sglist, nelems, base, npages); |
669 | #endif |
670 | - spin_unlock_irqrestore(&iommu->lock, flags); |
671 | |
672 | return used; |
673 | - |
674 | -bad: |
675 | - spin_unlock_irqrestore(&iommu->lock, flags); |
676 | - BUG(); |
677 | - return 0; |
678 | } |
679 | |
680 | -void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction) |
681 | +void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction) |
682 | { |
683 | - unsigned long size, flags; |
684 | struct sbus_iommu *iommu; |
685 | - u32 dvma_base; |
686 | - int i; |
687 | + iopte_t *base; |
688 | + unsigned long flags, i, npages; |
689 | + u32 bus_addr; |
690 | |
691 | - /* Fast path single entry scatterlists. */ |
692 | - if (nents == 1) { |
693 | - sbus_unmap_single(sdev, sg->dma_address, sg->dma_length, direction); |
694 | - return; |
695 | - } |
696 | + if (unlikely(direction == SBUS_DMA_NONE)) |
697 | + BUG(); |
698 | + |
699 | + iommu = sdev->bus->iommu; |
700 | + |
701 | + bus_addr = sglist->dma_address & IO_PAGE_MASK; |
702 | |
703 | - dvma_base = sg[0].dma_address & IO_PAGE_MASK; |
704 | - for (i = 0; i < nents; i++) { |
705 | - if (sg[i].dma_length == 0) |
706 | + for (i = 1; i < nelems; i++) |
707 | + if (sglist[i].dma_length == 0) |
708 | break; |
709 | - } |
710 | i--; |
711 | - size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - dvma_base; |
712 | + npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - |
713 | + bus_addr) >> IO_PAGE_SHIFT; |
714 | + |
715 | + base = iommu->page_table + |
716 | + ((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT); |
717 | |
718 | - iommu = sdev->bus->iommu; |
719 | spin_lock_irqsave(&iommu->lock, flags); |
720 | - free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); |
721 | - sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT, direction); |
722 | + sbus_strbuf_flush(iommu, bus_addr, npages, direction); |
723 | + for (i = 0; i < npages; i++) |
724 | + iopte_val(base[i]) = 0UL; |
725 | + free_npages(iommu, bus_addr - MAP_BASE, npages); |
726 | spin_unlock_irqrestore(&iommu->lock, flags); |
727 | } |
728 | |
729 | -void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t size, int direction) |
730 | +void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction) |
731 | { |
732 | - struct sbus_iommu *iommu = sdev->bus->iommu; |
733 | - unsigned long flags; |
734 | + struct sbus_iommu *iommu; |
735 | + unsigned long flags, npages; |
736 | + |
737 | + iommu = sdev->bus->iommu; |
738 | |
739 | - size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); |
740 | + npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); |
741 | + npages >>= IO_PAGE_SHIFT; |
742 | + bus_addr &= IO_PAGE_MASK; |
743 | |
744 | spin_lock_irqsave(&iommu->lock, flags); |
745 | - sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT, direction); |
746 | + sbus_strbuf_flush(iommu, bus_addr, npages, direction); |
747 | spin_unlock_irqrestore(&iommu->lock, flags); |
748 | } |
749 | |
750 | @@ -613,23 +535,25 @@ void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, dma_addr_t base, siz |
751 | { |
752 | } |
753 | |
754 | -void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction) |
755 | +void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction) |
756 | { |
757 | - struct sbus_iommu *iommu = sdev->bus->iommu; |
758 | - unsigned long flags, size; |
759 | - u32 base; |
760 | - int i; |
761 | + struct sbus_iommu *iommu; |
762 | + unsigned long flags, npages, i; |
763 | + u32 bus_addr; |
764 | + |
765 | + iommu = sdev->bus->iommu; |
766 | |
767 | - base = sg[0].dma_address & IO_PAGE_MASK; |
768 | - for (i = 0; i < nents; i++) { |
769 | - if (sg[i].dma_length == 0) |
770 | + bus_addr = sglist[0].dma_address & IO_PAGE_MASK; |
771 | + for (i = 0; i < nelems; i++) { |
772 | + if (!sglist[i].dma_length) |
773 | break; |
774 | } |
775 | i--; |
776 | - size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; |
777 | + npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) |
778 | + - bus_addr) >> IO_PAGE_SHIFT; |
779 | |
780 | spin_lock_irqsave(&iommu->lock, flags); |
781 | - sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT, direction); |
782 | + sbus_strbuf_flush(iommu, bus_addr, npages, direction); |
783 | spin_unlock_irqrestore(&iommu->lock, flags); |
784 | } |
785 | |
786 | @@ -1104,7 +1028,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) |
787 | struct linux_prom64_registers *pr; |
788 | struct device_node *dp; |
789 | struct sbus_iommu *iommu; |
790 | - unsigned long regs, tsb_base; |
791 | + unsigned long regs; |
792 | u64 control; |
793 | int i; |
794 | |
795 | @@ -1132,14 +1056,6 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) |
796 | |
797 | memset(iommu, 0, sizeof(*iommu)); |
798 | |
799 | - /* We start with no consistent mappings. */ |
800 | - iommu->lowest_consistent_map = CLUSTER_NPAGES; |
801 | - |
802 | - for (i = 0; i < NCLUSTERS; i++) { |
803 | - iommu->alloc_info[i].flush = 0; |
804 | - iommu->alloc_info[i].next = 0; |
805 | - } |
806 | - |
807 | /* Setup spinlock. */ |
808 | spin_lock_init(&iommu->lock); |
809 | |
810 | @@ -1159,25 +1075,13 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) |
811 | sbus->portid, regs); |
812 | |
813 | /* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */ |
814 | + sbus_iommu_table_init(iommu, IO_TSB_SIZE); |
815 | + |
816 | control = upa_readq(iommu->iommu_regs + IOMMU_CONTROL); |
817 | control = ((7UL << 16UL) | |
818 | (0UL << 2UL) | |
819 | (1UL << 1UL) | |
820 | (1UL << 0UL)); |
821 | - |
822 | - /* Using the above configuration we need 1MB iommu page |
823 | - * table (128K ioptes * 8 bytes per iopte). This is |
824 | - * page order 7 on UltraSparc. |
825 | - */ |
826 | - tsb_base = __get_free_pages(GFP_ATOMIC, get_order(IO_TSB_SIZE)); |
827 | - if (tsb_base == 0UL) { |
828 | - prom_printf("sbus_iommu_init: Fatal error, cannot alloc TSB table.\n"); |
829 | - prom_halt(); |
830 | - } |
831 | - |
832 | - iommu->page_table = (iopte_t *) tsb_base; |
833 | - memset(iommu->page_table, 0, IO_TSB_SIZE); |
834 | - |
835 | upa_writeq(control, iommu->iommu_regs + IOMMU_CONTROL); |
836 | |
837 | /* Clean out any cruft in the IOMMU using |
838 | @@ -1195,7 +1099,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) |
839 | upa_readq(iommu->sbus_control_reg); |
840 | |
841 | /* Give the TSB to SYSIO. */ |
842 | - upa_writeq(__pa(tsb_base), iommu->iommu_regs + IOMMU_TSBBASE); |
843 | + upa_writeq(__pa(iommu->page_table), iommu->iommu_regs + IOMMU_TSBBASE); |
844 | |
845 | /* Setup streaming buffer, DE=1 SB_EN=1 */ |
846 | control = (1UL << 1UL) | (1UL << 0UL); |
847 | diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S |
848 | index c09ab4b..010a737 100644 |
849 | --- a/arch/sparc64/kernel/sys32.S |
850 | +++ b/arch/sparc64/kernel/sys32.S |
851 | @@ -91,7 +91,6 @@ SIGN1(sys32_select, compat_sys_select, %o0) |
852 | SIGN1(sys32_mkdir, sys_mkdir, %o1) |
853 | SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) |
854 | SIGN1(sys32_sysfs, compat_sys_sysfs, %o0) |
855 | -SIGN3(sys32_ipc, compat_sys_ipc, %o1, %o2, %o3) |
856 | SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1) |
857 | SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1) |
858 | SIGN1(sys32_prctl, sys_prctl, %o0) |
859 | diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S |
860 | index 9a80267..46f870b 100644 |
861 | --- a/arch/sparc64/kernel/systbls.S |
862 | +++ b/arch/sparc64/kernel/systbls.S |
863 | @@ -62,7 +62,7 @@ sys_call_table32: |
864 | /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir |
865 | .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 |
866 | /*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, sys32_sysinfo |
867 | - .word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex |
868 | + .word compat_sys_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex |
869 | /*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid |
870 | .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 |
871 | /*230*/ .word sys32_select, compat_sys_time, sys32_splice, compat_sys_stime, compat_sys_statfs64 |
872 | diff --git a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S |
873 | index d6ff88f..6090516 100644 |
874 | --- a/arch/x86_64/boot/video.S |
875 | +++ b/arch/x86_64/boot/video.S |
876 | @@ -571,6 +571,16 @@ setr1: lodsw |
877 | jmp _m_s |
878 | |
879 | check_vesa: |
880 | +#ifdef CONFIG_FIRMWARE_EDID |
881 | + leaw modelist+1024, %di |
882 | + movw $0x4f00, %ax |
883 | + int $0x10 |
884 | + cmpw $0x004f, %ax |
885 | + jnz setbad |
886 | + |
887 | + movw 4(%di), %ax |
888 | + movw %ax, vbe_version |
889 | +#endif |
890 | leaw modelist+1024, %di |
891 | subb $VIDEO_FIRST_VESA>>8, %bh |
892 | movw %bx, %cx # Get mode information structure |
893 | @@ -1945,6 +1955,9 @@ store_edid: |
894 | rep |
895 | stosl |
896 | |
897 | + cmpw $0x0200, vbe_version # only do EDID on >= VBE2.0 |
898 | + jl no_edid |
899 | + |
900 | pushw %es # save ES |
901 | xorw %di, %di # Report Capability |
902 | pushw %di |
903 | @@ -1987,6 +2000,7 @@ do_restore: .byte 0 # Screen contents altered during mode change |
904 | svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes |
905 | graphic_mode: .byte 0 # Graphic mode with a linear frame buffer |
906 | dac_size: .byte 6 # DAC bit depth |
907 | +vbe_version: .word 0 # VBE bios version |
908 | |
909 | # Status messages |
910 | keymsg: .ascii "Press <RETURN> to see video modes available, " |
911 | diff --git a/arch/x86_64/kernel/k8.c b/arch/x86_64/kernel/k8.c |
912 | index 6416682..bc11b32 100644 |
913 | --- a/arch/x86_64/kernel/k8.c |
914 | +++ b/arch/x86_64/kernel/k8.c |
915 | @@ -61,8 +61,8 @@ int cache_k8_northbridges(void) |
916 | dev = NULL; |
917 | i = 0; |
918 | while ((dev = next_k8_northbridge(dev)) != NULL) { |
919 | - k8_northbridges[i++] = dev; |
920 | - pci_read_config_dword(dev, 0x9c, &flush_words[i]); |
921 | + k8_northbridges[i] = dev; |
922 | + pci_read_config_dword(dev, 0x9c, &flush_words[i++]); |
923 | } |
924 | k8_northbridges[i] = NULL; |
925 | return 0; |
926 | diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c |
927 | index 07b7062..0280fe6 100644 |
928 | --- a/block/cfq-iosched.c |
929 | +++ b/block/cfq-iosched.c |
930 | @@ -462,6 +462,12 @@ static void cfq_add_rq_rb(struct request *rq) |
931 | |
932 | if (!cfq_cfqq_on_rr(cfqq)) |
933 | cfq_add_cfqq_rr(cfqd, cfqq); |
934 | + |
935 | + /* |
936 | + * check if this request is a better next-serve candidate |
937 | + */ |
938 | + cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq); |
939 | + BUG_ON(!cfqq->next_rq); |
940 | } |
941 | |
942 | static inline void |
943 | @@ -1623,12 +1629,6 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, |
944 | cfqq->meta_pending++; |
945 | |
946 | /* |
947 | - * check if this request is a better next-serve candidate)) { |
948 | - */ |
949 | - cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq); |
950 | - BUG_ON(!cfqq->next_rq); |
951 | - |
952 | - /* |
953 | * we never wait for an async request and we don't allow preemption |
954 | * of an async request. so just return early |
955 | */ |
956 | diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c |
957 | index 84787ce..ed1d380 100644 |
958 | --- a/drivers/char/agp/intel-agp.c |
959 | +++ b/drivers/char/agp/intel-agp.c |
960 | @@ -405,9 +405,8 @@ static void intel_i830_init_gtt_entries(void) |
961 | |
962 | if (IS_I965) { |
963 | u32 pgetbl_ctl; |
964 | + pgetbl_ctl = readl(intel_i830_private.registers+I810_PGETBL_CTL); |
965 | |
966 | - pci_read_config_dword(agp_bridge->dev, I810_PGETBL_CTL, |
967 | - &pgetbl_ctl); |
968 | /* The 965 has a field telling us the size of the GTT, |
969 | * which may be larger than what is necessary to map the |
970 | * aperture. |
971 | diff --git a/drivers/char/mem.c b/drivers/char/mem.c |
972 | index f5c160c..5f06696 100644 |
973 | --- a/drivers/char/mem.c |
974 | +++ b/drivers/char/mem.c |
975 | @@ -248,7 +248,7 @@ static unsigned long get_unmapped_area_mem(struct file *file, |
976 | { |
977 | if (!valid_mmap_phys_addr_range(pgoff, len)) |
978 | return (unsigned long) -EINVAL; |
979 | - return pgoff; |
980 | + return pgoff << PAGE_SHIFT; |
981 | } |
982 | |
983 | /* can't do an in-place private mapping if there's no MMU */ |
984 | diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c |
985 | index dc8368e..60740a1 100644 |
986 | --- a/drivers/char/vt_ioctl.c |
987 | +++ b/drivers/char/vt_ioctl.c |
988 | @@ -1038,10 +1038,22 @@ int vt_waitactive(int vt) |
989 | |
990 | add_wait_queue(&vt_activate_queue, &wait); |
991 | for (;;) { |
992 | - set_current_state(TASK_INTERRUPTIBLE); |
993 | retval = 0; |
994 | - if (vt == fg_console) |
995 | + |
996 | + /* |
997 | + * Synchronize with redraw_screen(). By acquiring the console |
998 | + * semaphore we make sure that the console switch is completed |
999 | + * before we return. If we didn't wait for the semaphore, we |
1000 | + * could return at a point where fg_console has already been |
1001 | + * updated, but the console switch hasn't been completed. |
1002 | + */ |
1003 | + acquire_console_sem(); |
1004 | + set_current_state(TASK_INTERRUPTIBLE); |
1005 | + if (vt == fg_console) { |
1006 | + release_console_sem(); |
1007 | break; |
1008 | + } |
1009 | + release_console_sem(); |
1010 | retval = -EINTR; |
1011 | if (signal_pending(current)) |
1012 | break; |
1013 | diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c |
1014 | index 1ecad3e..f6fb5b3 100644 |
1015 | --- a/drivers/hid/hid-core.c |
1016 | +++ b/drivers/hid/hid-core.c |
1017 | @@ -876,10 +876,6 @@ static void hid_output_field(struct hid_field *field, __u8 *data) |
1018 | unsigned size = field->report_size; |
1019 | unsigned n; |
1020 | |
1021 | - /* make sure the unused bits in the last byte are zeros */ |
1022 | - if (count > 0 && size > 0) |
1023 | - data[(count*size-1)/8] = 0; |
1024 | - |
1025 | for (n = 0; n < count; n++) { |
1026 | if (field->logical_minimum < 0) /* signed values */ |
1027 | implement(data, offset + n * size, size, s32ton(field->value[n], size)); |
1028 | diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c |
1029 | index 212a155..b9d5dd4 100644 |
1030 | --- a/drivers/hwmon/w83627ehf.c |
1031 | +++ b/drivers/hwmon/w83627ehf.c |
1032 | @@ -389,7 +389,7 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr) |
1033 | break; |
1034 | case 4: |
1035 | reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0x73) |
1036 | - | ((data->fan_div[4] & 0x03) << 3) |
1037 | + | ((data->fan_div[4] & 0x03) << 2) |
1038 | | ((data->fan_div[4] & 0x04) << 5); |
1039 | w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg); |
1040 | break; |
1041 | @@ -453,9 +453,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) |
1042 | time */ |
1043 | if (data->fan[i] == 0xff |
1044 | && data->fan_div[i] < 0x07) { |
1045 | - dev_dbg(&client->dev, "Increasing fan %d " |
1046 | + dev_dbg(&client->dev, "Increasing fan%d " |
1047 | "clock divider from %u to %u\n", |
1048 | - i, div_from_reg(data->fan_div[i]), |
1049 | + i + 1, div_from_reg(data->fan_div[i]), |
1050 | div_from_reg(data->fan_div[i] + 1)); |
1051 | data->fan_div[i]++; |
1052 | w83627ehf_write_fan_div(client, i); |
1053 | diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c |
1054 | index f71ffa8..58012ac 100644 |
1055 | --- a/drivers/infiniband/hw/mthca/mthca_mr.c |
1056 | +++ b/drivers/infiniband/hw/mthca/mthca_mr.c |
1057 | @@ -751,6 +751,7 @@ void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr) |
1058 | |
1059 | key = arbel_key_to_hw_index(fmr->ibmr.lkey); |
1060 | key &= dev->limits.num_mpts - 1; |
1061 | + key = adjust_key(dev, key); |
1062 | fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key); |
1063 | |
1064 | fmr->maps = 0; |
1065 | diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c |
1066 | index 22c426c..1b5e189 100644 |
1067 | --- a/drivers/kvm/mmu.c |
1068 | +++ b/drivers/kvm/mmu.c |
1069 | @@ -131,7 +131,7 @@ static int dbg = 1; |
1070 | (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1)) |
1071 | |
1072 | |
1073 | -#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & PAGE_MASK) |
1074 | +#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) |
1075 | #define PT64_DIR_BASE_ADDR_MASK \ |
1076 | (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1)) |
1077 | |
1078 | @@ -406,8 +406,8 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) |
1079 | spte = desc->shadow_ptes[0]; |
1080 | } |
1081 | BUG_ON(!spte); |
1082 | - BUG_ON((*spte & PT64_BASE_ADDR_MASK) != |
1083 | - page_to_pfn(page) << PAGE_SHIFT); |
1084 | + BUG_ON((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT |
1085 | + != page_to_pfn(page)); |
1086 | BUG_ON(!(*spte & PT_PRESENT_MASK)); |
1087 | BUG_ON(!(*spte & PT_WRITABLE_MASK)); |
1088 | rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); |
1089 | @@ -1093,22 +1093,40 @@ out: |
1090 | return r; |
1091 | } |
1092 | |
1093 | +static void mmu_pre_write_zap_pte(struct kvm_vcpu *vcpu, |
1094 | + struct kvm_mmu_page *page, |
1095 | + u64 *spte) |
1096 | +{ |
1097 | + u64 pte; |
1098 | + struct kvm_mmu_page *child; |
1099 | + |
1100 | + pte = *spte; |
1101 | + if (is_present_pte(pte)) { |
1102 | + if (page->role.level == PT_PAGE_TABLE_LEVEL) |
1103 | + rmap_remove(vcpu, spte); |
1104 | + else { |
1105 | + child = page_header(pte & PT64_BASE_ADDR_MASK); |
1106 | + mmu_page_remove_parent_pte(vcpu, child, spte); |
1107 | + } |
1108 | + } |
1109 | + *spte = 0; |
1110 | +} |
1111 | + |
1112 | void kvm_mmu_pre_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes) |
1113 | { |
1114 | gfn_t gfn = gpa >> PAGE_SHIFT; |
1115 | struct kvm_mmu_page *page; |
1116 | - struct kvm_mmu_page *child; |
1117 | struct hlist_node *node, *n; |
1118 | struct hlist_head *bucket; |
1119 | unsigned index; |
1120 | u64 *spte; |
1121 | - u64 pte; |
1122 | unsigned offset = offset_in_page(gpa); |
1123 | unsigned pte_size; |
1124 | unsigned page_offset; |
1125 | unsigned misaligned; |
1126 | int level; |
1127 | int flooded = 0; |
1128 | + int npte; |
1129 | |
1130 | pgprintk("%s: gpa %llx bytes %d\n", __FUNCTION__, gpa, bytes); |
1131 | if (gfn == vcpu->last_pt_write_gfn) { |
1132 | @@ -1144,22 +1162,27 @@ void kvm_mmu_pre_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes) |
1133 | } |
1134 | page_offset = offset; |
1135 | level = page->role.level; |
1136 | + npte = 1; |
1137 | if (page->role.glevels == PT32_ROOT_LEVEL) { |
1138 | - page_offset <<= 1; /* 32->64 */ |
1139 | + page_offset <<= 1; /* 32->64 */ |
1140 | + /* |
1141 | + * A 32-bit pde maps 4MB while the shadow pdes map |
1142 | + * only 2MB. So we need to double the offset again |
1143 | + * and zap two pdes instead of one. |
1144 | + */ |
1145 | + if (level == PT32_ROOT_LEVEL) { |
1146 | + page_offset &= ~7; /* kill rounding error */ |
1147 | + page_offset <<= 1; |
1148 | + npte = 2; |
1149 | + } |
1150 | page_offset &= ~PAGE_MASK; |
1151 | } |
1152 | spte = __va(page->page_hpa); |
1153 | spte += page_offset / sizeof(*spte); |
1154 | - pte = *spte; |
1155 | - if (is_present_pte(pte)) { |
1156 | - if (level == PT_PAGE_TABLE_LEVEL) |
1157 | - rmap_remove(vcpu, spte); |
1158 | - else { |
1159 | - child = page_header(pte & PT64_BASE_ADDR_MASK); |
1160 | - mmu_page_remove_parent_pte(vcpu, child, spte); |
1161 | - } |
1162 | + while (npte--) { |
1163 | + mmu_pre_write_zap_pte(vcpu, page, spte); |
1164 | + ++spte; |
1165 | } |
1166 | - *spte = 0; |
1167 | } |
1168 | } |
1169 | |
1170 | diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c |
1171 | index 0252ef9..0e0401d 100644 |
1172 | --- a/drivers/pci/probe.c |
1173 | +++ b/drivers/pci/probe.c |
1174 | @@ -639,34 +639,7 @@ static void pci_read_irq(struct pci_dev *dev) |
1175 | dev->irq = irq; |
1176 | } |
1177 | |
1178 | -static void change_legacy_io_resource(struct pci_dev * dev, unsigned index, |
1179 | - unsigned start, unsigned end) |
1180 | -{ |
1181 | - unsigned base = start & PCI_BASE_ADDRESS_IO_MASK; |
1182 | - unsigned len = (end | ~PCI_BASE_ADDRESS_IO_MASK) - base + 1; |
1183 | - |
1184 | - /* |
1185 | - * Some X versions get confused when the BARs reported through |
1186 | - * /sys or /proc differ from those seen in config space, thus |
1187 | - * try to update the config space values, too. |
1188 | - */ |
1189 | - if (!(pci_resource_flags(dev, index) & IORESOURCE_IO)) |
1190 | - printk(KERN_WARNING "%s: cannot adjust BAR%u (not I/O)\n", |
1191 | - pci_name(dev), index); |
1192 | - else if (pci_resource_len(dev, index) != len) |
1193 | - printk(KERN_WARNING "%s: cannot adjust BAR%u (size %04X)\n", |
1194 | - pci_name(dev), index, (unsigned)pci_resource_len(dev, index)); |
1195 | - else { |
1196 | - printk(KERN_INFO "%s: trying to change BAR%u from %04X to %04X\n", |
1197 | - pci_name(dev), index, |
1198 | - (unsigned)pci_resource_start(dev, index), base); |
1199 | - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + index * 4, base); |
1200 | - } |
1201 | - pci_resource_start(dev, index) = start; |
1202 | - pci_resource_end(dev, index) = end; |
1203 | - pci_resource_flags(dev, index) = |
1204 | - IORESOURCE_IO | IORESOURCE_PCI_FIXED | PCI_BASE_ADDRESS_SPACE_IO; |
1205 | -} |
1206 | +#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) |
1207 | |
1208 | /** |
1209 | * pci_setup_device - fill in class and map information of a device |
1210 | @@ -719,12 +692,20 @@ static int pci_setup_device(struct pci_dev * dev) |
1211 | u8 progif; |
1212 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); |
1213 | if ((progif & 1) == 0) { |
1214 | - change_legacy_io_resource(dev, 0, 0x1F0, 0x1F7); |
1215 | - change_legacy_io_resource(dev, 1, 0x3F6, 0x3F6); |
1216 | + dev->resource[0].start = 0x1F0; |
1217 | + dev->resource[0].end = 0x1F7; |
1218 | + dev->resource[0].flags = LEGACY_IO_RESOURCE; |
1219 | + dev->resource[1].start = 0x3F6; |
1220 | + dev->resource[1].end = 0x3F6; |
1221 | + dev->resource[1].flags = LEGACY_IO_RESOURCE; |
1222 | } |
1223 | if ((progif & 4) == 0) { |
1224 | - change_legacy_io_resource(dev, 2, 0x170, 0x177); |
1225 | - change_legacy_io_resource(dev, 3, 0x376, 0x376); |
1226 | + dev->resource[2].start = 0x170; |
1227 | + dev->resource[2].end = 0x177; |
1228 | + dev->resource[2].flags = LEGACY_IO_RESOURCE; |
1229 | + dev->resource[3].start = 0x376; |
1230 | + dev->resource[3].end = 0x376; |
1231 | + dev->resource[3].flags = LEGACY_IO_RESOURCE; |
1232 | } |
1233 | } |
1234 | break; |
1235 | diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c |
1236 | index e1b44d6..2981ceb 100644 |
1237 | --- a/drivers/scsi/3w-xxxx.c |
1238 | +++ b/drivers/scsi/3w-xxxx.c |
1239 | @@ -1864,10 +1864,17 @@ static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id) |
1240 | /* This function will handle the request sense scsi command */ |
1241 | static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id) |
1242 | { |
1243 | + char request_buffer[18]; |
1244 | + |
1245 | dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n"); |
1246 | |
1247 | - /* For now we just zero the request buffer */ |
1248 | - memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen); |
1249 | + memset(request_buffer, 0, sizeof(request_buffer)); |
1250 | + request_buffer[0] = 0x70; /* Immediate fixed format */ |
1251 | + request_buffer[7] = 10; /* minimum size per SPC: 18 bytes */ |
1252 | + /* leave all other fields zero, giving effectively NO_SENSE return */ |
1253 | + tw_transfer_internal(tw_dev, request_id, request_buffer, |
1254 | + sizeof(request_buffer)); |
1255 | + |
1256 | tw_dev->state[request_id] = TW_S_COMPLETED; |
1257 | tw_state_request_finish(tw_dev, request_id); |
1258 | |
1259 | diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c |
1260 | index 9b827ce..9f10689 100644 |
1261 | --- a/drivers/scsi/qlogicpti.c |
1262 | +++ b/drivers/scsi/qlogicpti.c |
1263 | @@ -1281,7 +1281,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) |
1264 | (struct scatterlist *)Cmnd->request_buffer, |
1265 | Cmnd->use_sg, |
1266 | Cmnd->sc_data_direction); |
1267 | - } else { |
1268 | + } else if (Cmnd->request_bufflen) { |
1269 | sbus_unmap_single(qpti->sdev, |
1270 | (__u32)((unsigned long)Cmnd->SCp.ptr), |
1271 | Cmnd->request_bufflen, |
1272 | diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c |
1273 | index 5261f0a..2e542b9 100644 |
1274 | --- a/drivers/serial/8250.c |
1275 | +++ b/drivers/serial/8250.c |
1276 | @@ -1289,7 +1289,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up) |
1277 | { |
1278 | unsigned int status = serial_in(up, UART_MSR); |
1279 | |
1280 | - if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI) { |
1281 | + if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && |
1282 | + up->port.info != NULL) { |
1283 | if (status & UART_MSR_TERI) |
1284 | up->port.icount.rng++; |
1285 | if (status & UART_MSR_DDSR) |
1286 | diff --git a/fs/exec.c b/fs/exec.c |
1287 | index 11fe93f..0f8573a 100644 |
1288 | --- a/fs/exec.c |
1289 | +++ b/fs/exec.c |
1290 | @@ -1246,13 +1246,17 @@ EXPORT_SYMBOL(set_binfmt); |
1291 | * name into corename, which must have space for at least |
1292 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. |
1293 | */ |
1294 | -static void format_corename(char *corename, const char *pattern, long signr) |
1295 | +static int format_corename(char *corename, const char *pattern, long signr) |
1296 | { |
1297 | const char *pat_ptr = pattern; |
1298 | char *out_ptr = corename; |
1299 | char *const out_end = corename + CORENAME_MAX_SIZE; |
1300 | int rc; |
1301 | int pid_in_pattern = 0; |
1302 | + int ispipe = 0; |
1303 | + |
1304 | + if (*pattern == '|') |
1305 | + ispipe = 1; |
1306 | |
1307 | /* Repeat as long as we have more pattern to process and more output |
1308 | space */ |
1309 | @@ -1343,8 +1347,8 @@ static void format_corename(char *corename, const char *pattern, long signr) |
1310 | * |
1311 | * If core_pattern does not include a %p (as is the default) |
1312 | * and core_uses_pid is set, then .%pid will be appended to |
1313 | - * the filename */ |
1314 | - if (!pid_in_pattern |
1315 | + * the filename. Do not do this for piped commands. */ |
1316 | + if (!ispipe && !pid_in_pattern |
1317 | && (core_uses_pid || atomic_read(¤t->mm->mm_users) != 1)) { |
1318 | rc = snprintf(out_ptr, out_end - out_ptr, |
1319 | ".%d", current->tgid); |
1320 | @@ -1352,8 +1356,9 @@ static void format_corename(char *corename, const char *pattern, long signr) |
1321 | goto out; |
1322 | out_ptr += rc; |
1323 | } |
1324 | - out: |
1325 | +out: |
1326 | *out_ptr = 0; |
1327 | + return ispipe; |
1328 | } |
1329 | |
1330 | static void zap_process(struct task_struct *start) |
1331 | @@ -1504,16 +1509,15 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) |
1332 | * uses lock_kernel() |
1333 | */ |
1334 | lock_kernel(); |
1335 | - format_corename(corename, core_pattern, signr); |
1336 | + ispipe = format_corename(corename, core_pattern, signr); |
1337 | unlock_kernel(); |
1338 | - if (corename[0] == '|') { |
1339 | + if (ispipe) { |
1340 | /* SIGPIPE can happen, but it's just never processed */ |
1341 | if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) { |
1342 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1343 | corename); |
1344 | goto fail_unlock; |
1345 | } |
1346 | - ispipe = 1; |
1347 | } else |
1348 | file = filp_open(corename, |
1349 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1350 | diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c |
1351 | index d9ba8cb..80b4264 100644 |
1352 | --- a/fs/nfs/dir.c |
1353 | +++ b/fs/nfs/dir.c |
1354 | @@ -1659,7 +1659,8 @@ go_ahead: |
1355 | * ... prune child dentries and writebacks if needed. |
1356 | */ |
1357 | if (atomic_read(&old_dentry->d_count) > 1) { |
1358 | - nfs_wb_all(old_inode); |
1359 | + if (S_ISREG(old_inode->i_mode)) |
1360 | + nfs_wb_all(old_inode); |
1361 | shrink_dcache_parent(old_dentry); |
1362 | } |
1363 | nfs_inode_return_delegation(old_inode); |
1364 | diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c |
1365 | index 5a83e8d..e8cacef 100644 |
1366 | --- a/fs/nfs/inode.c |
1367 | +++ b/fs/nfs/inode.c |
1368 | @@ -334,8 +334,10 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) |
1369 | lock_kernel(); |
1370 | nfs_begin_data_update(inode); |
1371 | /* Write all dirty data */ |
1372 | - filemap_write_and_wait(inode->i_mapping); |
1373 | - nfs_wb_all(inode); |
1374 | + if (S_ISREG(inode->i_mode)) { |
1375 | + filemap_write_and_wait(inode->i_mapping); |
1376 | + nfs_wb_all(inode); |
1377 | + } |
1378 | /* |
1379 | * Return any delegations if we're going to change ACLs |
1380 | */ |
1381 | diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c |
1382 | index f01389f..c8178b7 100644 |
1383 | --- a/fs/reiserfs/xattr.c |
1384 | +++ b/fs/reiserfs/xattr.c |
1385 | @@ -54,82 +54,48 @@ |
1386 | static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char |
1387 | *prefix); |
1388 | |
1389 | -static struct dentry *create_xa_root(struct super_block *sb) |
1390 | +/* Returns the dentry referring to the root of the extended attribute |
1391 | + * directory tree. If it has already been retrieved, it is used. If it |
1392 | + * hasn't been created and the flags indicate creation is allowed, we |
1393 | + * attempt to create it. On error, we return a pointer-encoded error. |
1394 | + */ |
1395 | +static struct dentry *get_xa_root(struct super_block *sb, int flags) |
1396 | { |
1397 | struct dentry *privroot = dget(REISERFS_SB(sb)->priv_root); |
1398 | struct dentry *xaroot; |
1399 | |
1400 | /* This needs to be created at mount-time */ |
1401 | if (!privroot) |
1402 | - return ERR_PTR(-EOPNOTSUPP); |
1403 | + return ERR_PTR(-ENODATA); |
1404 | |
1405 | - xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); |
1406 | - if (IS_ERR(xaroot)) { |
1407 | + mutex_lock(&privroot->d_inode->i_mutex); |
1408 | + if (REISERFS_SB(sb)->xattr_root) { |
1409 | + xaroot = dget(REISERFS_SB(sb)->xattr_root); |
1410 | goto out; |
1411 | - } else if (!xaroot->d_inode) { |
1412 | - int err; |
1413 | - mutex_lock(&privroot->d_inode->i_mutex); |
1414 | - err = |
1415 | - privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot, |
1416 | - 0700); |
1417 | - mutex_unlock(&privroot->d_inode->i_mutex); |
1418 | - |
1419 | - if (err) { |
1420 | - dput(xaroot); |
1421 | - dput(privroot); |
1422 | - return ERR_PTR(err); |
1423 | - } |
1424 | - REISERFS_SB(sb)->xattr_root = dget(xaroot); |
1425 | } |
1426 | |
1427 | - out: |
1428 | - dput(privroot); |
1429 | - return xaroot; |
1430 | -} |
1431 | - |
1432 | -/* This will return a dentry, or error, refering to the xa root directory. |
1433 | - * If the xa root doesn't exist yet, the dentry will be returned without |
1434 | - * an associated inode. This dentry can be used with ->mkdir to create |
1435 | - * the xa directory. */ |
1436 | -static struct dentry *__get_xa_root(struct super_block *s) |
1437 | -{ |
1438 | - struct dentry *privroot = dget(REISERFS_SB(s)->priv_root); |
1439 | - struct dentry *xaroot = NULL; |
1440 | - |
1441 | - if (IS_ERR(privroot) || !privroot) |
1442 | - return privroot; |
1443 | - |
1444 | xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); |
1445 | if (IS_ERR(xaroot)) { |
1446 | goto out; |
1447 | } else if (!xaroot->d_inode) { |
1448 | - dput(xaroot); |
1449 | - xaroot = NULL; |
1450 | - goto out; |
1451 | + int err = -ENODATA; |
1452 | + if (flags == 0 || flags & XATTR_CREATE) |
1453 | + err = privroot->d_inode->i_op->mkdir(privroot->d_inode, |
1454 | + xaroot, 0700); |
1455 | + if (err) { |
1456 | + dput(xaroot); |
1457 | + xaroot = ERR_PTR(err); |
1458 | + goto out; |
1459 | + } |
1460 | } |
1461 | - |
1462 | - REISERFS_SB(s)->xattr_root = dget(xaroot); |
1463 | + REISERFS_SB(sb)->xattr_root = dget(xaroot); |
1464 | |
1465 | out: |
1466 | + mutex_unlock(&privroot->d_inode->i_mutex); |
1467 | dput(privroot); |
1468 | return xaroot; |
1469 | } |
1470 | |
1471 | -/* Returns the dentry (or NULL) referring to the root of the extended |
1472 | - * attribute directory tree. If it has already been retrieved, it is used. |
1473 | - * Otherwise, we attempt to retrieve it from disk. It may also return |
1474 | - * a pointer-encoded error. |
1475 | - */ |
1476 | -static inline struct dentry *get_xa_root(struct super_block *s) |
1477 | -{ |
1478 | - struct dentry *dentry = dget(REISERFS_SB(s)->xattr_root); |
1479 | - |
1480 | - if (!dentry) |
1481 | - dentry = __get_xa_root(s); |
1482 | - |
1483 | - return dentry; |
1484 | -} |
1485 | - |
1486 | /* Opens the directory corresponding to the inode's extended attribute store. |
1487 | * If flags allow, the tree to the directory may be created. If creation is |
1488 | * prohibited, -ENODATA is returned. */ |
1489 | @@ -138,21 +104,11 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags) |
1490 | struct dentry *xaroot, *xadir; |
1491 | char namebuf[17]; |
1492 | |
1493 | - xaroot = get_xa_root(inode->i_sb); |
1494 | - if (IS_ERR(xaroot)) { |
1495 | + xaroot = get_xa_root(inode->i_sb, flags); |
1496 | + if (IS_ERR(xaroot)) |
1497 | return xaroot; |
1498 | - } else if (!xaroot) { |
1499 | - if (flags == 0 || flags & XATTR_CREATE) { |
1500 | - xaroot = create_xa_root(inode->i_sb); |
1501 | - if (IS_ERR(xaroot)) |
1502 | - return xaroot; |
1503 | - } |
1504 | - if (!xaroot) |
1505 | - return ERR_PTR(-ENODATA); |
1506 | - } |
1507 | |
1508 | /* ok, we have xaroot open */ |
1509 | - |
1510 | snprintf(namebuf, sizeof(namebuf), "%X.%X", |
1511 | le32_to_cpu(INODE_PKEY(inode)->k_objectid), |
1512 | inode->i_generation); |
1513 | @@ -821,7 +777,7 @@ int reiserfs_delete_xattrs(struct inode *inode) |
1514 | |
1515 | /* Leftovers besides . and .. -- that's not good. */ |
1516 | if (dir->d_inode->i_nlink <= 2) { |
1517 | - root = get_xa_root(inode->i_sb); |
1518 | + root = get_xa_root(inode->i_sb, XATTR_REPLACE); |
1519 | reiserfs_write_lock_xattrs(inode->i_sb); |
1520 | err = vfs_rmdir(root->d_inode, dir); |
1521 | reiserfs_write_unlock_xattrs(inode->i_sb); |
1522 | diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h |
1523 | index 3fced47..a46104a 100644 |
1524 | --- a/include/linux/taskstats.h |
1525 | +++ b/include/linux/taskstats.h |
1526 | @@ -31,7 +31,7 @@ |
1527 | */ |
1528 | |
1529 | |
1530 | -#define TASKSTATS_VERSION 3 |
1531 | +#define TASKSTATS_VERSION 4 |
1532 | #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN |
1533 | * in linux/sched.h */ |
1534 | |
1535 | @@ -66,7 +66,7 @@ struct taskstats { |
1536 | /* Delay waiting for cpu, while runnable |
1537 | * count, delay_total NOT updated atomically |
1538 | */ |
1539 | - __u64 cpu_count; |
1540 | + __u64 cpu_count __attribute__((aligned(8))); |
1541 | __u64 cpu_delay_total; |
1542 | |
1543 | /* Following four fields atomically updated using task->delays->lock */ |
1544 | @@ -101,14 +101,17 @@ struct taskstats { |
1545 | |
1546 | /* Basic Accounting Fields start */ |
1547 | char ac_comm[TS_COMM_LEN]; /* Command name */ |
1548 | - __u8 ac_sched; /* Scheduling discipline */ |
1549 | + __u8 ac_sched __attribute__((aligned(8))); |
1550 | + /* Scheduling discipline */ |
1551 | __u8 ac_pad[3]; |
1552 | - __u32 ac_uid; /* User ID */ |
1553 | + __u32 ac_uid __attribute__((aligned(8))); |
1554 | + /* User ID */ |
1555 | __u32 ac_gid; /* Group ID */ |
1556 | __u32 ac_pid; /* Process ID */ |
1557 | __u32 ac_ppid; /* Parent process ID */ |
1558 | __u32 ac_btime; /* Begin time [sec since 1970] */ |
1559 | - __u64 ac_etime; /* Elapsed time [usec] */ |
1560 | + __u64 ac_etime __attribute__((aligned(8))); |
1561 | + /* Elapsed time [usec] */ |
1562 | __u64 ac_utime; /* User CPU time [usec] */ |
1563 | __u64 ac_stime; /* SYstem CPU time [usec] */ |
1564 | __u64 ac_minflt; /* Minor Page Fault Count */ |
1565 | diff --git a/mm/madvise.c b/mm/madvise.c |
1566 | index 77916e9..603c525 100644 |
1567 | --- a/mm/madvise.c |
1568 | +++ b/mm/madvise.c |
1569 | @@ -159,9 +159,10 @@ static long madvise_remove(struct vm_area_struct *vma, |
1570 | unsigned long start, unsigned long end) |
1571 | { |
1572 | struct address_space *mapping; |
1573 | - loff_t offset, endoff; |
1574 | + loff_t offset, endoff; |
1575 | + int error; |
1576 | |
1577 | - *prev = vma; |
1578 | + *prev = NULL; /* tell sys_madvise we drop mmap_sem */ |
1579 | |
1580 | if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB)) |
1581 | return -EINVAL; |
1582 | @@ -180,7 +181,12 @@ static long madvise_remove(struct vm_area_struct *vma, |
1583 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
1584 | endoff = (loff_t)(end - vma->vm_start - 1) |
1585 | + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
1586 | - return vmtruncate_range(mapping->host, offset, endoff); |
1587 | + |
1588 | + /* vmtruncate_range needs to take i_mutex and i_alloc_sem */ |
1589 | + up_write(¤t->mm->mmap_sem); |
1590 | + error = vmtruncate_range(mapping->host, offset, endoff); |
1591 | + down_write(¤t->mm->mmap_sem); |
1592 | + return error; |
1593 | } |
1594 | |
1595 | static long |
1596 | @@ -315,12 +321,15 @@ asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior) |
1597 | if (error) |
1598 | goto out; |
1599 | start = tmp; |
1600 | - if (start < prev->vm_end) |
1601 | + if (prev && start < prev->vm_end) |
1602 | start = prev->vm_end; |
1603 | error = unmapped_error; |
1604 | if (start >= end) |
1605 | goto out; |
1606 | - vma = prev->vm_next; |
1607 | + if (prev) |
1608 | + vma = prev->vm_next; |
1609 | + else /* madvise_remove dropped mmap_sem */ |
1610 | + vma = find_vma(current->mm, start); |
1611 | } |
1612 | out: |
1613 | up_write(¤t->mm->mmap_sem); |
1614 | diff --git a/mm/migrate.c b/mm/migrate.c |
1615 | index e9b161b..4372d6b 100644 |
1616 | --- a/mm/migrate.c |
1617 | +++ b/mm/migrate.c |
1618 | @@ -297,7 +297,7 @@ static int migrate_page_move_mapping(struct address_space *mapping, |
1619 | void **pslot; |
1620 | |
1621 | if (!mapping) { |
1622 | - /* Anonymous page */ |
1623 | + /* Anonymous page without mapping */ |
1624 | if (page_count(page) != 1) |
1625 | return -EAGAIN; |
1626 | return 0; |
1627 | @@ -333,6 +333,19 @@ static int migrate_page_move_mapping(struct address_space *mapping, |
1628 | */ |
1629 | __put_page(page); |
1630 | |
1631 | + /* |
1632 | + * If moved to a different zone then also account |
1633 | + * the page for that zone. Other VM counters will be |
1634 | + * taken care of when we establish references to the |
1635 | + * new page and drop references to the old page. |
1636 | + * |
1637 | + * Note that anonymous pages are accounted for |
1638 | + * via NR_FILE_PAGES and NR_ANON_PAGES if they |
1639 | + * are mapped to swap space. |
1640 | + */ |
1641 | + __dec_zone_page_state(page, NR_FILE_PAGES); |
1642 | + __inc_zone_page_state(newpage, NR_FILE_PAGES); |
1643 | + |
1644 | write_unlock_irq(&mapping->tree_lock); |
1645 | |
1646 | return 0; |
1647 | diff --git a/mm/oom_kill.c b/mm/oom_kill.c |
1648 | index 2f39169..223add3 100644 |
1649 | --- a/mm/oom_kill.c |
1650 | +++ b/mm/oom_kill.c |
1651 | @@ -176,6 +176,8 @@ static inline int constrained_alloc(struct zonelist *zonelist, gfp_t gfp_mask) |
1652 | struct zone **z; |
1653 | nodemask_t nodes; |
1654 | int node; |
1655 | + |
1656 | + nodes_clear(nodes); |
1657 | /* node has memory ? */ |
1658 | for_each_online_node(node) |
1659 | if (NODE_DATA(node)->node_present_pages) |
1660 | diff --git a/mm/shmem.c b/mm/shmem.c |
1661 | index 70da7a0..fc30c59 100644 |
1662 | --- a/mm/shmem.c |
1663 | +++ b/mm/shmem.c |
1664 | @@ -402,26 +402,38 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long |
1665 | /* |
1666 | * shmem_free_swp - free some swap entries in a directory |
1667 | * |
1668 | - * @dir: pointer to the directory |
1669 | - * @edir: pointer after last entry of the directory |
1670 | + * @dir: pointer to the directory |
1671 | + * @edir: pointer after last entry of the directory |
1672 | + * @punch_lock: pointer to spinlock when needed for the holepunch case |
1673 | */ |
1674 | -static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir) |
1675 | +static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir, |
1676 | + spinlock_t *punch_lock) |
1677 | { |
1678 | + spinlock_t *punch_unlock = NULL; |
1679 | swp_entry_t *ptr; |
1680 | int freed = 0; |
1681 | |
1682 | for (ptr = dir; ptr < edir; ptr++) { |
1683 | if (ptr->val) { |
1684 | + if (unlikely(punch_lock)) { |
1685 | + punch_unlock = punch_lock; |
1686 | + punch_lock = NULL; |
1687 | + spin_lock(punch_unlock); |
1688 | + if (!ptr->val) |
1689 | + continue; |
1690 | + } |
1691 | free_swap_and_cache(*ptr); |
1692 | *ptr = (swp_entry_t){0}; |
1693 | freed++; |
1694 | } |
1695 | } |
1696 | + if (punch_unlock) |
1697 | + spin_unlock(punch_unlock); |
1698 | return freed; |
1699 | } |
1700 | |
1701 | -static int shmem_map_and_free_swp(struct page *subdir, |
1702 | - int offset, int limit, struct page ***dir) |
1703 | +static int shmem_map_and_free_swp(struct page *subdir, int offset, |
1704 | + int limit, struct page ***dir, spinlock_t *punch_lock) |
1705 | { |
1706 | swp_entry_t *ptr; |
1707 | int freed = 0; |
1708 | @@ -431,7 +443,8 @@ static int shmem_map_and_free_swp(struct page *subdir, |
1709 | int size = limit - offset; |
1710 | if (size > LATENCY_LIMIT) |
1711 | size = LATENCY_LIMIT; |
1712 | - freed += shmem_free_swp(ptr+offset, ptr+offset+size); |
1713 | + freed += shmem_free_swp(ptr+offset, ptr+offset+size, |
1714 | + punch_lock); |
1715 | if (need_resched()) { |
1716 | shmem_swp_unmap(ptr); |
1717 | if (*dir) { |
1718 | @@ -481,7 +494,10 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) |
1719 | long nr_swaps_freed = 0; |
1720 | int offset; |
1721 | int freed; |
1722 | - int punch_hole = 0; |
1723 | + int punch_hole; |
1724 | + spinlock_t *needs_lock; |
1725 | + spinlock_t *punch_lock; |
1726 | + unsigned long upper_limit; |
1727 | |
1728 | inode->i_ctime = inode->i_mtime = CURRENT_TIME; |
1729 | idx = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
1730 | @@ -492,11 +508,20 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) |
1731 | info->flags |= SHMEM_TRUNCATE; |
1732 | if (likely(end == (loff_t) -1)) { |
1733 | limit = info->next_index; |
1734 | + upper_limit = SHMEM_MAX_INDEX; |
1735 | info->next_index = idx; |
1736 | + needs_lock = NULL; |
1737 | + punch_hole = 0; |
1738 | } else { |
1739 | - limit = (end + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
1740 | - if (limit > info->next_index) |
1741 | - limit = info->next_index; |
1742 | + if (end + 1 >= inode->i_size) { /* we may free a little more */ |
1743 | + limit = (inode->i_size + PAGE_CACHE_SIZE - 1) >> |
1744 | + PAGE_CACHE_SHIFT; |
1745 | + upper_limit = SHMEM_MAX_INDEX; |
1746 | + } else { |
1747 | + limit = (end + 1) >> PAGE_CACHE_SHIFT; |
1748 | + upper_limit = limit; |
1749 | + } |
1750 | + needs_lock = &info->lock; |
1751 | punch_hole = 1; |
1752 | } |
1753 | |
1754 | @@ -513,17 +538,30 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) |
1755 | size = limit; |
1756 | if (size > SHMEM_NR_DIRECT) |
1757 | size = SHMEM_NR_DIRECT; |
1758 | - nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size); |
1759 | + nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size, needs_lock); |
1760 | } |
1761 | |
1762 | /* |
1763 | * If there are no indirect blocks or we are punching a hole |
1764 | * below indirect blocks, nothing to be done. |
1765 | */ |
1766 | - if (!topdir || (punch_hole && (limit <= SHMEM_NR_DIRECT))) |
1767 | + if (!topdir || limit <= SHMEM_NR_DIRECT) |
1768 | goto done2; |
1769 | |
1770 | - BUG_ON(limit <= SHMEM_NR_DIRECT); |
1771 | + /* |
1772 | + * The truncation case has already dropped info->lock, and we're safe |
1773 | + * because i_size and next_index have already been lowered, preventing |
1774 | + * access beyond. But in the punch_hole case, we still need to take |
1775 | + * the lock when updating the swap directory, because there might be |
1776 | + * racing accesses by shmem_getpage(SGP_CACHE), shmem_unuse_inode or |
1777 | + * shmem_writepage. However, whenever we find we can remove a whole |
1778 | + * directory page (not at the misaligned start or end of the range), |
1779 | + * we first NULLify its pointer in the level above, and then have no |
1780 | + * need to take the lock when updating its contents: needs_lock and |
1781 | + * punch_lock (either pointing to info->lock or NULL) manage this. |
1782 | + */ |
1783 | + |
1784 | + upper_limit -= SHMEM_NR_DIRECT; |
1785 | limit -= SHMEM_NR_DIRECT; |
1786 | idx = (idx > SHMEM_NR_DIRECT)? (idx - SHMEM_NR_DIRECT): 0; |
1787 | offset = idx % ENTRIES_PER_PAGE; |
1788 | @@ -543,8 +581,14 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) |
1789 | if (*dir) { |
1790 | diroff = ((idx - ENTRIES_PER_PAGEPAGE/2) % |
1791 | ENTRIES_PER_PAGEPAGE) / ENTRIES_PER_PAGE; |
1792 | - if (!diroff && !offset) { |
1793 | - *dir = NULL; |
1794 | + if (!diroff && !offset && upper_limit >= stage) { |
1795 | + if (needs_lock) { |
1796 | + spin_lock(needs_lock); |
1797 | + *dir = NULL; |
1798 | + spin_unlock(needs_lock); |
1799 | + needs_lock = NULL; |
1800 | + } else |
1801 | + *dir = NULL; |
1802 | nr_pages_to_free++; |
1803 | list_add(&middir->lru, &pages_to_free); |
1804 | } |
1805 | @@ -570,39 +614,55 @@ static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) |
1806 | } |
1807 | stage = idx + ENTRIES_PER_PAGEPAGE; |
1808 | middir = *dir; |
1809 | - *dir = NULL; |
1810 | - nr_pages_to_free++; |
1811 | - list_add(&middir->lru, &pages_to_free); |
1812 | + if (punch_hole) |
1813 | + needs_lock = &info->lock; |
1814 | + if (upper_limit >= stage) { |
1815 | + if (needs_lock) { |
1816 | + spin_lock(needs_lock); |
1817 | + *dir = NULL; |
1818 | + spin_unlock(needs_lock); |
1819 | + needs_lock = NULL; |
1820 | + } else |
1821 | + *dir = NULL; |
1822 | + nr_pages_to_free++; |
1823 | + list_add(&middir->lru, &pages_to_free); |
1824 | + } |
1825 | shmem_dir_unmap(dir); |
1826 | cond_resched(); |
1827 | dir = shmem_dir_map(middir); |
1828 | diroff = 0; |
1829 | } |
1830 | + punch_lock = needs_lock; |
1831 | subdir = dir[diroff]; |
1832 | - if (subdir && page_private(subdir)) { |
1833 | + if (subdir && !offset && upper_limit-idx >= ENTRIES_PER_PAGE) { |
1834 | + if (needs_lock) { |
1835 | + spin_lock(needs_lock); |
1836 | + dir[diroff] = NULL; |
1837 | + spin_unlock(needs_lock); |
1838 | + punch_lock = NULL; |
1839 | + } else |
1840 | + dir[diroff] = NULL; |
1841 | + nr_pages_to_free++; |
1842 | + list_add(&subdir->lru, &pages_to_free); |
1843 | + } |
1844 | + if (subdir && page_private(subdir) /* has swap entries */) { |
1845 | size = limit - idx; |
1846 | if (size > ENTRIES_PER_PAGE) |
1847 | size = ENTRIES_PER_PAGE; |
1848 | freed = shmem_map_and_free_swp(subdir, |
1849 | - offset, size, &dir); |
1850 | + offset, size, &dir, punch_lock); |
1851 | if (!dir) |
1852 | dir = shmem_dir_map(middir); |
1853 | nr_swaps_freed += freed; |
1854 | - if (offset) |
1855 | + if (offset || punch_lock) { |
1856 | spin_lock(&info->lock); |
1857 | - set_page_private(subdir, page_private(subdir) - freed); |
1858 | - if (offset) |
1859 | + set_page_private(subdir, |
1860 | + page_private(subdir) - freed); |
1861 | spin_unlock(&info->lock); |
1862 | - if (!punch_hole) |
1863 | - BUG_ON(page_private(subdir) > offset); |
1864 | - } |
1865 | - if (offset) |
1866 | - offset = 0; |
1867 | - else if (subdir && !page_private(subdir)) { |
1868 | - dir[diroff] = NULL; |
1869 | - nr_pages_to_free++; |
1870 | - list_add(&subdir->lru, &pages_to_free); |
1871 | + } else |
1872 | + BUG_ON(page_private(subdir) != freed); |
1873 | } |
1874 | + offset = 0; |
1875 | } |
1876 | done1: |
1877 | shmem_dir_unmap(dir); |
1878 | @@ -614,8 +674,16 @@ done2: |
1879 | * generic_delete_inode did it, before we lowered next_index. |
1880 | * Also, though shmem_getpage checks i_size before adding to |
1881 | * cache, no recheck after: so fix the narrow window there too. |
1882 | + * |
1883 | + * Recalling truncate_inode_pages_range and unmap_mapping_range |
1884 | + * every time for punch_hole (which never got a chance to clear |
1885 | + * SHMEM_PAGEIN at the start of vmtruncate_range) is expensive, |
1886 | + * yet hardly ever necessary: try to optimize them out later. |
1887 | */ |
1888 | truncate_inode_pages_range(inode->i_mapping, start, end); |
1889 | + if (punch_hole) |
1890 | + unmap_mapping_range(inode->i_mapping, start, |
1891 | + end - start, 1); |
1892 | } |
1893 | |
1894 | spin_lock(&info->lock); |
1895 | diff --git a/net/core/netpoll.c b/net/core/netpoll.c |
1896 | index 823215d..522e441 100644 |
1897 | --- a/net/core/netpoll.c |
1898 | +++ b/net/core/netpoll.c |
1899 | @@ -471,6 +471,13 @@ int __netpoll_rx(struct sk_buff *skb) |
1900 | if (skb->len < len || len < iph->ihl*4) |
1901 | goto out; |
1902 | |
1903 | + /* |
1904 | + * Our transport medium may have padded the buffer out. |
1905 | + * Now We trim to the true length of the frame. |
1906 | + */ |
1907 | + if (pskb_trim_rcsum(skb, len)) |
1908 | + goto out; |
1909 | + |
1910 | if (iph->protocol != IPPROTO_UDP) |
1911 | goto out; |
1912 | |
1913 | diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c |
1914 | index ebe9d0d..4a71b31 100644 |
1915 | --- a/net/ipv4/tcp.c |
1916 | +++ b/net/ipv4/tcp.c |
1917 | @@ -2457,11 +2457,18 @@ void __init tcp_init(void) |
1918 | sysctl_max_syn_backlog = 128; |
1919 | } |
1920 | |
1921 | - /* Allow no more than 3/4 kernel memory (usually less) allocated to TCP */ |
1922 | - sysctl_tcp_mem[0] = (1536 / sizeof (struct inet_bind_hashbucket)) << order; |
1923 | - sysctl_tcp_mem[1] = sysctl_tcp_mem[0] * 4 / 3; |
1924 | + /* Set the pressure threshold to be a fraction of global memory that |
1925 | + * is up to 1/2 at 256 MB, decreasing toward zero with the amount of |
1926 | + * memory, with a floor of 128 pages. |
1927 | + */ |
1928 | + limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); |
1929 | + limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); |
1930 | + limit = max(limit, 128UL); |
1931 | + sysctl_tcp_mem[0] = limit / 4 * 3; |
1932 | + sysctl_tcp_mem[1] = limit; |
1933 | sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; |
1934 | |
1935 | + /* Set per-socket limits to no more than 1/128 the pressure threshold */ |
1936 | limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); |
1937 | max_share = min(4UL*1024*1024, limit); |
1938 | |
1939 | diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c |
1940 | index 7e1aea8..b296c1b 100644 |
1941 | --- a/net/irda/af_irda.c |
1942 | +++ b/net/irda/af_irda.c |
1943 | @@ -138,7 +138,6 @@ static void irda_disconnect_indication(void *instance, void *sap, |
1944 | sk->sk_shutdown |= SEND_SHUTDOWN; |
1945 | |
1946 | sk->sk_state_change(sk); |
1947 | - sock_orphan(sk); |
1948 | release_sock(sk); |
1949 | |
1950 | /* Close our TSAP. |
1951 | @@ -1446,7 +1445,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, |
1952 | */ |
1953 | ret = sock_error(sk); |
1954 | if (ret) |
1955 | - break; |
1956 | + ; |
1957 | else if (sk->sk_shutdown & RCV_SHUTDOWN) |
1958 | ; |
1959 | else if (noblock) |
1960 | diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c |
1961 | index 0d1e8fb..a568f9f 100644 |
1962 | --- a/net/sunrpc/svcauth_unix.c |
1963 | +++ b/net/sunrpc/svcauth_unix.c |
1964 | @@ -383,7 +383,10 @@ void svcauth_unix_purge(void) |
1965 | static inline struct ip_map * |
1966 | ip_map_cached_get(struct svc_rqst *rqstp) |
1967 | { |
1968 | - struct ip_map *ipm = rqstp->rq_sock->sk_info_authunix; |
1969 | + struct ip_map *ipm; |
1970 | + struct svc_sock *svsk = rqstp->rq_sock; |
1971 | + spin_lock_bh(&svsk->sk_defer_lock); |
1972 | + ipm = svsk->sk_info_authunix; |
1973 | if (ipm != NULL) { |
1974 | if (!cache_valid(&ipm->h)) { |
1975 | /* |
1976 | @@ -391,12 +394,14 @@ ip_map_cached_get(struct svc_rqst *rqstp) |
1977 | * remembered, e.g. by a second mount from the |
1978 | * same IP address. |
1979 | */ |
1980 | - rqstp->rq_sock->sk_info_authunix = NULL; |
1981 | + svsk->sk_info_authunix = NULL; |
1982 | + spin_unlock_bh(&svsk->sk_defer_lock); |
1983 | cache_put(&ipm->h, &ip_map_cache); |
1984 | return NULL; |
1985 | } |
1986 | cache_get(&ipm->h); |
1987 | } |
1988 | + spin_unlock_bh(&svsk->sk_defer_lock); |
1989 | return ipm; |
1990 | } |
1991 | |
1992 | @@ -405,9 +410,15 @@ ip_map_cached_put(struct svc_rqst *rqstp, struct ip_map *ipm) |
1993 | { |
1994 | struct svc_sock *svsk = rqstp->rq_sock; |
1995 | |
1996 | - if (svsk->sk_sock->type == SOCK_STREAM && svsk->sk_info_authunix == NULL) |
1997 | - svsk->sk_info_authunix = ipm; /* newly cached, keep the reference */ |
1998 | - else |
1999 | + spin_lock_bh(&svsk->sk_defer_lock); |
2000 | + if (svsk->sk_sock->type == SOCK_STREAM && |
2001 | + svsk->sk_info_authunix == NULL) { |
2002 | + /* newly cached, keep the reference */ |
2003 | + svsk->sk_info_authunix = ipm; |
2004 | + ipm = NULL; |
2005 | + } |
2006 | + spin_unlock_bh(&svsk->sk_defer_lock); |
2007 | + if (ipm) |
2008 | cache_put(&ipm->h, &ip_map_cache); |
2009 | } |
2010 | |
2011 | diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c |
2012 | index 30aaa60..6dc6b77 100644 |
2013 | --- a/sound/pci/intel8x0.c |
2014 | +++ b/sound/pci/intel8x0.c |
2015 | @@ -2489,7 +2489,10 @@ static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state) |
2016 | } |
2017 | pci_disable_device(pci); |
2018 | pci_save_state(pci); |
2019 | - pci_set_power_state(pci, pci_choose_state(pci, state)); |
2020 | + /* The call below may disable built-in speaker on some laptops |
2021 | + * after S2RAM. So, don't touch it. |
2022 | + */ |
2023 | + /* pci_set_power_state(pci, pci_choose_state(pci, state)); */ |
2024 | return 0; |
2025 | } |
2026 |