Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull more s390 updates from Martin Schwidefsky:
 "The big thing in this second merge for s390 is the new eBPF JIT from
  Michael which replaces the old 32-bit backend.

  The remaining commits are bug fixes"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/pci: add locking for fmb access
  s390/pci: extract software counters from fmb
  s390/dasd: Fix unresumed device after suspend/resume having no paths
  s390/dasd: fix unresumed device after suspend/resume
  s390/dasd: fix inability to set a DASD device offline
  s390/mm: Fix memory hotplug for unaligned standby memory
  s390/bpf: Add s390x eBPF JIT compiler backend
  s390: Use bool function return values of true/false not 1/0
This commit is contained in:
Linus Torvalds 2015-04-20 10:15:33 -07:00
commit b19a42e3cb
12 changed files with 1348 additions and 841 deletions

View file

@ -579,7 +579,8 @@ void dasd_kick_device(struct dasd_device *device)
{
dasd_get_device(device);
/* queue call to dasd_kick_device to the kernel event daemon. */
schedule_work(&device->kick_work);
if (!schedule_work(&device->kick_work))
dasd_put_device(device);
}
EXPORT_SYMBOL(dasd_kick_device);
@ -599,7 +600,8 @@ void dasd_reload_device(struct dasd_device *device)
{
dasd_get_device(device);
/* queue call to dasd_reload_device to the kernel event daemon. */
schedule_work(&device->reload_device);
if (!schedule_work(&device->reload_device))
dasd_put_device(device);
}
EXPORT_SYMBOL(dasd_reload_device);
@ -619,7 +621,8 @@ void dasd_restore_device(struct dasd_device *device)
{
dasd_get_device(device);
/* queue call to dasd_restore_device to the kernel event daemon. */
schedule_work(&device->restore_device);
if (!schedule_work(&device->restore_device))
dasd_put_device(device);
}
/*
@ -2163,18 +2166,22 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
cqr->intrc = -ENOLINK;
continue;
}
/* Don't try to start requests if device is stopped */
if (interruptible) {
rc = wait_event_interruptible(
generic_waitq, !(device->stopped));
if (rc == -ERESTARTSYS) {
cqr->status = DASD_CQR_FAILED;
maincqr->intrc = rc;
continue;
}
} else
wait_event(generic_waitq, !(device->stopped));
/*
* Don't try to start requests if device is stopped
* except path verification requests
*/
if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags)) {
if (interruptible) {
rc = wait_event_interruptible(
generic_waitq, !(device->stopped));
if (rc == -ERESTARTSYS) {
cqr->status = DASD_CQR_FAILED;
maincqr->intrc = rc;
continue;
}
} else
wait_event(generic_waitq, !(device->stopped));
}
if (!cqr->callback)
cqr->callback = dasd_wakeup_cb;
@ -2524,6 +2531,11 @@ static void __dasd_process_request_queue(struct dasd_block *block)
__blk_end_request_all(req, -EIO);
return;
}
/* if device ist stopped do not fetch new requests */
if (basedev->stopped)
return;
/* Now we try to fetch requests from the request queue */
while ((req = blk_peek_request(queue))) {
if (basedev->features & DASD_FEATURE_READONLY &&

View file

@ -1628,7 +1628,8 @@ static void dasd_eckd_kick_validate_server(struct dasd_device *device)
return;
}
/* queue call to do_validate_server to the kernel event daemon. */
schedule_work(&device->kick_validate);
if (!schedule_work(&device->kick_validate))
dasd_put_device(device);
}
static u32 get_fcx_max_data(struct dasd_device *device)

View file

@ -315,10 +315,29 @@ static int sclp_mem_change_state(unsigned long start, unsigned long size,
rc |= sclp_assign_storage(incr->rn);
else
sclp_unassign_storage(incr->rn);
if (rc == 0)
incr->standby = online ? 0 : 1;
}
return rc ? -EIO : 0;
}
static bool contains_standby_increment(unsigned long start, unsigned long end)
{
struct memory_increment *incr;
unsigned long istart;
list_for_each_entry(incr, &sclp_mem_list, list) {
istart = rn2addr(incr->rn);
if (end - 1 < istart)
continue;
if (start > istart + sclp_rzm - 1)
continue;
if (incr->standby)
return true;
}
return false;
}
static int sclp_mem_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
@ -334,8 +353,16 @@ static int sclp_mem_notifier(struct notifier_block *nb,
for_each_clear_bit(id, sclp_storage_ids, sclp_max_storage_id + 1)
sclp_attach_storage(id);
switch (action) {
case MEM_ONLINE:
case MEM_GOING_OFFLINE:
/*
* We do not allow to set memory blocks offline that contain
* standby memory. This is done to simplify the "memory online"
* case.
*/
if (contains_standby_increment(start, start + size))
rc = -EPERM;
break;
case MEM_ONLINE:
case MEM_CANCEL_OFFLINE:
break;
case MEM_GOING_ONLINE:
@ -361,6 +388,21 @@ static struct notifier_block sclp_mem_nb = {
.notifier_call = sclp_mem_notifier,
};
static void __init align_to_block_size(unsigned long long *start,
unsigned long long *size)
{
unsigned long long start_align, size_align, alignment;
alignment = memory_block_size_bytes();
start_align = roundup(*start, alignment);
size_align = rounddown(*start + *size, alignment) - start_align;
pr_info("Standby memory at 0x%llx (%lluM of %lluM usable)\n",
*start, size_align >> 20, *size >> 20);
*start = start_align;
*size = size_align;
}
static void __init add_memory_merged(u16 rn)
{
static u16 first_rn, num;
@ -382,7 +424,9 @@ static void __init add_memory_merged(u16 rn)
goto skip_add;
if (memory_end_set && (start + size > memory_end))
size = memory_end - start;
add_memory(0, start, size);
align_to_block_size(&start, &size);
if (size)
add_memory(0, start, size);
skip_add:
first_rn = rn;
num = 1;