diff --git a/[refs] b/[refs] index 527a68b508cd..394bc284eb95 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fbad8991ef9d41d1fad587dff23fa6deff01af83 +refs/heads/master: fa71f447065f676157ba6a2c121ba419818fc559 diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 3ff7785b3beb..124854714958 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -162,6 +162,7 @@ config IA64_GENERIC select ACPI_NUMA select SWIOTLB select PCI_MSI + select DMAR help This selects the system type of your hardware. A "generic" kernel will run on any supported IA-64 system. However, if you configure diff --git a/trunk/arch/ia64/configs/generic_defconfig b/trunk/arch/ia64/configs/generic_defconfig index 0e5cd1405e0e..1d7bca0a396d 100644 --- a/trunk/arch/ia64/configs/generic_defconfig +++ b/trunk/arch/ia64/configs/generic_defconfig @@ -234,4 +234,3 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y CONFIG_MISC_DEVICES=y -CONFIG_DMAR=y diff --git a/trunk/arch/x86/kvm/Kconfig b/trunk/arch/x86/kvm/Kconfig index ff5790d8e990..988724b236b6 100644 --- a/trunk/arch/x86/kvm/Kconfig +++ b/trunk/arch/x86/kvm/Kconfig @@ -22,8 +22,6 @@ config KVM depends on HAVE_KVM # for device assignment: depends on PCI - # for TASKSTATS/TASK_DELAY_ACCT: - depends on NET select PREEMPT_NOTIFIERS select MMU_NOTIFIER select ANON_INODES @@ -33,7 +31,6 @@ config KVM select KVM_ASYNC_PF select USER_RETURN_NOTIFIER select KVM_MMIO - select TASKSTATS select TASK_DELAY_ACCT ---help--- Support hosting fully virtualized guest machines using hardware diff --git a/trunk/drivers/base/power/domain.c b/trunk/drivers/base/power/domain.c index 1c374579407c..e18566a0fedd 100644 --- a/trunk/drivers/base/power/domain.c +++ b/trunk/drivers/base/power/domain.c @@ -460,21 +460,6 @@ static int pm_genpd_runtime_resume(struct device *dev) return 0; } -/** - * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use. - */ -void pm_genpd_poweroff_unused(void) -{ - struct generic_pm_domain *genpd; - - mutex_lock(&gpd_list_lock); - - list_for_each_entry(genpd, &gpd_list, gpd_list_node) - genpd_queue_power_off_work(genpd); - - mutex_unlock(&gpd_list_lock); -} - #else static inline void genpd_power_off_work_fn(struct work_struct *work) {} @@ -1270,3 +1255,18 @@ void pm_genpd_init(struct generic_pm_domain *genpd, list_add(&genpd->gpd_list_node, &gpd_list); mutex_unlock(&gpd_list_lock); } + +/** + * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use. + */ +void pm_genpd_poweroff_unused(void) +{ + struct generic_pm_domain *genpd; + + mutex_lock(&gpd_list_lock); + + list_for_each_entry(genpd, &gpd_list, gpd_list_node) + genpd_queue_power_off_work(genpd); + + mutex_unlock(&gpd_list_lock); +} diff --git a/trunk/drivers/edac/i7core_edac.c b/trunk/drivers/edac/i7core_edac.c index f6cf448d69b4..04f1e7ce02b1 100644 --- a/trunk/drivers/edac/i7core_edac.c +++ b/trunk/drivers/edac/i7core_edac.c @@ -1670,7 +1670,7 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, char *type, *optype, *err, *msg; unsigned long error = m->status & 0x1ff0000l; u32 optypenum = (m->status >> 4) & 0x07; - u32 core_err_cnt = (m->status >> 38) & 0x7fff; + u32 core_err_cnt = (m->status >> 38) && 0x7fff; u32 dimm = (m->misc >> 16) & 0x3; u32 channel = (m->misc >> 18) & 0x3; u32 syndrome = m->misc >> 32; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c index fe89c4660d55..43f89ba0a908 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -717,13 +717,11 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_neigh *neigh; - struct neighbour *n = NULL; + struct neighbour *n; unsigned long flags; - if (likely(skb_dst(skb))) - n = dst_get_neighbour(skb_dst(skb)); - - if (likely(n)) { + n = dst_get_neighbour(skb_dst(skb)); + if (likely(skb_dst(skb) && n)) { if (unlikely(!*to_ipoib_neigh(n))) { ipoib_path_lookup(skb, dev); return NETDEV_TX_OK; diff --git a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c index 9c61b9c2c597..8db008de5392 100644 --- a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -101,17 +101,13 @@ iscsi_iser_recv(struct iscsi_conn *conn, /* verify PDU length */ datalen = ntoh24(hdr->dlength); - if (datalen > rx_data_len || (datalen + 4) < rx_data_len) { - iser_err("wrong datalen %d (hdr), %d (IB)\n", - datalen, rx_data_len); + if (datalen != rx_data_len) { + printk(KERN_ERR "iscsi_iser: datalen %d (hdr) != %d (IB) \n", + datalen, rx_data_len); rc = ISCSI_ERR_DATALEN; goto error; } - if (datalen != rx_data_len) - iser_dbg("aligned datalen (%d) hdr, %d (IB)\n", - datalen, rx_data_len); - /* read AHS */ ahslen = hdr->hlength * 4; diff --git a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h index db6f3ce9f3bf..342cbc1bdaae 100644 --- a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -89,7 +89,7 @@ } while (0) #define SHIFT_4K 12 -#define SIZE_4K (1ULL << SHIFT_4K) +#define SIZE_4K (1UL << SHIFT_4K) #define MASK_4K (~(SIZE_4K-1)) /* support up to 512KB in one RDMA */ diff --git a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c index f299de6b419b..5745b7fe158c 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c @@ -412,7 +412,7 @@ int iser_send_control(struct iscsi_conn *conn, memcpy(iser_conn->ib_conn->login_buf, task->data, task->data_count); tx_dsg->addr = iser_conn->ib_conn->login_dma; - tx_dsg->length = task->data_count; + tx_dsg->length = data_seg_len; tx_dsg->lkey = device->mr->lkey; mdesc->num_sge = 2; } diff --git a/trunk/drivers/rtc/interface.c b/trunk/drivers/rtc/interface.c index 44e91e598f8d..3195dbd3ec34 100644 --- a/trunk/drivers/rtc/interface.c +++ b/trunk/drivers/rtc/interface.c @@ -639,7 +639,7 @@ EXPORT_SYMBOL_GPL(rtc_irq_unregister); static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled) { /* - * We always cancel the timer here first, because otherwise + * We unconditionally cancel the timer here, because otherwise * we could run into BUG_ON(timer->state != HRTIMER_STATE_CALLBACK); * when we manage to start the timer before the callback * returns HRTIMER_RESTART. @@ -708,7 +708,7 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) int err = 0; unsigned long flags; - if (freq <= 0 || freq > RTC_MAX_FREQ) + if (freq <= 0 || freq > 5000) return -EINVAL; retry: spin_lock_irqsave(&rtc->irq_task_lock, flags); diff --git a/trunk/drivers/staging/gma500/mdfld_dsi_dbi.c b/trunk/drivers/staging/gma500/mdfld_dsi_dbi.c index fd211f3467c4..02e17c9c8637 100644 --- a/trunk/drivers/staging/gma500/mdfld_dsi_dbi.c +++ b/trunk/drivers/staging/gma500/mdfld_dsi_dbi.c @@ -711,11 +711,10 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev, /* Create drm encoder object */ connector = &dsi_connector->base.base; encoder = &dbi_output->base.base; - /* Review this if we ever get MIPI-HDMI bridges or similar */ drm_encoder_init(dev, encoder, p_funcs->encoder_funcs, - DRM_MODE_ENCODER_LVDS); + DRM_MODE_ENCODER_MIPI); drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs); /* Attach to given connector */ diff --git a/trunk/drivers/staging/gma500/mdfld_dsi_dbi.h b/trunk/drivers/staging/gma500/mdfld_dsi_dbi.h index f0fa986fd934..dc6242c51d0b 100644 --- a/trunk/drivers/staging/gma500/mdfld_dsi_dbi.h +++ b/trunk/drivers/staging/gma500/mdfld_dsi_dbi.h @@ -42,6 +42,9 @@ #include "mdfld_dsi_output.h" #include "mdfld_output.h" +#define DRM_MODE_ENCODER_MIPI 5 + + /* * DBI encoder which inherits from mdfld_dsi_encoder */ diff --git a/trunk/drivers/staging/gma500/mdfld_dsi_dpi.c b/trunk/drivers/staging/gma500/mdfld_dsi_dpi.c index e685f1217baa..6e03a91e947e 100644 --- a/trunk/drivers/staging/gma500/mdfld_dsi_dpi.c +++ b/trunk/drivers/staging/gma500/mdfld_dsi_dpi.c @@ -777,15 +777,10 @@ struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, /* Create drm encoder object */ connector = &dsi_connector->base.base; encoder = &dpi_output->base.base; - /* - * On existing hardware this will be a panel of some form, - * if future devices also have HDMI bridges this will need - * revisiting - */ drm_encoder_init(dev, encoder, p_funcs->encoder_funcs, - DRM_MODE_ENCODER_LVDS); + DRM_MODE_ENCODER_MIPI); drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs); diff --git a/trunk/drivers/staging/gma500/mdfld_dsi_output.c b/trunk/drivers/staging/gma500/mdfld_dsi_output.c index 9050c0f78b15..7536095c30a0 100644 --- a/trunk/drivers/staging/gma500/mdfld_dsi_output.c +++ b/trunk/drivers/staging/gma500/mdfld_dsi_output.c @@ -955,9 +955,7 @@ void mdfld_dsi_output_init(struct drm_device *dev, psb_output->type = (pipe == 0) ? INTEL_OUTPUT_MIPI : INTEL_OUTPUT_MIPI2; connector = &psb_output->base; - /* Revisit type if MIPI/HDMI bridges ever appear on Medfield */ - drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); + drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs, DRM_MODE_CONNECTOR_MIPI); drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; diff --git a/trunk/drivers/staging/gma500/medfield.h b/trunk/drivers/staging/gma500/medfield.h index 09e9687431f1..38165e8367e5 100644 --- a/trunk/drivers/staging/gma500/medfield.h +++ b/trunk/drivers/staging/gma500/medfield.h @@ -21,6 +21,8 @@ * DEALINGS IN THE SOFTWARE. */ +#define DRM_MODE_ENCODER_MIPI 5 + /* Medfield DSI controller registers */ #define MIPIA_DEVICE_READY_REG 0xb000 diff --git a/trunk/drivers/staging/gma500/psb_drv.h b/trunk/drivers/staging/gma500/psb_drv.h index fd4732dd783a..72f487a2a1b7 100644 --- a/trunk/drivers/staging/gma500/psb_drv.h +++ b/trunk/drivers/staging/gma500/psb_drv.h @@ -35,6 +35,7 @@ /* Append new drm mode definition here, align with libdrm definition */ #define DRM_MODE_SCALE_NO_SCALE 2 +#define DRM_MODE_CONNECTOR_MIPI 15 enum { CHIP_PSB_8108 = 0, /* Poulsbo */ diff --git a/trunk/drivers/xen/xen-selfballoon.c b/trunk/drivers/xen/xen-selfballoon.c index 6ea852e25162..1b4afd81f872 100644 --- a/trunk/drivers/xen/xen-selfballoon.c +++ b/trunk/drivers/xen/xen-selfballoon.c @@ -70,7 +70,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/befs/linuxvfs.c b/trunk/fs/befs/linuxvfs.c index 720d885e8dca..54b8c28bebc8 100644 --- a/trunk/fs/befs/linuxvfs.c +++ b/trunk/fs/befs/linuxvfs.c @@ -474,22 +474,17 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd) befs_data_stream *data = &befs_ino->i_data.ds; befs_off_t len = data->size; - if (len == 0) { - befs_error(sb, "Long symlink with illegal length"); + befs_debug(sb, "Follow long symlink"); + + link = kmalloc(len, GFP_NOFS); + if (!link) { + link = ERR_PTR(-ENOMEM); + } else if (befs_read_lsymlink(sb, data, link, len) != len) { + kfree(link); + befs_error(sb, "Failed to read entire long symlink"); link = ERR_PTR(-EIO); } else { - befs_debug(sb, "Follow long symlink"); - - link = kmalloc(len, GFP_NOFS); - if (!link) { - link = ERR_PTR(-ENOMEM); - } else if (befs_read_lsymlink(sb, data, link, len) != len) { - kfree(link); - befs_error(sb, "Failed to read entire long symlink"); - link = ERR_PTR(-EIO); - } else { - link[len - 1] = '\0'; - } + link[len - 1] = '\0'; } } else { link = befs_ino->i_data.symlink; diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index ae576fbb5142..72d448bf96ce 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -105,8 +105,8 @@ build_path_from_dentry(struct dentry *direntry) } rcu_read_unlock(); if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) { - cERROR(1, "did not end path lookup where expected namelen is %d", - namelen); + cFYI(1, "did not end path lookup where expected. namelen=%d " + "dfsplen=%d", namelen, dfsplen); /* presumably this is only possible if racing with a rename of one of the parent directories (we can not lock the dentries above us to prevent this, but retrying should be harmless) */ diff --git a/trunk/fs/fat/dir.c b/trunk/fs/fat/dir.c index 5efbd5d7701a..4ad64732cbce 100644 --- a/trunk/fs/fat/dir.c +++ b/trunk/fs/fat/dir.c @@ -1231,7 +1231,7 @@ int fat_add_entries(struct inode *dir, void *slots, int nr_slots, struct super_block *sb = dir->i_sb; struct msdos_sb_info *sbi = MSDOS_SB(sb); struct buffer_head *bh, *prev, *bhs[3]; /* 32*slots (672bytes) */ - struct msdos_dir_entry *uninitialized_var(de); + struct msdos_dir_entry *de; int err, free_slots, i, nr_bhs; loff_t pos, i_pos; diff --git a/trunk/fs/fat/inode.c b/trunk/fs/fat/inode.c index 1726d7303047..5942fec22c65 100644 --- a/trunk/fs/fat/inode.c +++ b/trunk/fs/fat/inode.c @@ -1188,9 +1188,9 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, out: /* UTF-8 doesn't provide FAT semantics */ if (!strcmp(opts->iocharset, "utf8")) { - fat_msg(sb, KERN_WARNING, "utf8 is not a recommended IO charset" + fat_msg(sb, KERN_ERR, "utf8 is not a recommended IO charset" " for FAT filesystems, filesystem will be " - "case sensitive!"); + "case sensitive!\n"); } /* If user doesn't specify allow_utime, it's initialized from dmask. */ @@ -1367,7 +1367,6 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sbi->free_clusters = -1; /* Don't know yet */ sbi->free_clus_valid = 0; sbi->prev_free = FAT_START_ENT; - sb->s_maxbytes = 0xffffffff; if (!sbi->fat_length && b->fat32_length) { struct fat_boot_fsinfo *fsinfo; @@ -1378,6 +1377,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sbi->fat_length = le32_to_cpu(b->fat32_length); sbi->root_cluster = le32_to_cpu(b->root_cluster); + sb->s_maxbytes = 0xffffffff; + /* MC - if info_sector is 0, don't multiply by 0 */ sbi->fsinfo_sector = le16_to_cpu(b->info_sector); if (sbi->fsinfo_sector == 0) diff --git a/trunk/include/asm-generic/memory_model.h b/trunk/include/asm-generic/memory_model.h index aea9e45efce6..fb2d63f13f4c 100644 --- a/trunk/include/asm-generic/memory_model.h +++ b/trunk/include/asm-generic/memory_model.h @@ -39,7 +39,7 @@ }) #define __page_to_pfn(pg) \ -({ const struct page *__pg = (pg); \ +({ struct page *__pg = (pg); \ struct pglist_data *__pgdat = NODE_DATA(page_to_nid(__pg)); \ (unsigned long)(__pg - __pgdat->node_mem_map) + \ __pgdat->node_start_pfn; \ @@ -57,7 +57,7 @@ * section[i].section_mem_map == mem_map's address - start_pfn; */ #define __page_to_pfn(pg) \ -({ const struct page *__pg = (pg); \ +({ struct page *__pg = (pg); \ int __sec = page_to_section(__pg); \ (unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); \ }) diff --git a/trunk/include/linux/hash.h b/trunk/include/linux/hash.h index b80506bdd733..06d25c189cc5 100644 --- a/trunk/include/linux/hash.h +++ b/trunk/include/linux/hash.h @@ -63,7 +63,7 @@ static inline u32 hash_32(u32 val, unsigned int bits) return hash >> (32 - bits); } -static inline unsigned long hash_ptr(const void *ptr, unsigned int bits) +static inline unsigned long hash_ptr(void *ptr, unsigned int bits) { return hash_long((unsigned long)ptr, bits); } diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 59517300a315..87a06f345bd2 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -548,15 +547,7 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d) return d->msi_desc; } -int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, - struct module *owner); - -static inline int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, - int node) -{ - return __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE); -} - +int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node); void irq_free_descs(unsigned int irq, unsigned int cnt); int irq_reserve_irqs(unsigned int from, unsigned int cnt); diff --git a/trunk/include/linux/irqdesc.h b/trunk/include/linux/irqdesc.h index 150134ac709a..2d921b35212c 100644 --- a/trunk/include/linux/irqdesc.h +++ b/trunk/include/linux/irqdesc.h @@ -66,7 +66,6 @@ struct irq_desc { #ifdef CONFIG_PROC_FS struct proc_dir_entry *dir; #endif - struct module *owner; const char *name; } ____cacheline_internodealigned_in_smp; diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 7438071b44aa..fd599f4bb846 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -685,7 +685,7 @@ static inline void set_page_section(struct page *page, unsigned long section) page->flags |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT; } -static inline unsigned long page_to_section(const struct page *page) +static inline unsigned long page_to_section(struct page *page) { return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK; } @@ -720,7 +720,7 @@ static inline void set_page_links(struct page *page, enum zone_type zone, static __always_inline void *lowmem_page_address(const struct page *page) { - return __va(PFN_PHYS(page_to_pfn(page))); + return __va(PFN_PHYS(page_to_pfn((struct page *)page))); } #if defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) @@ -737,7 +737,7 @@ static __always_inline void *lowmem_page_address(const struct page *page) #endif #if defined(HASHED_PAGE_VIRTUAL) -void *page_address(const struct page *page); +void *page_address(struct page *page); void set_page_address(struct page *page, void *virtual); void page_address_init(void); #endif diff --git a/trunk/include/linux/pm_domain.h b/trunk/include/linux/pm_domain.h index f9ec1736a116..21097cb086fe 100644 --- a/trunk/include/linux/pm_domain.h +++ b/trunk/include/linux/pm_domain.h @@ -72,6 +72,8 @@ extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, extern void pm_genpd_init(struct generic_pm_domain *genpd, struct dev_power_governor *gov, bool is_off); extern int pm_genpd_poweron(struct generic_pm_domain *genpd); +extern void pm_genpd_poweroff_unused(void); +extern void genpd_queue_power_off_work(struct generic_pm_domain *genpd); #else static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) @@ -99,14 +101,8 @@ static inline int pm_genpd_poweron(struct generic_pm_domain *genpd) { return -ENOSYS; } -#endif - -#ifdef CONFIG_PM_GENERIC_DOMAINS_RUNTIME -extern void genpd_queue_power_off_work(struct generic_pm_domain *genpd); -extern void pm_genpd_poweroff_unused(void); -#else -static inline void genpd_queue_power_off_work(struct generic_pm_domain *gpd) {} static inline void pm_genpd_poweroff_unused(void) {} +static inline void genpd_queue_power_off_work(struct generic_pm_domain *gpd) {} #endif #endif /* _LINUX_PM_DOMAIN_H */ diff --git a/trunk/include/linux/rtc.h b/trunk/include/linux/rtc.h index 93f4d035076b..b27ebea25660 100644 --- a/trunk/include/linux/rtc.h +++ b/trunk/include/linux/rtc.h @@ -97,9 +97,6 @@ struct rtc_pll_info { #define RTC_AF 0x20 /* Alarm interrupt */ #define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */ - -#define RTC_MAX_FREQ 8192 - #ifdef __KERNEL__ #include diff --git a/trunk/kernel/irq/generic-chip.c b/trunk/kernel/irq/generic-chip.c index e38544dddb18..3a2cab407b93 100644 --- a/trunk/kernel/irq/generic-chip.c +++ b/trunk/kernel/irq/generic-chip.c @@ -246,7 +246,7 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask); for (i = gc->irq_base; msk; msk >>= 1, i++) { - if (!(msk & 0x01)) + if (!msk & 0x01) continue; if (flags & IRQ_GC_INIT_NESTED_LOCK) @@ -301,7 +301,7 @@ void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, raw_spin_unlock(&gc_lock); for (; msk; msk >>= 1, i++) { - if (!(msk & 0x01)) + if (!msk & 0x01) continue; /* Remove handler first. That will mask the irq line */ diff --git a/trunk/kernel/irq/irqdesc.c b/trunk/kernel/irq/irqdesc.c index 039b889ea053..4c60a50e66b2 100644 --- a/trunk/kernel/irq/irqdesc.c +++ b/trunk/kernel/irq/irqdesc.c @@ -70,8 +70,7 @@ static inline void desc_smp_init(struct irq_desc *desc, int node) { } static inline int desc_node(struct irq_desc *desc) { return 0; } #endif -static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, - struct module *owner) +static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node) { int cpu; @@ -87,7 +86,6 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, desc->irq_count = 0; desc->irqs_unhandled = 0; desc->name = NULL; - desc->owner = owner; for_each_possible_cpu(cpu) *per_cpu_ptr(desc->kstat_irqs, cpu) = 0; desc_smp_init(desc, node); @@ -130,7 +128,7 @@ static void free_masks(struct irq_desc *desc) static inline void free_masks(struct irq_desc *desc) { } #endif -static struct irq_desc *alloc_desc(int irq, int node, struct module *owner) +static struct irq_desc *alloc_desc(int irq, int node) { struct irq_desc *desc; gfp_t gfp = GFP_KERNEL; @@ -149,7 +147,7 @@ static struct irq_desc *alloc_desc(int irq, int node, struct module *owner) raw_spin_lock_init(&desc->lock); lockdep_set_class(&desc->lock, &irq_desc_lock_class); - desc_set_defaults(irq, desc, node, owner); + desc_set_defaults(irq, desc, node); return desc; @@ -175,14 +173,13 @@ static void free_desc(unsigned int irq) kfree(desc); } -static int alloc_descs(unsigned int start, unsigned int cnt, int node, - struct module *owner) +static int alloc_descs(unsigned int start, unsigned int cnt, int node) { struct irq_desc *desc; int i; for (i = 0; i < cnt; i++) { - desc = alloc_desc(start + i, node, owner); + desc = alloc_desc(start + i, node); if (!desc) goto err; mutex_lock(&sparse_irq_lock); @@ -230,7 +227,7 @@ int __init early_irq_init(void) nr_irqs = initcnt; for (i = 0; i < initcnt; i++) { - desc = alloc_desc(i, node, NULL); + desc = alloc_desc(i, node); set_bit(i, allocated_irqs); irq_insert_desc(i, desc); } @@ -264,7 +261,7 @@ int __init early_irq_init(void) alloc_masks(&desc[i], GFP_KERNEL, node); raw_spin_lock_init(&desc[i].lock); lockdep_set_class(&desc[i].lock, &irq_desc_lock_class); - desc_set_defaults(i, &desc[i], node, NULL); + desc_set_defaults(i, &desc[i], node); } return arch_early_irq_init(); } @@ -279,16 +276,8 @@ static void free_desc(unsigned int irq) dynamic_irq_cleanup(irq); } -static inline int alloc_descs(unsigned int start, unsigned int cnt, int node, - struct module *owner) +static inline int alloc_descs(unsigned int start, unsigned int cnt, int node) { - u32 i; - - for (i = 0; i < cnt; i++) { - struct irq_desc *desc = irq_to_desc(start + i); - - desc->owner = owner; - } return start; } @@ -344,13 +333,11 @@ EXPORT_SYMBOL_GPL(irq_free_descs); * @from: Start the search from this irq number * @cnt: Number of consecutive irqs to allocate. * @node: Preferred node on which the irq descriptor should be allocated - * @owner: Owning module (can be NULL) * * Returns the first irq number or error code */ int __ref -__irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, - struct module *owner) +irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node) { int start, ret; @@ -379,13 +366,13 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, bitmap_set(allocated_irqs, start, cnt); mutex_unlock(&sparse_irq_lock); - return alloc_descs(start, cnt, node, owner); + return alloc_descs(start, cnt, node); err: mutex_unlock(&sparse_irq_lock); return ret; } -EXPORT_SYMBOL_GPL(__irq_alloc_descs); +EXPORT_SYMBOL_GPL(irq_alloc_descs); /** * irq_reserve_irqs - mark irqs allocated @@ -453,7 +440,7 @@ void dynamic_irq_cleanup(unsigned int irq) unsigned long flags; raw_spin_lock_irqsave(&desc->lock, flags); - desc_set_defaults(irq, desc, desc_node(desc), NULL); + desc_set_defaults(irq, desc, desc_node(desc)); raw_spin_unlock_irqrestore(&desc->lock, flags); } diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index 2e9425889fa8..0a7840aeb0fb 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -883,8 +883,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) if (desc->irq_data.chip == &no_irq_chip) return -ENOSYS; - if (!try_module_get(desc->owner)) - return -ENODEV; /* * Some drivers like serial.c use request_irq() heavily, * so we have to be careful not to interfere with a @@ -908,10 +906,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) */ nested = irq_settings_is_nested_thread(desc); if (nested) { - if (!new->thread_fn) { - ret = -EINVAL; - goto out_mput; - } + if (!new->thread_fn) + return -EINVAL; /* * Replace the primary handler which was provided from * the driver for non nested interrupt handling by the @@ -933,10 +929,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) t = kthread_create(irq_thread, new, "irq/%d-%s", irq, new->name); - if (IS_ERR(t)) { - ret = PTR_ERR(t); - goto out_mput; - } + if (IS_ERR(t)) + return PTR_ERR(t); /* * We keep the reference to the task struct even if * the thread dies to avoid that the interrupt code @@ -1101,8 +1095,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) kthread_stop(t); put_task_struct(t); } -out_mput: - module_put(desc->owner); return ret; } @@ -1211,7 +1203,6 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) put_task_struct(action->thread); } - module_put(desc->owner); return action; } @@ -1331,7 +1322,6 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler, if (!thread_fn) return -EINVAL; handler = irq_default_primary_handler; - irqflags |= IRQF_ONESHOT; } action = kzalloc(sizeof(struct irqaction), GFP_KERNEL); diff --git a/trunk/kernel/lockdep.c b/trunk/kernel/lockdep.c index 91d67ce3a8d5..8c24294e477f 100644 --- a/trunk/kernel/lockdep.c +++ b/trunk/kernel/lockdep.c @@ -3111,13 +3111,7 @@ static int match_held_lock(struct held_lock *hlock, struct lockdep_map *lock) if (!class) class = look_up_lock_class(lock, 0); - /* - * If look_up_lock_class() failed to find a class, we're trying - * to test if we hold a lock that has never yet been acquired. - * Clearly if the lock hasn't been acquired _ever_, we're not - * holding it either, so report failure. - */ - if (!class) + if (DEBUG_LOCKS_WARN_ON(!class)) return 0; if (DEBUG_LOCKS_WARN_ON(!hlock->nest_lock)) diff --git a/trunk/kernel/power/Kconfig b/trunk/kernel/power/Kconfig index 3744c594b19b..b1914cb9095c 100644 --- a/trunk/kernel/power/Kconfig +++ b/trunk/kernel/power/Kconfig @@ -231,7 +231,3 @@ config PM_CLK config PM_GENERIC_DOMAINS bool depends on PM - -config PM_GENERIC_DOMAINS_RUNTIME - def_bool y - depends on PM_RUNTIME && PM_GENERIC_DOMAINS diff --git a/trunk/mm/highmem.c b/trunk/mm/highmem.c index 5ef672c07f75..693394daa2ed 100644 --- a/trunk/mm/highmem.c +++ b/trunk/mm/highmem.c @@ -326,7 +326,7 @@ static struct page_address_slot { spinlock_t lock; /* Protect this bucket's list */ } ____cacheline_aligned_in_smp page_address_htable[1<addr != iwp->addr) - return DIE_FIND_CB_CONTINUE; - - /* Ignore redundant instances */ - if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) { - dwarf_decl_line(origin, &tmp); - if (die_get_call_lineno(inst) == tmp) { - tmp = die_get_decl_fileno(origin); - if (die_get_call_fileno(inst) == tmp) - return DIE_FIND_CB_CONTINUE; - } - } - - iwp->retval = iwp->callback(inst, iwp->data); - - return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE; -} - -/** - * die_walk_instances - Walk on instances of given DIE - * @or_die: an abstract original DIE - * @callback: a callback function which is called with instance DIE - * @data: user data - * - * Walk on the instances of give @in_die. @in_die must be an inlined function - * declartion. This returns the return value of @callback if it returns - * non-zero value, or -ENOENT if there is no instance. - */ -int die_walk_instances(Dwarf_Die *or_die, int (*callback)(Dwarf_Die *, void *), - void *data) -{ - Dwarf_Die cu_die; - Dwarf_Die die_mem; - struct __instance_walk_param iwp = { - .addr = or_die->addr, - .callback = callback, - .data = data, - .retval = -ENOENT, - }; - - if (dwarf_diecu(or_die, &cu_die, NULL, NULL) == NULL) - return -ENOENT; - - die_find_child(&cu_die, __die_walk_instances_cb, &iwp, &die_mem); - - return iwp.retval; -} - /* Line walker internal parameters */ struct __line_walk_param { - bool recursive; + const char *fname; line_walk_callback_t callback; void *data; int retval; @@ -544,56 +385,39 @@ struct __line_walk_param { static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data) { struct __line_walk_param *lw = data; - Dwarf_Addr addr = 0; - const char *fname; + Dwarf_Addr addr; int lineno; if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) { - fname = die_get_call_file(in_die); lineno = die_get_call_lineno(in_die); - if (fname && lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) { - lw->retval = lw->callback(fname, lineno, addr, lw->data); + if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) { + lw->retval = lw->callback(lw->fname, lineno, addr, + lw->data); if (lw->retval != 0) return DIE_FIND_CB_END; } } - if (!lw->recursive) - /* Don't need to search recursively */ - return DIE_FIND_CB_SIBLING; - - if (addr) { - fname = dwarf_decl_file(in_die); - if (fname && dwarf_decl_line(in_die, &lineno) == 0) { - lw->retval = lw->callback(fname, lineno, addr, lw->data); - if (lw->retval != 0) - return DIE_FIND_CB_END; - } - } - - /* Continue to search nested inlined function call-sites */ - return DIE_FIND_CB_CONTINUE; + return DIE_FIND_CB_SIBLING; } /* Walk on lines of blocks included in given DIE */ -static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive, +static int __die_walk_funclines(Dwarf_Die *sp_die, line_walk_callback_t callback, void *data) { struct __line_walk_param lw = { - .recursive = recursive, .callback = callback, .data = data, .retval = 0, }; Dwarf_Die die_mem; Dwarf_Addr addr; - const char *fname; int lineno; /* Handle function declaration line */ - fname = dwarf_decl_file(sp_die); - if (fname && dwarf_decl_line(sp_die, &lineno) == 0 && + lw.fname = dwarf_decl_file(sp_die); + if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 && dwarf_entrypc(sp_die, &addr) == 0) { - lw.retval = callback(fname, lineno, addr, data); + lw.retval = callback(lw.fname, lineno, addr, data); if (lw.retval != 0) goto done; } @@ -606,7 +430,7 @@ static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data) { struct __line_walk_param *lw = data; - lw->retval = __die_walk_funclines(sp_die, true, lw->callback, lw->data); + lw->retval = __die_walk_funclines(sp_die, lw->callback, lw->data); if (lw->retval != 0) return DWARF_CB_ABORT; @@ -615,7 +439,7 @@ static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data) /** * die_walk_lines - Walk on lines inside given DIE - * @rt_die: a root DIE (CU, subprogram or inlined_subroutine) + * @rt_die: a root DIE (CU or subprogram) * @callback: callback routine * @data: user data * @@ -636,12 +460,12 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data) size_t nlines, i; /* Get the CU die */ - if (dwarf_tag(rt_die) != DW_TAG_compile_unit) + if (dwarf_tag(rt_die) == DW_TAG_subprogram) cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL); else cu_die = rt_die; if (!cu_die) { - pr_debug2("Failed to get CU from given DIE.\n"); + pr_debug2("Failed to get CU from subprogram\n"); return -EINVAL; } @@ -685,11 +509,7 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data) * subroutines. We have to check functions list or given function. */ if (rt_die != cu_die) - /* - * Don't need walk functions recursively, because nested - * inlined functions don't have lines of the specified DIE. - */ - ret = __die_walk_funclines(rt_die, false, callback, data); + ret = __die_walk_funclines(rt_die, callback, data); else { struct __line_walk_param param = { .callback = callback, diff --git a/trunk/tools/perf/util/dwarf-aux.h b/trunk/tools/perf/util/dwarf-aux.h index 6ce1717784b7..bc3b21167e70 100644 --- a/trunk/tools/perf/util/dwarf-aux.h +++ b/trunk/tools/perf/util/dwarf-aux.h @@ -34,19 +34,12 @@ extern const char *cu_get_comp_dir(Dwarf_Die *cu_die); extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, const char **fname, int *lineno); -/* Walk on funcitons at given address */ -extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, - int (*callback)(Dwarf_Die *, void *), void *data); - /* Compare diename and tname */ extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); /* Get callsite line number of inline-function instance */ extern int die_get_call_lineno(Dwarf_Die *in_die); -/* Get callsite file name of inlined function instance */ -extern const char *die_get_call_file(Dwarf_Die *in_die); - /* Get type die */ extern Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); @@ -80,10 +73,6 @@ extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, Dwarf_Die *die_mem); -/* Walk on the instances of given DIE */ -extern int die_walk_instances(Dwarf_Die *in_die, - int (*callback)(Dwarf_Die *, void *), void *data); - /* Walker on lines (Note: line number will not be sorted) */ typedef int (* line_walk_callback_t) (const char *fname, int lineno, Dwarf_Addr addr, void *data); diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index b6c1ad123ca9..d4f3101773db 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -726,16 +726,7 @@ static int perf_header__read_build_ids_abi_quirk(struct perf_header *header, return -1; bev.header = old_bev.header; - - /* - * As the pid is the missing value, we need to fill - * it properly. The header.misc value give us nice hint. - */ - bev.pid = HOST_KERNEL_ID; - if (bev.header.misc == PERF_RECORD_MISC_GUEST_USER || - bev.header.misc == PERF_RECORD_MISC_GUEST_KERNEL) - bev.pid = DEFAULT_GUEST_KERNEL_ID; - + bev.pid = 0; memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id)); __event_process_build_id(&bev, filename, session); diff --git a/trunk/tools/perf/util/probe-finder.c b/trunk/tools/perf/util/probe-finder.c index 555fc3864b90..3e44a3e36519 100644 --- a/trunk/tools/perf/util/probe-finder.c +++ b/trunk/tools/perf/util/probe-finder.c @@ -612,12 +612,12 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) return ret; } -/* Find a variable in a scope DIE */ -static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) +/* Find a variable in a subprogram die */ +static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) { - Dwarf_Die vr_die; + Dwarf_Die vr_die, *scopes; char buf[32], *ptr; - int ret = 0; + int ret, nscopes; if (!is_c_varname(pf->pvar->var)) { /* Copy raw parameters */ @@ -652,16 +652,30 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) if (pf->tvar->name == NULL) return -ENOMEM; - pr_debug("Searching '%s' variable in context.\n", pf->pvar->var); + pr_debug("Searching '%s' variable in context.\n", + pf->pvar->var); /* Search child die for local variables and parameters. */ - if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) { - /* Search again in global variables */ - if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die)) - ret = -ENOENT; - } - if (ret == 0) + if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die)) ret = convert_variable(&vr_die, pf); - + else { + /* Search upper class */ + nscopes = dwarf_getscopes_die(sp_die, &scopes); + while (nscopes-- > 1) { + pr_debug("Searching variables in %s\n", + dwarf_diename(&scopes[nscopes])); + /* We should check this scope, so give dummy address */ + if (die_find_variable_at(&scopes[nscopes], + pf->pvar->var, 0, + &vr_die)) { + ret = convert_variable(&vr_die, pf); + goto found; + } + } + if (scopes) + free(scopes); + ret = -ENOENT; + } +found: if (ret < 0) pr_warning("Failed to find '%s' in this function.\n", pf->pvar->var); @@ -704,30 +718,26 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr, return 0; } -/* Call probe_finder callback with scope DIE */ -static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf) +/* Call probe_finder callback with real subprogram DIE */ +static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf) { + Dwarf_Die die_mem; Dwarf_Attribute fb_attr; size_t nops; int ret; - if (!sc_die) { - pr_err("Caller must pass a scope DIE. Program error.\n"); - return -EINVAL; - } - - /* If not a real subprogram, find a real one */ - if (dwarf_tag(sc_die) != DW_TAG_subprogram) { - if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { + /* If no real subprogram, find a real one */ + if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) { + sp_die = die_find_realfunc(&pf->cu_die, pf->addr, &die_mem); + if (!sp_die) { pr_warning("Failed to find probe point in any " "functions.\n"); return -ENOENT; } - } else - memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die)); + } - /* Get the frame base attribute/ops from subprogram */ - dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr); + /* Get the frame base attribute/ops */ + dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); if (ret <= 0 || nops == 0) { pf->fb_ops = NULL; @@ -745,7 +755,7 @@ static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf) } /* Call finder's callback handler */ - ret = pf->callback(sc_die, pf); + ret = pf->callback(sp_die, pf); /* *pf->fb_ops will be cached in libdw. Don't free it. */ pf->fb_ops = NULL; @@ -753,82 +763,17 @@ static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf) return ret; } -struct find_scope_param { - const char *function; - const char *file; - int line; - int diff; - Dwarf_Die *die_mem; - bool found; -}; - -static int find_best_scope_cb(Dwarf_Die *fn_die, void *data) -{ - struct find_scope_param *fsp = data; - const char *file; - int lno; - - /* Skip if declared file name does not match */ - if (fsp->file) { - file = dwarf_decl_file(fn_die); - if (!file || strcmp(fsp->file, file) != 0) - return 0; - } - /* If the function name is given, that's what user expects */ - if (fsp->function) { - if (die_compare_name(fn_die, fsp->function)) { - memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); - fsp->found = true; - return 1; - } - } else { - /* With the line number, find the nearest declared DIE */ - dwarf_decl_line(fn_die, &lno); - if (lno < fsp->line && fsp->diff > fsp->line - lno) { - /* Keep a candidate and continue */ - fsp->diff = fsp->line - lno; - memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); - fsp->found = true; - } - } - return 0; -} - -/* Find an appropriate scope fits to given conditions */ -static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem) -{ - struct find_scope_param fsp = { - .function = pf->pev->point.function, - .file = pf->fname, - .line = pf->lno, - .diff = INT_MAX, - .die_mem = die_mem, - .found = false, - }; - - cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb, &fsp); - - return fsp.found ? die_mem : NULL; -} - static int probe_point_line_walker(const char *fname, int lineno, Dwarf_Addr addr, void *data) { struct probe_finder *pf = data; - Dwarf_Die *sc_die, die_mem; int ret; if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0) return 0; pf->addr = addr; - sc_die = find_best_scope(pf, &die_mem); - if (!sc_die) { - pr_warning("Failed to find scope of probe point.\n"); - return -ENOENT; - } - - ret = call_probe_finder(sc_die, pf); + ret = call_probe_finder(NULL, pf); /* Continue if no error, because the line will be in inline function */ return ret < 0 ? ret : 0; @@ -882,7 +827,6 @@ static int probe_point_lazy_walker(const char *fname, int lineno, Dwarf_Addr addr, void *data) { struct probe_finder *pf = data; - Dwarf_Die *sc_die, die_mem; int ret; if (!line_list__has_line(&pf->lcache, lineno) || @@ -892,14 +836,7 @@ static int probe_point_lazy_walker(const char *fname, int lineno, pr_debug("Probe line found: line:%d addr:0x%llx\n", lineno, (unsigned long long)addr); pf->addr = addr; - pf->lno = lineno; - sc_die = find_best_scope(pf, &die_mem); - if (!sc_die) { - pr_warning("Failed to find scope of probe point.\n"); - return -ENOENT; - } - - ret = call_probe_finder(sc_die, pf); + ret = call_probe_finder(NULL, pf); /* * Continue if no error, because the lazy pattern will match @@ -924,39 +861,42 @@ static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf) return die_walk_lines(sp_die, probe_point_lazy_walker, pf); } +/* Callback parameter with return value */ +struct dwarf_callback_param { + void *data; + int retval; +}; + static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) { - struct probe_finder *pf = data; + struct dwarf_callback_param *param = data; + struct probe_finder *pf = param->data; struct perf_probe_point *pp = &pf->pev->point; Dwarf_Addr addr; - int ret; if (pp->lazy_line) - ret = find_probe_point_lazy(in_die, pf); + param->retval = find_probe_point_lazy(in_die, pf); else { /* Get probe address */ if (dwarf_entrypc(in_die, &addr) != 0) { pr_warning("Failed to get entry address of %s.\n", dwarf_diename(in_die)); - return -ENOENT; + param->retval = -ENOENT; + return DWARF_CB_ABORT; } pf->addr = addr; pf->addr += pp->offset; pr_debug("found inline addr: 0x%jx\n", (uintmax_t)pf->addr); - ret = call_probe_finder(in_die, pf); + param->retval = call_probe_finder(in_die, pf); + if (param->retval < 0) + return DWARF_CB_ABORT; } - return ret; + return DWARF_CB_OK; } -/* Callback parameter with return value for libdw */ -struct dwarf_callback_param { - void *data; - int retval; -}; - /* Search function from function name */ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) { @@ -993,10 +933,14 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) /* TODO: Check the address in this function */ param->retval = call_probe_finder(sp_die, pf); } - } else + } else { + struct dwarf_callback_param _param = {.data = (void *)pf, + .retval = 0}; /* Inlined function: search instances */ - param->retval = die_walk_instances(sp_die, - probe_point_inline_cb, (void *)pf); + dwarf_func_inline_instances(sp_die, probe_point_inline_cb, + &_param); + param->retval = _param.retval; + } return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */ } @@ -1116,7 +1060,7 @@ static int debuginfo__find_probes(struct debuginfo *self, } /* Add a found probe point into trace event list */ -static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) +static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf) { struct trace_event_finder *tf = container_of(pf, struct trace_event_finder, pf); @@ -1131,9 +1075,8 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) } tev = &tf->tevs[tf->ntevs++]; - /* Trace point should be converted from subprogram DIE */ - ret = convert_to_trace_point(&pf->sp_die, pf->addr, - pf->pev->point.retprobe, &tev->point); + ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, + &tev->point); if (ret < 0) return ret; @@ -1148,8 +1091,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) for (i = 0; i < pf->pev->nargs; i++) { pf->pvar = &pf->pev->args[i]; pf->tvar = &tev->args[i]; - /* Variable should be found from scope DIE */ - ret = find_variable(sc_die, pf); + ret = find_variable(sp_die, pf); if (ret != 0) return ret; } @@ -1217,13 +1159,13 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data) } /* Add a found vars into available variables list */ -static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf) +static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf) { struct available_var_finder *af = container_of(pf, struct available_var_finder, pf); struct variable_list *vl; - Dwarf_Die die_mem; - int ret; + Dwarf_Die die_mem, *scopes = NULL; + int ret, nscopes; /* Check number of tevs */ if (af->nvls == af->max_vls) { @@ -1232,9 +1174,8 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf) } vl = &af->vls[af->nvls++]; - /* Trace point should be converted from subprogram DIE */ - ret = convert_to_trace_point(&pf->sp_die, pf->addr, - pf->pev->point.retprobe, &vl->point); + ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, + &vl->point); if (ret < 0) return ret; @@ -1246,14 +1187,19 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf) if (vl->vars == NULL) return -ENOMEM; af->child = true; - die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem); + die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem); /* Find external variables */ if (!af->externs) goto out; /* Don't need to search child DIE for externs. */ af->child = false; - die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem); + nscopes = dwarf_getscopes_die(sp_die, &scopes); + while (nscopes-- > 1) + die_find_child(&scopes[nscopes], collect_variables_cb, + (void *)af, &die_mem); + if (scopes) + free(scopes); out: if (strlist__empty(vl->vars)) { @@ -1445,14 +1391,10 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) static int line_range_inline_cb(Dwarf_Die *in_die, void *data) { - find_line_range_by_line(in_die, data); + struct dwarf_callback_param *param = data; - /* - * We have to check all instances of inlined function, because - * some execution paths can be optimized out depends on the - * function argument of instances - */ - return 0; + param->retval = find_line_range_by_line(in_die, param->data); + return DWARF_CB_ABORT; /* No need to find other instances */ } /* Search function from function name */ @@ -1480,10 +1422,15 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data) pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); lr->start = lf->lno_s; lr->end = lf->lno_e; - if (dwarf_func_inline(sp_die)) - param->retval = die_walk_instances(sp_die, - line_range_inline_cb, lf); - else + if (dwarf_func_inline(sp_die)) { + struct dwarf_callback_param _param; + _param.data = (void *)lf; + _param.retval = 0; + dwarf_func_inline_instances(sp_die, + line_range_inline_cb, + &_param); + param->retval = _param.retval; + } else param->retval = find_line_range_by_line(sp_die, lf); return DWARF_CB_ABORT; } diff --git a/trunk/tools/perf/util/probe-finder.h b/trunk/tools/perf/util/probe-finder.h index 1132c8f0ce89..c478b42a2473 100644 --- a/trunk/tools/perf/util/probe-finder.h +++ b/trunk/tools/perf/util/probe-finder.h @@ -57,7 +57,7 @@ struct probe_finder { struct perf_probe_event *pev; /* Target probe event */ /* Callback when a probe point is found */ - int (*callback)(Dwarf_Die *sc_die, struct probe_finder *pf); + int (*callback)(Dwarf_Die *sp_die, struct probe_finder *pf); /* For function searching */ int lno; /* Line number */ diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index 469c0264ed29..a8b53714542a 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -1506,7 +1506,7 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) if (strncmp(dso->name, "/tmp/perf-", 10) == 0) { struct stat st; - if (lstat(dso->name, &st) < 0) + if (stat(dso->name, &st) < 0) return -1; if (st.st_uid && (st.st_uid != geteuid())) { @@ -2181,22 +2181,27 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *machines, return ret; } -static struct dso* -dso__kernel_findnew(struct machine *machine, const char *name, - const char *short_name, int dso_type) +struct dso *dso__new_kernel(const char *name) { - /* - * The kernel dso could be created by build_id processing. - */ - struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); + struct dso *dso = dso__new(name ?: "[kernel.kallsyms]"); - /* - * We need to run this in all cases, since during the build_id - * processing we had no idea this was the kernel dso. - */ if (dso != NULL) { - dso__set_short_name(dso, short_name); - dso->kernel = dso_type; + dso__set_short_name(dso, "[kernel]"); + dso->kernel = DSO_TYPE_KERNEL; + } + + return dso; +} + +static struct dso *dso__new_guest_kernel(struct machine *machine, + const char *name) +{ + char bf[PATH_MAX]; + struct dso *dso = dso__new(name ?: machine__mmap_name(machine, bf, + sizeof(bf))); + if (dso != NULL) { + dso__set_short_name(dso, "[guest.kernel]"); + dso->kernel = DSO_TYPE_GUEST_KERNEL; } return dso; @@ -2214,36 +2219,24 @@ void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine) dso->has_build_id = true; } -static struct dso *machine__get_kernel(struct machine *machine) +static struct dso *machine__create_kernel(struct machine *machine) { const char *vmlinux_name = NULL; struct dso *kernel; if (machine__is_host(machine)) { vmlinux_name = symbol_conf.vmlinux_name; - if (!vmlinux_name) - vmlinux_name = "[kernel.kallsyms]"; - - kernel = dso__kernel_findnew(machine, vmlinux_name, - "[kernel]", - DSO_TYPE_KERNEL); + kernel = dso__new_kernel(vmlinux_name); } else { - char bf[PATH_MAX]; - if (machine__is_default_guest(machine)) vmlinux_name = symbol_conf.default_guest_vmlinux_name; - if (!vmlinux_name) - vmlinux_name = machine__mmap_name(machine, bf, - sizeof(bf)); - - kernel = dso__kernel_findnew(machine, vmlinux_name, - "[guest.kernel]", - DSO_TYPE_GUEST_KERNEL); + kernel = dso__new_guest_kernel(machine, vmlinux_name); } - if (kernel != NULL && (!kernel->has_build_id)) + if (kernel != NULL) { dso__read_running_kernel_build_id(kernel, machine); - + dsos__add(&machine->kernel_dsos, kernel); + } return kernel; } @@ -2347,7 +2340,7 @@ void machine__destroy_kernel_maps(struct machine *machine) int machine__create_kernel_maps(struct machine *machine) { - struct dso *kernel = machine__get_kernel(machine); + struct dso *kernel = machine__create_kernel(machine); if (kernel == NULL || __machine__create_kernel_maps(machine, kernel) < 0) diff --git a/trunk/tools/perf/util/symbol.h b/trunk/tools/perf/util/symbol.h index 4f377d92e75a..325ee36a9d29 100644 --- a/trunk/tools/perf/util/symbol.h +++ b/trunk/tools/perf/util/symbol.h @@ -155,6 +155,7 @@ struct dso { }; struct dso *dso__new(const char *name); +struct dso *dso__new_kernel(const char *name); void dso__delete(struct dso *dso); int dso__name_len(const struct dso *dso); diff --git a/trunk/tools/perf/util/ui/browsers/top.c b/trunk/tools/perf/util/ui/browsers/top.c index 88403cf8396a..5a06538532af 100644 --- a/trunk/tools/perf/util/ui/browsers/top.c +++ b/trunk/tools/perf/util/ui/browsers/top.c @@ -208,5 +208,6 @@ int perf_top__tui_browser(struct perf_top *top) }, }; + ui_helpline__push("Press <- or ESC to exit"); return perf_top_browser__run(&browser); }