Commit 8ef44e25 authored by Anton Blanchard's avatar Anton Blanchard

Merge samba.org:/scratch/anton/linux-2.5

into samba.org:/scratch/anton/sfr
parents 5679732a 8da730e9
......@@ -480,7 +480,7 @@ void __init cpu_init (void)
*/
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
if(current->mm)
if (current->mm)
BUG();
enter_lazy_tlb(&init_mm, current, cpu);
......@@ -508,7 +508,7 @@ void __init cpu_init (void)
/*
* Force FPU initialization:
*/
clear_thread_flag(TIF_USEDFPU);
current_thread_info()->status = 0;
current->used_math = 0;
stts();
}
......@@ -54,9 +54,11 @@ void init_fpu(struct task_struct *tsk)
void kernel_fpu_begin(void)
{
struct thread_info *thread = current_thread_info();
preempt_disable();
if (test_thread_flag(TIF_USEDFPU)) {
__save_init_fpu(current);
if (thread->status & TS_USEDFPU) {
__save_init_fpu(thread->task);
return;
}
clts();
......
......@@ -275,6 +275,15 @@ void release_thread(struct task_struct *dead_task)
release_x86_irqs(dead_task);
}
/*
* This gets called before we allocate a new thread and copy
* the current task into it.
*/
void prepare_to_copy(struct task_struct *tsk)
{
unlazy_fpu(tsk);
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
......@@ -297,9 +306,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
savesegment(gs,p->thread.gs);
tsk = current;
unlazy_fpu(tsk);
struct_cpy(&p->thread.i387, &tsk->thread.i387);
if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
if (!p->thread.ts_io_bitmap)
......
......@@ -737,13 +737,14 @@ asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs,
*/
asmlinkage void math_state_restore(struct pt_regs regs)
{
struct task_struct *tsk = current;
clts(); /* Allow maths ops (or we recurse) */
struct thread_info *thread = current_thread_info();
struct task_struct *tsk = thread->task;
clts(); /* Allow maths ops (or we recurse) */
if (!tsk->used_math)
init_fpu(tsk);
restore_fpu(tsk);
set_thread_flag(TIF_USEDFPU); /* So we fnsave on switch_to() */
thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */
}
#ifndef CONFIG_MATH_EMULATION
......
......@@ -83,6 +83,8 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
return NULL;
memset(sglist, 0, sizeof(*sglist) * nr_pages);
if (NULL == pages[0])
goto nopage;
if (PageHighMem(pages[0]))
/* DMA to highmem pages might not work */
goto highmem;
......@@ -118,7 +120,7 @@ int videobuf_lock(struct page **pages, int nr_pages)
for (i = 0; i < nr_pages; i++)
if (TryLockPage(pages[i]))
goto err;
dprintk(2,"lock ok\n");
dprintk(2,"lock ok [%d pages]\n",nr_pages);
return 0;
err:
......@@ -136,7 +138,7 @@ int videobuf_unlock(struct page **pages, int nr_pages)
dprintk(2,"unlock start ...\n");
for (i = 0; i < nr_pages; i++)
unlock_page(pages[i]);
dprintk(2,"unlock ok\n");
dprintk(2,"unlock ok [%d pages]\n",nr_pages);
return 0;
}
......@@ -270,7 +272,7 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
/* --------------------------------------------------------------------- */
void* videobuf_alloc(int size)
void* videobuf_alloc(unsigned int size)
{
struct videobuf_buffer *vb;
......@@ -340,7 +342,7 @@ videobuf_queue_init(struct videobuf_queue *q,
spinlock_t *irqlock,
enum v4l2_buf_type type,
enum v4l2_field field,
int msize)
unsigned int msize)
{
memset(q,0,sizeof(*q));
......@@ -417,11 +419,11 @@ videobuf_next_field(struct videobuf_queue *q)
if (V4L2_FIELD_ALTERNATE == field) {
if (V4L2_FIELD_TOP == q->last) {
field = V4L2_FIELD_TOP;
q->last = V4L2_FIELD_TOP;
} else {
field = V4L2_FIELD_BOTTOM;
q->last = V4L2_FIELD_BOTTOM;
} else {
field = V4L2_FIELD_TOP;
q->last = V4L2_FIELD_TOP;
}
}
return field;
......@@ -463,7 +465,8 @@ int
videobuf_reqbufs(struct file *file, struct videobuf_queue *q,
struct v4l2_requestbuffers *req)
{
int size,count,retval;
unsigned int size,count;
int retval;
if (req->type != q->type)
return -EINVAL;
......@@ -477,6 +480,8 @@ videobuf_reqbufs(struct file *file, struct videobuf_queue *q,
size = 0;
q->ops->buf_setup(file,&count,&size);
size = PAGE_ALIGN(size);
dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n",
count, size, (count*size)>>PAGE_SHIFT);
retval = videobuf_mmap_setup(file,q,count,size);
if (retval < 0)
......@@ -660,7 +665,10 @@ videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q,
retval = videobuf_waiton(q->read_buf,0,0);
if (0 == retval) {
videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
retval = q->read_buf->size;
if (STATE_ERROR == q->read_buf->state)
retval = -EIO;
else
retval = q->read_buf->size;
}
done:
......@@ -676,7 +684,8 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
{
enum v4l2_field field;
unsigned long flags;
int retval, bytes, size, nbufs;
unsigned size, nbufs, bytes;
int retval;
down(&q->lock);
......@@ -686,7 +695,7 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
count >= size &&
!(file->f_flags & O_NONBLOCK)) {
retval = videobuf_read_zerocopy(file,q,data,count,ppos);
if (retval >= 0)
if (retval >= 0 || retval == -EIO)
/* ok, all done */
goto done;
/* fallback to kernel bounce buffer on failures */
......@@ -714,6 +723,15 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
goto done;
videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
if (STATE_ERROR == q->read_buf->state) {
/* catch I/O errors */
q->ops->buf_release(file,q->read_buf);
kfree(q->read_buf);
q->read_buf = NULL;
retval = -EIO;
goto done;
}
/* copy to userspace */
bytes = count;
if (bytes > q->read_buf->size - q->read_off)
......@@ -788,8 +806,8 @@ ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q,
char *data, size_t count, loff_t *ppos,
int vbihack)
{
unsigned int *fc;
int err, bytes, retval;
unsigned int *fc, bytes;
int err, retval;
unsigned long flags;
down(&q->lock);
......@@ -968,9 +986,10 @@ static struct vm_operations_struct videobuf_vm_ops =
};
int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q,
int bcount, int bsize)
unsigned int bcount, unsigned int bsize)
{
int i,err;
unsigned int i;
int err;
err = videobuf_mmap_free(file,q);
if (0 != err)
......@@ -1008,7 +1027,8 @@ int videobuf_mmap_mapper(struct vm_area_struct *vma,
struct videobuf_queue *q)
{
struct videobuf_mapping *map;
int first,last,size,i,retval;
unsigned int first,last,size,i;
int retval;
down(&q->lock);
retval = -EINVAL;
......@@ -1025,7 +1045,7 @@ int videobuf_mmap_mapper(struct vm_area_struct *vma,
for (first = 0; first < VIDEO_MAX_FRAME; first++) {
if (NULL == q->bufs[first])
continue;
if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
break;
}
if (VIDEO_MAX_FRAME == first) {
......
......@@ -110,7 +110,7 @@ struct videobuf_buffer;
struct videobuf_queue;
struct videobuf_mapping {
int count;
unsigned int count;
int highmem_ok;
unsigned long start;
unsigned long end;
......@@ -128,19 +128,19 @@ enum videobuf_state {
};
struct videobuf_buffer {
int i;
unsigned int i;
/* info about the buffer */
int width;
int height;
long size;
unsigned int width;
unsigned int height;
unsigned long size;
enum v4l2_field field;
enum videobuf_state state;
struct videobuf_dmabuf dma;
struct list_head stream; /* QBUF/DQBUF list */
/* for mmap'ed buffers */
off_t boff; /* buffer offset (mmap) */
size_t boff; /* buffer offset (mmap) */
size_t bsize; /* buffer size */
unsigned long baddr; /* buffer addr (userland ptr!) */
struct videobuf_mapping *map;
......@@ -148,12 +148,13 @@ struct videobuf_buffer {
/* touched by irq handler */
struct list_head queue;
wait_queue_head_t done;
int field_count;
unsigned int field_count;
struct timeval ts;
};
struct videobuf_queue_ops {
int (*buf_setup)(struct file *file, int *count, int *size);
int (*buf_setup)(struct file *file,
unsigned int *count, unsigned int *size);
int (*buf_prepare)(struct file *file,struct videobuf_buffer *vb,
enum v4l2_field field);
void (*buf_queue)(struct file *file,struct videobuf_buffer *vb);
......@@ -166,23 +167,23 @@ struct videobuf_queue {
struct pci_dev *pci;
enum v4l2_buf_type type;
int msize;
unsigned int msize;
enum v4l2_field field;
enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */
struct videobuf_buffer *bufs[VIDEO_MAX_FRAME];
struct videobuf_queue_ops *ops;
/* capture via mmap() + ioctl(QBUF/DQBUF) */
int streaming;
unsigned int streaming;
struct list_head stream;
/* capture via read() */
int reading;
int read_off;
unsigned int reading;
unsigned int read_off;
struct videobuf_buffer *read_buf;
};
void* videobuf_alloc(int size);
void* videobuf_alloc(unsigned int size);
int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
int videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb);
......@@ -190,7 +191,8 @@ void videobuf_queue_init(struct videobuf_queue *q,
struct videobuf_queue_ops *ops,
struct pci_dev *pci, spinlock_t *irqlock,
enum v4l2_buf_type type,
enum v4l2_field field, int msize);
enum v4l2_field field,
unsigned int msize);
int videobuf_queue_is_busy(struct videobuf_queue *q);
void videobuf_queue_cancel(struct file *file, struct videobuf_queue *q);
......@@ -218,7 +220,7 @@ unsigned int videobuf_poll_stream(struct file *file,
poll_table *wait);
int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q,
int bcount, int bsize);
unsigned int bcount, unsigned int bsize);
int videobuf_mmap_free(struct file *file, struct videobuf_queue *q);
int videobuf_mmap_mapper(struct vm_area_struct *vma,
struct videobuf_queue *q);
......
......@@ -51,6 +51,9 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
/* Create a kernel thread without removing it from tasklists. */
extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
......
......@@ -62,6 +62,9 @@ struct task_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
......
......@@ -123,6 +123,9 @@ static inline void release_thread(struct task_struct *dead_task)
/* Nothing needs to be done. */
}
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
/*
* Return saved PC of a blocked thread.
*/
......
......@@ -36,7 +36,7 @@ static inline void __save_init_fpu( struct task_struct *tsk )
asm volatile( "fnsave %0 ; fwait"
: "=m" (tsk->thread.i387.fsave) );
}
tsk->thread_info->flags &= ~_TIF_USEDFPU;
tsk->thread_info->status &= ~TS_USEDFPU;
}
static inline void save_init_fpu( struct task_struct *tsk )
......@@ -47,15 +47,15 @@ static inline void save_init_fpu( struct task_struct *tsk )
#define unlazy_fpu( tsk ) do { \
if ((tsk)->thread_info->flags & _TIF_USEDFPU) \
if ((tsk)->thread_info->status & TS_USEDFPU) \
save_init_fpu( tsk ); \
} while (0)
#define clear_fpu( tsk ) \
do { \
if ((tsk)->thread_info->flags & _TIF_USEDFPU) { \
if ((tsk)->thread_info->status & TS_USEDFPU) { \
asm volatile("fwait"); \
(tsk)->thread_info->flags &= ~_TIF_USEDFPU; \
(tsk)->thread_info->status &= ~TS_USEDFPU; \
stts(); \
} \
} while (0)
......
......@@ -446,6 +446,10 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
extern void prepare_to_copy(struct task_struct *tsk);
/*
* create a kernel thread without removing it from tasklists
*/
......
......@@ -25,6 +25,7 @@ struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */
unsigned long status; /* thread-synchronous flags */
__u32 cpu; /* current CPU */
__s32 preempt_count; /* 0 => preemptable, <0 => BUG */
......@@ -43,10 +44,11 @@ struct thread_info {
#define TI_TASK 0x00000000
#define TI_EXEC_DOMAIN 0x00000004
#define TI_FLAGS 0x00000008
#define TI_CPU 0x0000000C
#define TI_PRE_COUNT 0x00000010
#define TI_ADDR_LIMIT 0x00000014
#define TI_RESTART_BLOCK 0x0000018
#define TI_STATUS 0x0000000C
#define TI_CPU 0x00000010
#define TI_PRE_COUNT 0x00000014
#define TI_ADDR_LIMIT 0x00000018
#define TI_RESTART_BLOCK 0x000001C
#endif
......@@ -111,8 +113,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
#define TIF_IRET 5 /* return with iret */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
......@@ -120,12 +121,20 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_IRET (1<<TIF_IRET)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
/*
* Thread-synchronous status.
*
* This is different from the flags in that nobody else
* ever touches our thread-synchronous status, so we don't
* have to worry about atomic accesses.
*/
#define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */
#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */
......@@ -344,6 +344,9 @@ struct task_struct;
# define release_thread(dead_task)
#endif
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
/*
* This is the mechanism for creating a new kernel thread.
*
......
......@@ -112,6 +112,9 @@ static inline void release_thread(struct task_struct *dead_task)
{
}
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
......
......@@ -108,6 +108,9 @@ static inline void release_thread(struct task_struct *dead_task)
{
}
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
......
......@@ -208,6 +208,9 @@ struct thread_struct {
/* Free all resources held by a thread. */
#define release_thread(thread) do { } while(0)
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
......
......@@ -231,6 +231,9 @@ struct thread_struct {
/* Free all resources held by a thread. */
#define release_thread(thread) do { } while(0)
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
......
......@@ -290,6 +290,9 @@ struct mm_struct;
extern void release_thread(struct task_struct *);
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern void map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm);
static inline unsigned long get_wchan(struct task_struct *p)
......
......@@ -608,6 +608,9 @@ struct task_struct;
void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
/*
* Create a new kernel thread.
*/
......
......@@ -601,6 +601,9 @@ struct task_struct;
void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
/*
* Create a new kernel thread.
*/
......
......@@ -114,6 +114,9 @@ struct mm_struct;
extern void release_thread(struct task_struct *);
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
/*
* Return saved PC of a blocked thread.
*/
......
......@@ -129,6 +129,9 @@ struct mm_struct;
extern void release_thread(struct task_struct *);
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
/*
* Return saved PC of a blocked thread.
*/
......
......@@ -134,6 +134,10 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
/*
* create a kernel thread without removing it from tasklists
*/
......
......@@ -139,6 +139,9 @@ extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc,
#define release_thread(tsk) do { } while(0)
extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern unsigned long get_wchan(struct task_struct *);
#define KSTK_EIP(tsk) ((tsk)->thread.kregs->pc)
......
......@@ -186,6 +186,9 @@ do { \
/* Free all resources held by a thread. */
#define release_thread(tsk) do { } while (0)
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
extern unsigned long get_wchan(struct task_struct *task);
......
......@@ -81,6 +81,9 @@ extern inline void release_thread (struct task_struct *dead_task)
{
}
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern int kernel_thread (int (*fn)(void *), void * arg, unsigned long flags);
/* Free current thread data structures etc. */
......
......@@ -267,6 +267,10 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
/*
* create a kernel thread without removing it from tasklists
*/
......
......@@ -214,6 +214,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
struct thread_info *ti;
int cpu = get_cpu();
prepare_to_copy(orig);
tsk = task_cache[cpu];
task_cache[cpu] = NULL;
put_cpu();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment