diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-04-20 00:47:49 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-04-20 00:47:49 -0700 |
| commit | 8f421acbbdc3daba1682bdf7b99083f4725ce5d3 (patch) | |
| tree | 28d8e5910bd466ed487654d5e62269b8446a80bd /include | |
| parent | 2d0ed1066cf5dd005c518be917649ca3f3b5c961 (diff) | |
| parent | b009a1c6a6c0273f60d96eca2561bc79da3b6614 (diff) | |
Merge home.transmeta.com:/home/torvalds/v2.5/akpm
into home.transmeta.com:/home/torvalds/v2.5/linux
Diffstat (limited to 'include')
27 files changed, 137 insertions, 117 deletions
diff --git a/include/asm-alpha/pgalloc.h b/include/asm-alpha/pgalloc.h index fc675efac381..b34194c3d96c 100644 --- a/include/asm-alpha/pgalloc.h +++ b/include/asm-alpha/pgalloc.h @@ -40,7 +40,7 @@ pgd_free(pgd_t *pgd) static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long address) { - pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL); + pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (ret) clear_page(ret); return ret; diff --git a/include/asm-arm/proc-armv/pgalloc.h b/include/asm-arm/proc-armv/pgalloc.h index 4440be79d5ac..3263c346ccba 100644 --- a/include/asm-arm/proc-armv/pgalloc.h +++ b/include/asm-arm/proc-armv/pgalloc.h @@ -27,17 +27,9 @@ static inline pte_t * pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) { - int count = 0; pte_t *pte; - do { - pte = (pte_t *)__get_free_page(GFP_KERNEL); - if (!pte) { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - } - } while (!pte && (count++ < 10)); - + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pte) { clear_page(pte); clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); @@ -51,16 +43,8 @@ static inline struct page * pte_alloc_one(struct mm_struct *mm, unsigned long addr) { struct page *pte; - int count = 0; - - do { - pte = alloc_pages(GFP_KERNEL, 0); - if (!pte) { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - } - } while (!pte && (count++ < 10)); + pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); if (pte) { void *page = page_address(pte); clear_page(page); diff --git a/include/asm-cris/pgalloc.h b/include/asm-cris/pgalloc.h index 80e73be0d2b0..75dde6f4a42f 100644 --- a/include/asm-cris/pgalloc.h +++ b/include/asm-cris/pgalloc.h @@ -62,7 +62,7 @@ static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) { pte_t *pte; - pte = (pte_t *) __get_free_page(GFP_KERNEL); + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pte) clear_page(pte); return pte; diff --git a/include/asm-i386/div64.h b/include/asm-i386/div64.h index ef915df700e4..bc8718a0b1ce 100644 --- a/include/asm-i386/div64.h +++ b/include/asm-i386/div64.h @@ -14,4 +14,22 @@ __mod; \ }) +/* + * (long)X = ((long long)divs) / (long)div + * (long)rem = ((long long)divs) % (long)div + * + * Warning, this will do an exception if X overflows. + */ +#define div_long_long_rem(a,b,c) div_ll_X_l_rem(a,b,c) + +extern inline long +div_ll_X_l_rem(long long divs, long div, long *rem) +{ + long dum2; + __asm__("divl %2":"=a"(dum2), "=d"(*rem) + : "rm"(div), "A"(divs)); + + return dum2; + +} #endif diff --git a/include/asm-ia64/pgalloc.h b/include/asm-ia64/pgalloc.h index 2e6134af88bc..4f56ceb9c42b 100644 --- a/include/asm-ia64/pgalloc.h +++ b/include/asm-ia64/pgalloc.h @@ -93,7 +93,7 @@ pmd_alloc_one_fast (struct mm_struct *mm, unsigned long addr) static inline pmd_t* pmd_alloc_one (struct mm_struct *mm, unsigned long addr) { - pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL); + pmd_t *pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (likely(pmd != NULL)) clear_page(pmd); @@ -125,7 +125,7 @@ pmd_populate_kernel (struct mm_struct *mm, pmd_t *pmd_entry, pte_t *pte) static inline struct page * pte_alloc_one (struct mm_struct *mm, unsigned long addr) { - struct page *pte = alloc_pages(GFP_KERNEL, 0); + struct page *pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); if (likely(pte != NULL)) clear_page(page_address(pte)); @@ -135,7 +135,7 @@ pte_alloc_one (struct mm_struct *mm, unsigned long addr) static inline pte_t * pte_alloc_one_kernel (struct mm_struct *mm, unsigned long addr) { - pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL); + pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (likely(pte != NULL)) clear_page(pte); diff --git a/include/asm-m68k/motorola_pgalloc.h b/include/asm-m68k/motorola_pgalloc.h index 4beb7a822b38..f315615e488a 100644 --- a/include/asm-m68k/motorola_pgalloc.h +++ b/include/asm-m68k/motorola_pgalloc.h @@ -11,7 +11,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long ad { pte_t *pte; - pte = (pte_t *) __get_free_page(GFP_KERNEL); + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pte) { clear_page(pte); __flush_page_to_ram(pte); @@ -30,7 +30,7 @@ static inline void pte_free_kernel(pte_t *pte) static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) { - struct page *page = alloc_pages(GFP_KERNEL, 0); + struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); pte_t *pte; if(!page) diff --git a/include/asm-m68k/sun3_pgalloc.h b/include/asm-m68k/sun3_pgalloc.h index 7740a2936511..4580b60196b9 100644 --- a/include/asm-m68k/sun3_pgalloc.h +++ b/include/asm-m68k/sun3_pgalloc.h @@ -18,7 +18,7 @@ extern const char bad_pmd_string[]; -#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) +#define lpmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) static inline void pte_free_kernel(pte_t * pte) @@ -39,7 +39,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *page) static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - unsigned long page = __get_free_page(GFP_KERNEL); + unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT); if (!page) return NULL; @@ -51,7 +51,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) { - struct page *page = alloc_pages(GFP_KERNEL, 0); + struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); if (page == NULL) return NULL; diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h index 9492a50dae76..f71b90b1c8e1 100644 --- a/include/asm-mips/pgalloc.h +++ b/include/asm-mips/pgalloc.h @@ -132,7 +132,7 @@ static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) { pte_t *pte; - pte = (pte_t *) __get_free_page(GFP_KERNEL); + pte = (pte_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pte) clear_page(pte); return pte; diff --git a/include/asm-mips64/pgalloc.h b/include/asm-mips64/pgalloc.h index 79b58408d660..2b777eebcc31 100644 --- a/include/asm-mips64/pgalloc.h +++ b/include/asm-mips64/pgalloc.h @@ -93,7 +93,7 @@ static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) { pte_t *pte; - pte = (pte_t *) __get_free_page(GFP_KERNEL); + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pte) clear_page(pte); return pte; @@ -141,7 +141,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) { pmd_t *pmd; - pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 1); + pmd = (pmd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 1); if (pmd) pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table); return pmd; diff --git a/include/asm-parisc/pgalloc.h b/include/asm-parisc/pgalloc.h index 32dcf11d084c..bbc02cb134b7 100644 --- a/include/asm-parisc/pgalloc.h +++ b/include/asm-parisc/pgalloc.h @@ -35,7 +35,7 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) { - pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL); + pmd_t *pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pmd) clear_page(pmd); return pmd; @@ -73,7 +73,7 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) static inline struct page * pte_alloc_one(struct mm_struct *mm, unsigned long address) { - struct page *page = alloc_page(GFP_KERNEL); + struct page *page = alloc_page(GFP_KERNEL|__GFP_REPEAT); if (likely(page != NULL)) clear_page(page_address(page)); return page; @@ -82,7 +82,7 @@ pte_alloc_one(struct mm_struct *mm, unsigned long address) static inline pte_t * pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) { - pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL); + pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (likely(pte != NULL)) clear_page(pte); return pte; diff --git a/include/asm-ppc64/pgalloc.h b/include/asm-ppc64/pgalloc.h index 0c461418bb48..9376b791bee7 100644 --- a/include/asm-ppc64/pgalloc.h +++ b/include/asm-ppc64/pgalloc.h @@ -31,19 +31,11 @@ pgd_free(pgd_t *pgd) static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - int count = 0; pmd_t *pmd; - do { - pmd = (pmd_t *)__get_free_page(GFP_KERNEL); - if (pmd) - clear_page(pmd); - else { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - } - } while (!pmd && (count++ < 10)); - + pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + if (pmd) + clear_page(pmd); return pmd; } @@ -62,19 +54,11 @@ pmd_free(pmd_t *pmd) static inline pte_t * pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) { - int count = 0; pte_t *pte; - do { - pte = (pte_t *)__get_free_page(GFP_KERNEL); - if (pte) - clear_page(pte); - else { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - } - } while (!pte && (count++ < 10)); - + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + if (pte) + clear_page(pte); return pte; } diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h index 67230ef0e0c5..e4729fb912fd 100644 --- a/include/asm-s390/pgalloc.h +++ b/include/asm-s390/pgalloc.h @@ -120,20 +120,13 @@ static inline pte_t * pte_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr) { pte_t *pte; - int count; int i; - count = 0; - do { - pte = (pte_t *) __get_free_page(GFP_KERNEL); - if (pte != NULL) { - for (i=0; i < PTRS_PER_PTE; i++) - pte_clear(pte+i); - } else { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ); - } - } while (!pte && (count++ < 10)); + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + if (pte != NULL) { + for (i=0; i < PTRS_PER_PTE; i++) + pte_clear(pte+i); + } return pte; } diff --git a/include/asm-sh/pgalloc.h b/include/asm-sh/pgalloc.h index 9cc5a7dc98ed..a60b4c961a4f 100644 --- a/include/asm-sh/pgalloc.h +++ b/include/asm-sh/pgalloc.h @@ -35,7 +35,7 @@ static inline void pgd_free(pgd_t *pgd) static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) { - pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL); + pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pte) clear_page(pte); return pte; diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index 037c09b1a737..d3c3a7060664 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h @@ -159,7 +159,7 @@ static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addre pmd = pmd_alloc_one_fast(mm, address); if (!pmd) { - pmd = (pmd_t *)__get_free_page(GFP_KERNEL); + pmd = (pmd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pmd) memset(pmd, 0, PAGE_SIZE); } diff --git a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h index 4cae8e6a37a0..e15895c99a4e 100644 --- a/include/asm-x86_64/pgalloc.h +++ b/include/asm-x86_64/pgalloc.h @@ -31,12 +31,12 @@ extern __inline__ void pmd_free(pmd_t *pmd) static inline pmd_t *pmd_alloc_one (struct mm_struct *mm, unsigned long addr) { - return (pmd_t *) get_zeroed_page(GFP_KERNEL); + return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); } static inline pgd_t *pgd_alloc (struct mm_struct *mm) { - return (pgd_t *)get_zeroed_page(GFP_KERNEL); + return (pgd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); } static inline void pgd_free (pgd_t *pgd) @@ -48,12 +48,12 @@ static inline void pgd_free (pgd_t *pgd) static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - return (pte_t *) get_zeroed_page(GFP_KERNEL); + return (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); } static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) { - void *p = (void *)get_zeroed_page(GFP_KERNEL); + void *p = (void *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); if (!p) return NULL; return virt_to_page(p); diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 64a70553d40c..26d71a5fb742 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -172,7 +172,7 @@ struct buffer_head * __getblk(struct block_device *, sector_t, int); void __brelse(struct buffer_head *); void __bforget(struct buffer_head *); struct buffer_head *__bread(struct block_device *, sector_t block, int size); -struct buffer_head *alloc_buffer_head(void); +struct buffer_head *alloc_buffer_head(int gfp_flags); void free_buffer_head(struct buffer_head * bh); void FASTCALL(unlock_buffer(struct buffer_head *bh)); void ll_rw_block(int, int, struct buffer_head * bh[]); diff --git a/include/linux/dcache.h b/include/linux/dcache.h index db979c3cf890..78fafd500123 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -270,7 +270,6 @@ static inline struct dentry *dget(struct dentry *dentry) if (!atomic_read(&dentry->d_count)) BUG(); atomic_inc(&dentry->d_count); - dentry->d_vfs_flags |= DCACHE_REFERENCED; } return dentry; } diff --git a/include/linux/genhd.h b/include/linux/genhd.h index c2432bd349e5..ac8fc9ef5bdb 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -64,7 +64,7 @@ struct hd_struct { sector_t nr_sects; struct kobject kobj; unsigned reads, read_sectors, writes, write_sectors; - int policy; + int policy, partno; }; #define GENHD_FL_REMOVABLE 1 @@ -89,7 +89,7 @@ struct gendisk { int minor_shift; /* number of times minor is shifted to get real minor */ char disk_name[16]; /* name of major driver */ - struct hd_struct *part; /* [indexed by minor] */ + struct hd_struct **part; /* [indexed by minor] */ struct block_device_operations *fops; struct request_queue *queue; void *private_data; diff --git a/include/linux/gfp.h b/include/linux/gfp.h index c475f7b41e59..ade6d9e97475 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -11,13 +11,26 @@ #define __GFP_DMA 0x01 #define __GFP_HIGHMEM 0x02 -/* Action modifiers - doesn't change the zoning */ +/* + * Action modifiers - doesn't change the zoning + * + * __GFP_REPEAT: Try hard to allocate the memory, but the allocation attempt + * _might_ fail. This depends upon the particular VM implementation. + * + * __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller + * cannot handle allocation failures. + * + * __GFP_NORETRY: The VM implementation must not retry indefinitely. + */ #define __GFP_WAIT 0x10 /* Can wait and reschedule? */ #define __GFP_HIGH 0x20 /* Should access emergency pools? */ #define __GFP_IO 0x40 /* Can start physical IO? */ #define __GFP_FS 0x80 /* Can call down to low-level FS? */ #define __GFP_COLD 0x100 /* Cache-cold page required */ #define __GFP_NOWARN 0x200 /* Suppress page allocation failure warning */ +#define __GFP_REPEAT 0x400 /* Retry the allocation. Might fail */ +#define __GFP_NOFAIL 0x800 /* Retry for ever. Cannot fail */ +#define __GFP_NORETRY 0x1000 /* Do not retry. Might fail */ #define GFP_ATOMIC (__GFP_HIGH) #define GFP_NOIO (__GFP_WAIT) diff --git a/include/linux/linux_logo.h b/include/linux/linux_logo.h index ea05e16c2b16..9c01bde5bf1b 100644 --- a/include/linux/linux_logo.h +++ b/include/linux/linux_logo.h @@ -32,6 +32,6 @@ struct linux_logo { const unsigned char *data; }; -extern const struct linux_logo * __init find_logo(int depth); +extern const struct linux_logo *fb_find_logo(int depth); #endif /* _LINUX_LINUX_LOGO_H */ diff --git a/include/linux/mm.h b/include/linux/mm.h index ede6c5ff4181..6aa89d73f65b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -594,28 +594,10 @@ extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned lon extern unsigned int nr_used_zone_pages(void); -#ifdef CONFIG_MMU extern struct page * vmalloc_to_page(void *addr); extern struct page * follow_page(struct mm_struct *mm, unsigned long address, int write); extern int remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to, unsigned long size, pgprot_t prot); -#else -static inline struct page * vmalloc_to_page(void *addr) -{ - return NULL; -} -static inline struct page * follow_page(struct mm_struct *mm, - unsigned long address, int write) -{ - return NULL; -} -static inline int remap_page_range(struct vm_area_struct *vma, - unsigned long from, unsigned long to, - unsigned long size, pgprot_t prot) -{ - return -EPERM; -} -#endif /* CONFIG_MMU */ #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h index 37b8901433d6..b6fa4d1839e3 100644 --- a/include/linux/nfsd/syscall.h +++ b/include/linux/nfsd/syscall.h @@ -59,7 +59,7 @@ struct nfsctl_client { struct nfsctl_export { char ex_client[NFSCLNT_IDMAX+1]; char ex_path[NFS_MAXPATHLEN+1]; - __kernel_dev_t ex_dev; + __kernel_old_dev_t ex_dev; __kernel_ino_t ex_ino; int ex_flags; __kernel_uid_t ex_anon_uid; @@ -104,7 +104,6 @@ struct nfsctl_arg { #define ca_export u.u_export #define ca_getfd u.u_getfd #define ca_getfs u.u_getfs -#define ca_authd u.u_authd }; union nfsctl_res { diff --git a/include/linux/sched.h b/include/linux/sched.h index c30c44f3cfcc..eee58c7354b4 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -465,6 +465,7 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) #define PF_FROZEN 0x00010000 /* frozen for system suspend */ #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ #define PF_KSWAPD 0x00040000 /* I am kswapd */ +#define PF_SWAPOFF 0x00080000 /* I am in swapoff */ #if CONFIG_SMP extern void set_cpus_allowed(task_t *p, unsigned long new_mask); diff --git a/include/linux/slab.h b/include/linux/slab.h index bdc5256de12a..603748b9b349 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -22,7 +22,7 @@ typedef struct kmem_cache_s kmem_cache_t; #define SLAB_KERNEL GFP_KERNEL #define SLAB_DMA GFP_DMA -#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|__GFP_COLD|__GFP_NOWARN) +#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|__GFP_COLD|__GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|__GFP_NORETRY) #define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */ /* flags to pass to kmem_cache_create(). diff --git a/include/linux/time.h b/include/linux/time.h index 4d7238025fe9..fdab2abc43be 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -26,6 +26,16 @@ struct timezone { #include <linux/spinlock.h> #include <linux/seqlock.h> +#include <linux/timex.h> +#include <asm/div64.h> +#ifndef div_long_long_rem + +#define div_long_long_rem(dividend,divisor,remainder) ({ \ + u64 result = dividend; \ + *remainder = do_div(result,divisor); \ + result; }) + +#endif /* * Have the 32 bit jiffies value wrap 5 minutes after boot @@ -59,25 +69,52 @@ struct timezone { #ifndef NSEC_PER_USEC #define NSEC_PER_USEC (1000L) #endif +/* + * We want to do realistic conversions of time so we need to use the same + * values the update wall clock code uses as the jiffie size. This value + * is: TICK_NSEC(TICK_USEC) (both of which are defined in timex.h). This + * is a constant and is in nanoseconds. We will used scaled math and + * with a scales defined here as SEC_JIFFIE_SC, USEC_JIFFIE_SC and + * NSEC_JIFFIE_SC. Note that these defines contain nothing but + * constants and so are computed at compile time. SHIFT_HZ (computed in + * timex.h) adjusts the scaling for different HZ values. + */ +#define SEC_JIFFIE_SC (30 - SHIFT_HZ) +#define NSEC_JIFFIE_SC (SEC_JIFFIE_SC + 30) +#define USEC_JIFFIE_SC (SEC_JIFFIE_SC + 20) +#define SEC_CONVERSION ((unsigned long)(((u64)NSEC_PER_SEC << SEC_JIFFIE_SC) /\ + (u64)TICK_NSEC(TICK_USEC))) +#define NSEC_CONVERSION ((unsigned long)(((u64)1 << NSEC_JIFFIE_SC) / \ + (u64)TICK_NSEC(TICK_USEC))) +#define USEC_CONVERSION \ + ((unsigned long)(((u64)NSEC_PER_USEC << USEC_JIFFIE_SC)/ \ + (u64)TICK_NSEC(TICK_USEC))) +#define MAX_SEC_IN_JIFFIES \ + (u32)((u64)((u64)MAX_JIFFY_OFFSET * TICK_NSEC(TICK_USEC)) / NSEC_PER_SEC) static __inline__ unsigned long timespec_to_jiffies(struct timespec *value) { unsigned long sec = value->tv_sec; - long nsec = value->tv_nsec; + long nsec = value->tv_nsec + TICK_NSEC(TICK_USEC) - 1; - if (sec >= (MAX_JIFFY_OFFSET / HZ)) + if (sec >= MAX_SEC_IN_JIFFIES) return MAX_JIFFY_OFFSET; - nsec += 1000000000L / HZ - 1; - nsec /= 1000000000L / HZ; - return HZ * sec + nsec; + return (((u64)sec * SEC_CONVERSION) + + (((u64)nsec * NSEC_CONVERSION) >> + (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; + } static __inline__ void jiffies_to_timespec(unsigned long jiffies, struct timespec *value) { - value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ); - value->tv_sec = jiffies / HZ; + /* + * Convert jiffies to nanoseconds and seperate with + * one divide. + */ + u64 nsec = (u64)jiffies * TICK_NSEC(TICK_USEC); + value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_nsec); } /* Same for "timeval" */ @@ -85,20 +122,25 @@ static __inline__ unsigned long timeval_to_jiffies(struct timeval *value) { unsigned long sec = value->tv_sec; - long usec = value->tv_usec; + long usec = value->tv_usec + USEC_PER_SEC / HZ - 1; - if (sec >= (MAX_JIFFY_OFFSET / HZ)) + if (sec >= MAX_SEC_IN_JIFFIES) return MAX_JIFFY_OFFSET; - usec += 1000000L / HZ - 1; - usec /= 1000000L / HZ; - return HZ * sec + usec; + return (((u64)sec * SEC_CONVERSION) + + (((u64)usec * USEC_CONVERSION) >> + (USEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; } static __inline__ void jiffies_to_timeval(unsigned long jiffies, struct timeval *value) { - value->tv_usec = (jiffies % HZ) * (1000000L / HZ); - value->tv_sec = jiffies / HZ; + /* + * Convert jiffies to nanoseconds and seperate with + * one divide. + */ + u64 nsec = (u64)jiffies * TICK_NSEC(TICK_USEC); + value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec); + value->tv_usec /= NSEC_PER_USEC; } static __inline__ int timespec_equal(struct timespec *a, struct timespec *b) @@ -140,6 +182,7 @@ mktime (unsigned int year, unsigned int mon, } extern struct timespec xtime; +extern struct timespec wall_to_monotonic; extern seqlock_t xtime_lock; static inline unsigned long get_seconds(void) @@ -200,6 +243,9 @@ struct itimerval { #define CLOCK_MONOTONIC_HR 5 #define MAX_CLOCKS 6 +#define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC | \ + CLOCK_REALTIME_HR | CLOCK_MONOTONIC_HR) +#define CLOCKS_MONO (CLOCK_MONOTONIC & CLOCK_MONOTONIC_HR) /* * The various flags for setting POSIX.1b interval timers. diff --git a/include/linux/timex.h b/include/linux/timex.h index 5b2b0ac18ae7..6c00606c6e33 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -51,7 +51,6 @@ #ifndef _LINUX_TIMEX_H #define _LINUX_TIMEX_H -#include <linux/time.h> #include <asm/param.h> /* @@ -177,6 +176,7 @@ /* a value TUSEC for TICK_USEC (can be set bij adjtimex) */ #define TICK_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8)) +#include <linux/time.h> /* * syscall interface - used (mainly by NTP daemon) * to discipline kernel clock oscillator diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index d90763253759..570778ddeae9 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -27,7 +27,8 @@ extern void *vmalloc_32(unsigned long size); extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot); extern void vfree(void *addr); -extern void *vmap(struct page **pages, unsigned int count); +extern void *vmap(struct page **pages, unsigned int count, + unsigned long flags, pgprot_t prot); extern void vunmap(void *addr); /* |
