diff options
-rw-r--r-- | arch/mips/kernel/rtlx.c | 15 | ||||
-rw-r--r-- | arch/mips/kernel/vpe.c | 77 |
2 files changed, 50 insertions, 42 deletions
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index a10ebfdc28a..364f066cb49 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -72,8 +72,9 @@ static void rtlx_dispatch(void) */ static irqreturn_t rtlx_interrupt(int irq, void *dev_id) { + unsigned int vpeflags; + unsigned long flags; int i; - unsigned int flags, vpeflags; /* Ought not to be strictly necessary for SMTC builds */ local_irq_save(flags); @@ -392,20 +393,12 @@ out: static int file_open(struct inode *inode, struct file *filp) { - int minor = iminor(inode); - int err; - - lock_kernel(); - err = rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1); - unlock_kernel(); - return err; + return rtlx_open(iminor(inode), (filp->f_flags & O_NONBLOCK) ? 0 : 1); } static int file_release(struct inode *inode, struct file *filp) { - int minor = iminor(inode); - - return rtlx_release(minor); + return rtlx_release(iminor(inode)); } static unsigned int file_poll(struct file *file, poll_table * wait) diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index eb6c4c5b7fb..03092ab2a29 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -144,14 +144,15 @@ struct tc { }; struct { - /* Virtual processing elements */ - struct list_head vpe_list; - - /* Thread contexts */ - struct list_head tc_list; + spinlock_t vpe_list_lock; + struct list_head vpe_list; /* Virtual processing elements */ + spinlock_t tc_list_lock; + struct list_head tc_list; /* Thread contexts */ } vpecontrol = { - .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list), - .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list) + .vpe_list_lock = SPIN_LOCK_UNLOCKED, + .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list), + .tc_list_lock = SPIN_LOCK_UNLOCKED, + .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list) }; static void release_progmem(void *ptr); @@ -159,28 +160,38 @@ static void release_progmem(void *ptr); /* get the vpe associated with this minor */ static struct vpe *get_vpe(int minor) { - struct vpe *v; + struct vpe *res, *v; if (!cpu_has_mipsmt) return NULL; + res = NULL; + spin_lock(&vpecontrol.vpe_list_lock); list_for_each_entry(v, &vpecontrol.vpe_list, list) { - if (v->minor == minor) - return v; + if (v->minor == minor) { + res = v; + break; + } } + spin_unlock(&vpecontrol.vpe_list_lock); - return NULL; + return res; } /* get the vpe associated with this minor */ static struct tc *get_tc(int index) { - struct tc *t; + struct tc *res, *t; + res = NULL; + spin_lock(&vpecontrol.tc_list_lock); list_for_each_entry(t, &vpecontrol.tc_list, list) { - if (t->index == index) - return t; + if (t->index == index) { + res = t; + break; + } } + spin_unlock(&vpecontrol.tc_list_lock); return NULL; } @@ -190,15 +201,17 @@ static struct vpe *alloc_vpe(int minor) { struct vpe *v; - if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { + if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) return NULL; - } INIT_LIST_HEAD(&v->tc); + spin_lock(&vpecontrol.vpe_list_lock); list_add_tail(&v->list, &vpecontrol.vpe_list); + spin_unlock(&vpecontrol.vpe_list_lock); INIT_LIST_HEAD(&v->notify); v->minor = minor; + return v; } @@ -212,7 +225,10 @@ static struct tc *alloc_tc(int index) INIT_LIST_HEAD(&tc->tc); tc->index = index; + + spin_lock(&vpecontrol.tc_list_lock); list_add_tail(&tc->list, &vpecontrol.tc_list); + spin_unlock(&vpecontrol.tc_list_lock); out: return tc; @@ -227,7 +243,7 @@ static void release_vpe(struct vpe *v) kfree(v); } -static void dump_mtregs(void) +static void __maybe_unused dump_mtregs(void) { unsigned long val; @@ -1048,20 +1064,19 @@ static int vpe_open(struct inode *inode, struct file *filp) enum vpe_state state; struct vpe_notifications *not; struct vpe *v; - int ret, err = 0; + int ret; - lock_kernel(); if (minor != iminor(inode)) { /* assume only 1 device at the moment. */ - printk(KERN_WARNING "VPE loader: only vpe1 is supported\n"); - err = -ENODEV; - goto out; + pr_warning("VPE loader: only vpe1 is supported\n"); + + return -ENODEV; } if ((v = get_vpe(tclimit)) == NULL) { - printk(KERN_WARNING "VPE loader: unable to get vpe\n"); - err = -ENODEV; - goto out; + pr_warning("VPE loader: unable to get vpe\n"); + + return -ENODEV; } state = xchg(&v->state, VPE_STATE_INUSE); @@ -1101,8 +1116,8 @@ static int vpe_open(struct inode *inode, struct file *filp) v->shared_ptr = NULL; v->__start = 0; -out: unlock_kernel(); + return 0; } @@ -1594,14 +1609,14 @@ static void __exit vpe_module_exit(void) { struct vpe *v, *n; + device_del(&vpe_device); + unregister_chrdev(major, module_name); + + /* No locking needed here */ list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) { - if (v->state != VPE_STATE_UNUSED) { + if (v->state != VPE_STATE_UNUSED) release_vpe(v); - } } - - device_del(&vpe_device); - unregister_chrdev(major, module_name); } module_init(vpe_module_init); |