Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 276371
b: refs/heads/master
c: 52cef18
h: refs/heads/master
i:
  276369: dbcde41
  276367: d160019
v: v3
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Dec 5, 2011
1 parent 08c3c17 commit ce09e06
Show file tree
Hide file tree
Showing 21 changed files with 130 additions and 311 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7125faceabe43067293d0c9e2ef7154ecea51721
refs/heads/master: 52cef189165d74a5d6030184a8e05595194c69ca
8 changes: 4 additions & 4 deletions trunk/arch/s390/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -599,10 +599,10 @@ static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
skey = page_get_storage_key(address);
bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
/* Clear page changed & referenced bit in the storage key */
if (bits & _PAGE_CHANGED)
page_set_storage_key(address, skey ^ bits, 1);
else if (bits)
page_reset_referenced(address);
if (bits) {
skey ^= bits;
page_set_storage_key(address, skey, 1);
}
/* Transfer page changed & referenced bit to guest bits in pgste */
pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */
/* Get host changed & referenced bits from pgste */
Expand Down
30 changes: 12 additions & 18 deletions trunk/arch/s390/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,13 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))))
/* Invalid psw mask. */
return -EINVAL;
if (addr == (addr_t) &dummy->regs.psw.addr)
/*
* The debugger changed the instruction address,
* reset system call restart, see signal.c:do_signal
*/
task_thread_info(child)->system_call = 0;

*(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;

} else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
Expand Down Expand Up @@ -607,6 +614,11 @@ static int __poke_user_compat(struct task_struct *child,
/* Transfer 31 bit amode bit to psw mask. */
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) |
(__u64)(tmp & PSW32_ADDR_AMODE);
/*
* The debugger changed the instruction address,
* reset system call restart, see signal.c:do_signal
*/
task_thread_info(child)->system_call = 0;
} else {
/* gpr 0-15 */
*(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp;
Expand Down Expand Up @@ -893,14 +905,6 @@ static int s390_last_break_get(struct task_struct *target,
return 0;
}

static int s390_last_break_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
return 0;
}

#endif

static int s390_system_call_get(struct task_struct *target,
Expand Down Expand Up @@ -947,7 +951,6 @@ static const struct user_regset s390_regsets[] = {
.size = sizeof(long),
.align = sizeof(long),
.get = s390_last_break_get,
.set = s390_last_break_set,
},
#endif
[REGSET_SYSTEM_CALL] = {
Expand Down Expand Up @@ -1113,14 +1116,6 @@ static int s390_compat_last_break_get(struct task_struct *target,
return 0;
}

static int s390_compat_last_break_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
return 0;
}

static const struct user_regset s390_compat_regsets[] = {
[REGSET_GENERAL] = {
.core_note_type = NT_PRSTATUS,
Expand All @@ -1144,7 +1139,6 @@ static const struct user_regset s390_compat_regsets[] = {
.size = sizeof(long),
.align = sizeof(long),
.get = s390_compat_last_break_get,
.set = s390_compat_last_break_set,
},
[REGSET_SYSTEM_CALL] = {
.core_note_type = NT_S390_SYSTEM_CALL,
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/s390/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ static unsigned long __init find_crash_base(unsigned long crash_size,
*msg = "first memory chunk must be at least crashkernel size";
return 0;
}
if (OLDMEM_BASE && crash_size == OLDMEM_SIZE)
if (is_kdump_kernel() && (crash_size == OLDMEM_SIZE))
return OLDMEM_BASE;

for (i = MEMORY_CHUNKS - 1; i >= 0; i--) {
Expand Down
8 changes: 5 additions & 3 deletions trunk/arch/s390/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,9 @@ void do_signal(struct pt_regs *regs)
regs->svc_code >> 16);
break;
}
/* No longer in a system call */
clear_thread_flag(TIF_SYSCALL);
}
/* No longer in a system call */
clear_thread_flag(TIF_SYSCALL);

if ((is_compat_task() ?
handle_signal32(signr, &ka, &info, oldset, regs) :
Expand All @@ -486,7 +486,6 @@ void do_signal(struct pt_regs *regs)
}

/* No handlers present - check for system call restart */
clear_thread_flag(TIF_SYSCALL);
if (current_thread_info()->system_call) {
regs->svc_code = current_thread_info()->system_call;
switch (regs->gprs[2]) {
Expand All @@ -501,6 +500,9 @@ void do_signal(struct pt_regs *regs)
regs->gprs[2] = regs->orig_gpr2;
set_thread_flag(TIF_SYSCALL);
break;
default:
clear_thread_flag(TIF_SYSCALL);
break;
}
}

Expand Down
23 changes: 1 addition & 22 deletions trunk/arch/x86/include/asm/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,6 @@ extern int no_timer_check;
* (mathieu.desnoyers@polymtl.ca)
*
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
*
* In:
*
* ns = cycles * cyc2ns_scale / SC
*
* Although we may still have enough bits to store the value of ns,
* in some cases, we may not have enough bits to store cycles * cyc2ns_scale,
* leading to an incorrect result.
*
* To avoid this, we can decompose 'cycles' into quotient and remainder
* of division by SC. Then,
*
* ns = (quot * SC + rem) * cyc2ns_scale / SC
* = quot * cyc2ns_scale + (rem * cyc2ns_scale) / SC
*
* - sqazi@google.com
*/

DECLARE_PER_CPU(unsigned long, cyc2ns);
Expand All @@ -57,14 +41,9 @@ DECLARE_PER_CPU(unsigned long long, cyc2ns_offset);

static inline unsigned long long __cycles_2_ns(unsigned long long cyc)
{
unsigned long long quot;
unsigned long long rem;
int cpu = smp_processor_id();
unsigned long long ns = per_cpu(cyc2ns_offset, cpu);
quot = (cyc >> CYC2NS_SCALE_FACTOR);
rem = cyc & ((1ULL << CYC2NS_SCALE_FACTOR) - 1);
ns += quot * per_cpu(cyc2ns, cpu) +
((rem * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR);
ns += cyc * per_cpu(cyc2ns, cpu) >> CYC2NS_SCALE_FACTOR;
return ns;
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/gpio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o
obj-$(CONFIG_MACH_KS8695) += gpio-ks8695.o
obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o
obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
Expand Down
7 changes: 5 additions & 2 deletions trunk/drivers/s390/cio/chsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,10 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data)
int chsc_chp_vary(struct chp_id chpid, int on)
{
struct channel_path *chp = chpid_to_chp(chpid);
struct chp_link link;

memset(&link, 0, sizeof(struct chp_link));
link.chpid = chpid;
/* Wait until previous actions have settled. */
css_wait_for_slow_path();
/*
Expand All @@ -539,10 +542,10 @@ int chsc_chp_vary(struct chp_id chpid, int on)
/* Try to update the channel path descritor. */
chsc_determine_base_channel_path_desc(chpid, &chp->desc);
for_each_subchannel_staged(s390_subchannel_vary_chpid_on,
__s390_vary_chpid_on, &chpid);
__s390_vary_chpid_on, &link);
} else
for_each_subchannel_staged(s390_subchannel_vary_chpid_off,
NULL, &chpid);
NULL, &link);

return 0;
}
Expand Down
5 changes: 0 additions & 5 deletions trunk/drivers/s390/cio/cio.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,8 @@ struct schib {
__u8 mda[4]; /* model dependent area */
} __attribute__ ((packed,aligned(4)));

/*
* When rescheduled, todo's with higher values will overwrite those
* with lower values.
*/
enum sch_todo {
SCH_TODO_NOTHING,
SCH_TODO_EVAL,
SCH_TODO_UNREG,
};

Expand Down
104 changes: 45 additions & 59 deletions trunk/drivers/s390/cio/css.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,51 @@ void css_sch_device_unregister(struct subchannel *sch)
}
EXPORT_SYMBOL_GPL(css_sch_device_unregister);

static void css_sch_todo(struct work_struct *work)
{
struct subchannel *sch;
enum sch_todo todo;

sch = container_of(work, struct subchannel, todo_work);
/* Find out todo. */
spin_lock_irq(sch->lock);
todo = sch->todo;
CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid,
sch->schid.sch_no, todo);
sch->todo = SCH_TODO_NOTHING;
spin_unlock_irq(sch->lock);
/* Perform todo. */
if (todo == SCH_TODO_UNREG)
css_sch_device_unregister(sch);
/* Release workqueue ref. */
put_device(&sch->dev);
}

/**
* css_sched_sch_todo - schedule a subchannel operation
* @sch: subchannel
* @todo: todo
*
* Schedule the operation identified by @todo to be performed on the slow path
* workqueue. Do nothing if another operation with higher priority is already
* scheduled. Needs to be called with subchannel lock held.
*/
void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo)
{
CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n",
sch->schid.ssid, sch->schid.sch_no, todo);
if (sch->todo >= todo)
return;
/* Get workqueue ref. */
if (!get_device(&sch->dev))
return;
sch->todo = todo;
if (!queue_work(cio_work_q, &sch->todo_work)) {
/* Already queued, release workqueue ref. */
put_device(&sch->dev);
}
}

static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw)
{
int i;
Expand Down Expand Up @@ -421,65 +466,6 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow)
css_schedule_eval(schid);
}

/**
* css_sched_sch_todo - schedule a subchannel operation
* @sch: subchannel
* @todo: todo
*
* Schedule the operation identified by @todo to be performed on the slow path
* workqueue. Do nothing if another operation with higher priority is already
* scheduled. Needs to be called with subchannel lock held.
*/
void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo)
{
CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n",
sch->schid.ssid, sch->schid.sch_no, todo);
if (sch->todo >= todo)
return;
/* Get workqueue ref. */
if (!get_device(&sch->dev))
return;
sch->todo = todo;
if (!queue_work(cio_work_q, &sch->todo_work)) {
/* Already queued, release workqueue ref. */
put_device(&sch->dev);
}
}

static void css_sch_todo(struct work_struct *work)
{
struct subchannel *sch;
enum sch_todo todo;
int ret;

sch = container_of(work, struct subchannel, todo_work);
/* Find out todo. */
spin_lock_irq(sch->lock);
todo = sch->todo;
CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid,
sch->schid.sch_no, todo);
sch->todo = SCH_TODO_NOTHING;
spin_unlock_irq(sch->lock);
/* Perform todo. */
switch (todo) {
case SCH_TODO_NOTHING:
break;
case SCH_TODO_EVAL:
ret = css_evaluate_known_subchannel(sch, 1);
if (ret == -EAGAIN) {
spin_lock_irq(sch->lock);
css_sched_sch_todo(sch, todo);
spin_unlock_irq(sch->lock);
}
break;
case SCH_TODO_UNREG:
css_sch_device_unregister(sch);
break;
}
/* Release workqueue ref. */
put_device(&sch->dev);
}

static struct idset *slow_subchannel_set;
static spinlock_t slow_subchannel_lock;
static wait_queue_head_t css_eval_wq;
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/s390/cio/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -1868,9 +1868,9 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev)
*/
cdev->private->flags.resuming = 1;
cdev->private->path_new_mask = LPM_ANYPATH;
css_sched_sch_todo(sch, SCH_TODO_EVAL);
css_schedule_eval(sch->schid);
spin_unlock_irq(sch->lock);
css_wait_for_slow_path();
css_complete_work();

/* cdev may have been moved to a different subchannel. */
sch = to_subchannel(cdev->dev.parent);
Expand Down
30 changes: 8 additions & 22 deletions trunk/drivers/s390/cio/device_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,26 +496,8 @@ static void ccw_device_reset_path_events(struct ccw_device *cdev)
cdev->private->pgid_reset_mask = 0;
}

static void create_fake_irb(struct irb *irb, int type)
{
memset(irb, 0, sizeof(*irb));
if (type == FAKE_CMD_IRB) {
struct cmd_scsw *scsw = &irb->scsw.cmd;
scsw->cc = 1;
scsw->fctl = SCSW_FCTL_START_FUNC;
scsw->actl = SCSW_ACTL_START_PEND;
scsw->stctl = SCSW_STCTL_STATUS_PEND;
} else if (type == FAKE_TM_IRB) {
struct tm_scsw *scsw = &irb->scsw.tm;
scsw->x = 1;
scsw->cc = 1;
scsw->fctl = SCSW_FCTL_START_FUNC;
scsw->actl = SCSW_ACTL_START_PEND;
scsw->stctl = SCSW_STCTL_STATUS_PEND;
}
}

void ccw_device_verify_done(struct ccw_device *cdev, int err)
void
ccw_device_verify_done(struct ccw_device *cdev, int err)
{
struct subchannel *sch;

Expand All @@ -538,8 +520,12 @@ void ccw_device_verify_done(struct ccw_device *cdev, int err)
ccw_device_done(cdev, DEV_STATE_ONLINE);
/* Deliver fake irb to device driver, if needed. */
if (cdev->private->flags.fake_irb) {
create_fake_irb(&cdev->private->irb,
cdev->private->flags.fake_irb);
memset(&cdev->private->irb, 0, sizeof(struct irb));
cdev->private->irb.scsw.cmd.cc = 1;
cdev->private->irb.scsw.cmd.fctl = SCSW_FCTL_START_FUNC;
cdev->private->irb.scsw.cmd.actl = SCSW_ACTL_START_PEND;
cdev->private->irb.scsw.cmd.stctl =
SCSW_STCTL_STATUS_PEND;
cdev->private->flags.fake_irb = 0;
if (cdev->handler)
cdev->handler(cdev, cdev->private->intparm,
Expand Down
Loading

0 comments on commit ce09e06

Please sign in to comment.