diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-03 10:26:41 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-03 10:26:41 -0700 |
commit | 8f5759aeb88a47448cd92ab55a016d013b154a98 (patch) | |
tree | a9c0536e10300a95292b99332171837675af1e16 /drivers | |
parent | e5c4ecdc55b6d824365ba7964bcd3185223f9688 (diff) | |
parent | 63aef00b55d37e9fad837a8b38a2c261f0d32041 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux into next
Pull first set of s390 updates from Martin Schwidefsky:
"The biggest change in this patchset is conversion from the bootmem
bitmaps to the memblock code. This conversion requires two common
code patches to introduce the 'physmem' memblock list.
We experimented with ticket spinlocks but in the end decided against
them as they perform poorly on virtualized systems. But the spinlock
cleanup and some small improvements are included.
The uaccess code got another optimization, the get_user/put_user calls
are now inline again for kernel compiles targeted at z10 or newer
machines. This makes the text segment shorter and the code gets a
little bit faster.
And as always some bug fixes"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (31 commits)
s390/lowcore: replace lowcore irb array with a per-cpu variable
s390/lowcore: reserve 96 bytes for IRB in lowcore
s390/facilities: remove extract-cpu-time facility check
s390: require mvcos facility for z10 and newer machines
s390/boot: fix boot of compressed kernel built with gcc 4.9
s390/cio: remove weird assignment during argument evaluation
s390/time: cast tv_nsec to u64 prior to shift in update_vsyscall
s390/oprofile: make return of 0 explicit
s390/spinlock: refactor arch_spin_lock_wait[_flags]
s390/rwlock: add missing local_irq_restore calls
s390/spinlock,rwlock: always to a load-and-test first
s390/cio: fix multiple structure definitions
s390/spinlock: fix system hang with spin_retry <= 0
s390/appldata: add slab.h for kzalloc/kfree
s390/uaccess: provide inline variants of get_user/put_user
s390/pci: add some new arch specific pci attributes
s390/pci: use pdev->dev.groups for attribute creation
s390/pci: use macro for attribute creation
s390/pci: improve state check when processing hotplug events
s390: split TIF bits into CIF, PIF and TIF bits
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/char/Makefile | 2 | ||||
-rw-r--r-- | drivers/s390/char/zcore.c | 44 | ||||
-rw-r--r-- | drivers/s390/cio/ccwreq.c | 4 | ||||
-rw-r--r-- | drivers/s390/cio/chp.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/chp.h | 2 | ||||
-rw-r--r-- | drivers/s390/cio/chsc.h | 11 | ||||
-rw-r--r-- | drivers/s390/cio/chsc_sch.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 9 | ||||
-rw-r--r-- | drivers/s390/cio/cio.h | 2 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 4 | ||||
-rw-r--r-- | drivers/s390/cio/device_ops.c | 13 | ||||
-rw-r--r-- | drivers/s390/cio/eadm_sch.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 12 |
13 files changed, 44 insertions, 65 deletions
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index b69ab17f13fa..629fcc275e92 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile @@ -33,4 +33,4 @@ obj-$(CONFIG_MONWRITER) += monwriter.o obj-$(CONFIG_S390_VMUR) += vmur.o zcore_mod-objs := sclp_sdias.o zcore.o -obj-$(CONFIG_ZFCPDUMP) += zcore_mod.o +obj-$(CONFIG_CRASH_DUMP) += zcore_mod.o diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 3d8e4d63f514..1884653e4472 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -17,6 +17,8 @@ #include <linux/miscdevice.h> #include <linux/debugfs.h> #include <linux/module.h> +#include <linux/memblock.h> + #include <asm/asm-offsets.h> #include <asm/ipl.h> #include <asm/sclp.h> @@ -411,33 +413,24 @@ static ssize_t zcore_memmap_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { return simple_read_from_buffer(buf, count, ppos, filp->private_data, - MEMORY_CHUNKS * CHUNK_INFO_SIZE); + memblock.memory.cnt * CHUNK_INFO_SIZE); } static int zcore_memmap_open(struct inode *inode, struct file *filp) { - int i; + struct memblock_region *reg; char *buf; - struct mem_chunk *chunk_array; + int i = 0; - chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk), - GFP_KERNEL); - if (!chunk_array) - return -ENOMEM; - detect_memory_layout(chunk_array, 0); - buf = kzalloc(MEMORY_CHUNKS * CHUNK_INFO_SIZE, GFP_KERNEL); + buf = kzalloc(memblock.memory.cnt * CHUNK_INFO_SIZE, GFP_KERNEL); if (!buf) { - kfree(chunk_array); return -ENOMEM; } - for (i = 0; i < MEMORY_CHUNKS; i++) { - sprintf(buf + (i * CHUNK_INFO_SIZE), "%016llx %016llx ", - (unsigned long long) chunk_array[i].addr, - (unsigned long long) chunk_array[i].size); - if (chunk_array[i].size == 0) - break; + for_each_memblock(memory, reg) { + sprintf(buf + (i++ * CHUNK_INFO_SIZE), "%016llx %016llx ", + (unsigned long long) reg->base, + (unsigned long long) reg->size); } - kfree(chunk_array); filp->private_data = buf; return nonseekable_open(inode, filp); } @@ -593,21 +586,12 @@ static int __init check_sdias(void) static int __init get_mem_info(unsigned long *mem, unsigned long *end) { - int i; - struct mem_chunk *chunk_array; + struct memblock_region *reg; - chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk), - GFP_KERNEL); - if (!chunk_array) - return -ENOMEM; - detect_memory_layout(chunk_array, 0); - for (i = 0; i < MEMORY_CHUNKS; i++) { - if (chunk_array[i].size == 0) - break; - *mem += chunk_array[i].size; - *end = max(*end, chunk_array[i].addr + chunk_array[i].size); + for_each_memblock(memory, reg) { + *mem += reg->size; + *end = max_t(unsigned long, *end, reg->base + reg->size); } - kfree(chunk_array); return 0; } diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c index 5156264d0c74..07676c22d514 100644 --- a/drivers/s390/cio/ccwreq.c +++ b/drivers/s390/cio/ccwreq.c @@ -46,7 +46,7 @@ static u16 ccwreq_next_path(struct ccw_device *cdev) goto out; } req->retries = req->maxretries; - req->mask = lpm_adjust(req->mask >>= 1, req->lpm); + req->mask = lpm_adjust(req->mask >> 1, req->lpm); out: return req->mask; } @@ -252,7 +252,7 @@ static void ccwreq_log_status(struct ccw_device *cdev, enum io_status status) */ void ccw_request_handler(struct ccw_device *cdev) { - struct irb *irb = (struct irb *)&S390_lowcore.irb; + struct irb *irb = &__get_cpu_var(cio_irb); struct ccw_request *req = &cdev->private->req; enum io_status status; int rc = -EOPNOTSUPP; diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 6c440d4349d4..d497aa05a72f 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -509,7 +509,7 @@ out: * On success return a newly allocated copy of the channel-path description * data associated with the given channel-path ID. Return %NULL on error. */ -void *chp_get_chp_desc(struct chp_id chpid) +struct channel_path_desc *chp_get_chp_desc(struct chp_id chpid) { struct channel_path *chp; struct channel_path_desc *desc; diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h index 9284b785a06f..4efd5b867cc3 100644 --- a/drivers/s390/cio/chp.h +++ b/drivers/s390/cio/chp.h @@ -60,7 +60,7 @@ static inline struct channel_path *chpid_to_chp(struct chp_id chpid) int chp_get_status(struct chp_id chpid); u8 chp_get_sch_opm(struct subchannel *sch); int chp_is_registered(struct chp_id chpid); -void *chp_get_chp_desc(struct chp_id chpid); +struct channel_path_desc *chp_get_chp_desc(struct chp_id chpid); void chp_remove_cmg_attr(struct channel_path *chp); int chp_add_cmg_attr(struct channel_path *chp); int chp_update_desc(struct channel_path *chp); diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index 7e53a9c8b0b9..76c9b50700b2 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h @@ -21,17 +21,6 @@ struct cmg_entry { u32 values[NR_MEASUREMENT_ENTRIES]; } __attribute__ ((packed)); -struct channel_path_desc { - u8 flags; - u8 lsn; - u8 desc; - u8 chpid; - u8 swla; - u8 zeroes; - u8 chla; - u8 chpp; -} __attribute__ ((packed)); - struct channel_path_desc_fmt1 { u8 flags; u8 lsn; diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 1d3661af7bd8..3d22d2a4ce14 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -58,7 +58,7 @@ static void chsc_subchannel_irq(struct subchannel *sch) { struct chsc_private *private = dev_get_drvdata(&sch->dev); struct chsc_request *request = private->request; - struct irb *irb = (struct irb *)&S390_lowcore.irb; + struct irb *irb = &__get_cpu_var(cio_irb); CHSC_LOG(4, "irb"); CHSC_LOG_HEX(4, irb, sizeof(*irb)); diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 9e058c4657a3..77f9c92df4b9 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -46,6 +46,9 @@ debug_info_t *cio_debug_msg_id; debug_info_t *cio_debug_trace_id; debug_info_t *cio_debug_crw_id; +DEFINE_PER_CPU_ALIGNED(struct irb, cio_irb); +EXPORT_PER_CPU_SYMBOL(cio_irb); + /* * Function: cio_debug_init * Initializes three debug logs for common I/O: @@ -560,7 +563,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy) __this_cpu_write(s390_idle.nohz_delay, 1); tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; - irb = (struct irb *) &S390_lowcore.irb; + irb = &__get_cpu_var(cio_irb); sch = (struct subchannel *)(unsigned long) tpi_info->intparm; if (!sch) { /* Clear pending interrupt condition. */ @@ -609,7 +612,7 @@ void cio_tsch(struct subchannel *sch) struct irb *irb; int irq_context; - irb = (struct irb *)&S390_lowcore.irb; + irb = &__get_cpu_var(cio_irb); /* Store interrupt response block to lowcore. */ if (tsch(sch->schid, irb) != 0) /* Not status pending or not operational. */ @@ -746,7 +749,7 @@ __clear_io_subchannel_easy(struct subchannel_id schid) struct tpi_info ti; if (tpi(&ti)) { - tsch(ti.schid, (struct irb *)&S390_lowcore.irb); + tsch(ti.schid, &__get_cpu_var(cio_irb)); if (schid_equal(&ti.schid, &schid)) return 0; } diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index d42f67412bd8..a01376ae1749 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -102,6 +102,8 @@ struct subchannel { struct schib_config config; } __attribute__ ((aligned(8))); +DECLARE_PER_CPU(struct irb, cio_irb); + #define to_subchannel(n) container_of(n, struct subchannel, dev) extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id); diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index c7638c543250..0bc902b3cd84 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -739,7 +739,7 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event) struct irb *irb; int is_cmd; - irb = (struct irb *)&S390_lowcore.irb; + irb = &__get_cpu_var(cio_irb); is_cmd = !scsw_is_tm(&irb->scsw); /* Check for unsolicited interrupt. */ if (!scsw_is_solicited(&irb->scsw)) { @@ -805,7 +805,7 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) { struct irb *irb; - irb = (struct irb *)&S390_lowcore.irb; + irb = &__get_cpu_var(cio_irb); /* Check for unsolicited interrupt. */ if (scsw_stctl(&irb->scsw) == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 4845d64f2842..f3c417943dad 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c @@ -563,14 +563,23 @@ out_unlock: return rc; } -void *ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no) +/** + * chp_get_chp_desc - return newly allocated channel-path descriptor + * @cdev: device to obtain the descriptor for + * @chp_idx: index of the channel path + * + * On success return a newly allocated copy of the channel-path description + * data associated with the given channel path. Return %NULL on error. + */ +struct channel_path_desc *ccw_device_get_chp_desc(struct ccw_device *cdev, + int chp_idx) { struct subchannel *sch; struct chp_id chpid; sch = to_subchannel(cdev->dev.parent); chp_id_init(&chpid); - chpid.id = sch->schib.pmcw.chpid[chp_no]; + chpid.id = sch->schib.pmcw.chpid[chp_idx]; return chp_get_chp_desc(chpid); } diff --git a/drivers/s390/cio/eadm_sch.c b/drivers/s390/cio/eadm_sch.c index 3a2ee4a740b4..c4f7bf3e24c2 100644 --- a/drivers/s390/cio/eadm_sch.c +++ b/drivers/s390/cio/eadm_sch.c @@ -134,7 +134,7 @@ static void eadm_subchannel_irq(struct subchannel *sch) { struct eadm_private *private = get_eadm_private(sch); struct eadm_scsw *scsw = &sch->schib.scsw.eadm; - struct irb *irb = (struct irb *)&S390_lowcore.irb; + struct irb *irb = &__get_cpu_var(cio_irb); int error = 0; EADM_LOG(6, "irq"); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 22470a3b182f..e89f38c31176 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -22,6 +22,7 @@ #include <net/iucv/af_iucv.h> #include <asm/ebcdic.h> +#include <asm/chpid.h> #include <asm/io.h> #include <asm/sysinfo.h> #include <asm/compat.h> @@ -1344,16 +1345,7 @@ static void qeth_set_multiple_write_queues(struct qeth_card *card) static void qeth_update_from_chp_desc(struct qeth_card *card) { struct ccw_device *ccwdev; - struct channelPath_dsc { - u8 flags; - u8 lsn; - u8 desc; - u8 chpid; - u8 swla; - u8 zeroes; - u8 chla; - u8 chpp; - } *chp_dsc; + struct channel_path_desc *chp_dsc; QETH_DBF_TEXT(SETUP, 2, "chp_desc"); |