Re: [RFC 19/19] s390/facilities: enable AP facilities needed by guest

2017-12-04 Thread Harald Freudenberger
On 12/02/2017 02:30 AM, Tony Krowiak wrote:
> On 11/03/2017 04:47 AM, Christian Borntraeger wrote:
>>
>> On 11/02/2017 07:49 PM, Tony Krowiak wrote:
>>> On 11/02/2017 11:53 AM, Christian Borntraeger wrote:
 On 11/02/2017 04:36 PM, Tony Krowiak wrote:
> On 11/02/2017 08:08 AM, Christian Borntraeger wrote:
>> On 10/16/2017 11:25 AM, Martin Schwidefsky wrote:
>>> On Fri, 13 Oct 2017 13:39:04 -0400
>>> Tony Krowiak  wrote:
>>>
 Sets up the following facilities bits to enable the specified AP
 facilities for the guest VM:
   * STFLE.12: Enables the AP Query Configuration Information
   facility. The AP bus running in the guest uses
   the information returned from this instruction
   to configure AP adapters and domains for the
   guest machine.
   * STFLE.15: Indicates the AP facilities test is available.
   The AP bus running in the guest uses the
   information.

 Signed-off-by: Tony Krowiak 
 ---
    arch/s390/tools/gen_facilities.c |    2 ++
    1 files changed, 2 insertions(+), 0 deletions(-)

 diff --git a/arch/s390/tools/gen_facilities.c 
 b/arch/s390/tools/gen_facilities.c
 index 70dd8f1..eeaa7db 100644
 --- a/arch/s390/tools/gen_facilities.c
 +++ b/arch/s390/tools/gen_facilities.c
 @@ -74,8 +74,10 @@ struct facility_def {
    8,  /* enhanced-DAT 1 */
    9,  /* sense-running-status */
    10, /* conditional sske */
 +    12, /* AP query configuration */
    13, /* ipte-range */
    14, /* nonquiescing key-setting */
 +    15, /* AP special-command facility */
    73, /* transactional execution */
    75, /* access-exception-fetch/store indication */
    76, /* msa extension 3 */
>>> With this all KVM guests will always have the AP instructions 
>>> available, no?
>>> In principles I like this approach, but it differs from the way z/VM 
>>> does things,
>>> there the guest will get an exception if it tries to execute an AP 
>>> instruction
>>> if there are no AP devices assigned to the guest. I wonder if there is 
>>> a reason
>>> why z/VM does it the way it does.
>> A good question. For LPAR it seems that you have AP instructions even if 
>> you have
>> no crypto cards.
>>
> I don't believe these facilities control whether or not AP instructions 
> will be available
>
> to the guest.
 This is actually handled by your patch2 enabling the ECA bit.
 I think we must decide if we want to be able to disable these instructions
 via the cpu model. If yes we must then couple the facilities with the 
 enablement.
>>> The ECA.28 bit controls whether instructions are intercepted or interpreted 
>>> - i.e., handled via hardware
>>> virtualization. If set, as is done in patch2, then instructions will be 
>>> interpreted. I don't see how
>>> that affects enabling or disabling AP instructions, unless we don't set 
>>> ECA.28, intercept every instruction
>>> and program check. Am I missing something here?
>> If we do not set ECA.28 these instructions intercept and we (the hypervisor) 
>> can then
>> decide what to do. For example we can give an PIC01 operation exception 
>> (illegal
>> instruction) - thats what we do today.
>>
>> Now: if we want to be able to migrate a guest from a new kernel back to an 
>> old kernel,
>> there must be a way to disable the new behaviour so that the user can 
>> configure a guest
>> that does NOT have these 3 instructions. That means, I want to bind the ap 
>> instruction
>> to a cpu model feature, so that we only enable ECA.28 and the facility bits, 
>> if the
>> feature is enabled in the CPU model. Otherwise we have no control on what 
>> happens
>> when the guest issues these instructions.
>>
>> Imagine what happens if we not do this and you migrate from an identical hw 
>> with an
>> identical libvirt/qemu but from a new kernel to an old kernel:
>>
>> The guest boots starts up on the new kernel
>> guest kernel: drivers/s390/crypto/ap_bus.c  ap_module_init -> 
>> ap_instructions_available
>> checks if the instructions work. They do and now the guest driver assumes 
>> that all
>> instructions will continue to work.
>>
>> Now the guest is migrated back to an old kernel
>> sooner or later the ap_scan_bus kthread will run to scan the bus (or some 
>> crypto operation
>> is started) and the instruction will be rejected with a PIC01. kernel oops.
> There are several scenarios that have to be accounted for, such as:
> * Migrating from a linux host where both the KVM/kernel and QEMU support AP 
> matrix
>   devices to a 

[f2fs-dev] [PATCH] f2fs: release reserved blocks for quota

2017-12-04 Thread LiFan

Quota has been modified during inc_valid_block_count(), but not in
truncate process. This patch adds it.

Signed-off-by: Fan li 
---
 fs/f2fs/f2fs.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 82f1dc3..71fbba96 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1619,7 +1619,9 @@ static inline void dec_valid_block_count(struct 
f2fs_sb_info *sbi,
sbi->current_reserved_blocks = min(sbi->reserved_blocks,
sbi->current_reserved_blocks + count);
spin_unlock(&sbi->stat_lock);
+
f2fs_i_blocks_write(inode, count, false, true);
+   dquot_release_reservation_block(inode, count);
 }
 
 static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
-- 
2.7.4




[PATCH] SCSI: run queue if SCSI device queue isn't ready and queue is idle

2017-12-04 Thread Ming Lei
Before commit 0df21c86bdbf ("scsi: implement .get_budget and .put_budget
for blk-mq"), we run queue after 3ms if queue is idle and SCSI device
queue isn't ready, which is done in handling BLK_STS_RESOURCE. After
commit 0df21c86bdbf is introduced, queue won't be run any more under
this situation.

IO hang is observed when timeout happened, and this patch fixes the IO
hang issue by running queue after delay in scsi_dev_queue_ready, just like
non-mq. This issue can be triggered by the following script[1].

There is another issue which can be covered by running idle queue:
when .get_budget() is called on request coming from hctx->dispatch_list,
if one request just completes during .get_budget(), we can't depend on
SCSI's restart to make progress any more. This patch fixes the race too.

With this patch, we basically recover to previous behaviour(before commit
0df21c86bdbf) of handling idle queue when running out of resource.

[1] script for test/verify SCSI timeout
rmmod scsi_debug
modprobe scsi_debug max_queue=1

DEVICE=`ls -d 
/sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*/block/* | head -1 | 
xargs basename`
DISK_DIR=`ls -d /sys/block/$DEVICE/device/scsi_disk/*`

echo "using scsi device $DEVICE"
echo "-1" >/sys/bus/pseudo/drivers/scsi_debug/every_nth
echo "temporary write through" >$DISK_DIR/cache_type
echo "128" >/sys/bus/pseudo/drivers/scsi_debug/opts
echo none > /sys/block/$DEVICE/queue/scheduler
dd if=/dev/$DEVICE of=/dev/null bs=1M iflag=direct count=1 &
sleep 5
echo "0" >/sys/bus/pseudo/drivers/scsi_debug/opts
wait
echo "SUCCESS"

Fixes: 0df21c86bdbf ("scsi: implement .get_budget and .put_budget for blk-mq")
Signed-off-by: Ming Lei 
---
 drivers/scsi/scsi_lib.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index db9556662e27..1816dd8259b3 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1967,6 +1967,8 @@ static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx)
 out_put_device:
put_device(&sdev->sdev_gendev);
 out:
+   if (atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev))
+   blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY);
return false;
 }
 
-- 
2.9.5



Re: [PATCH 4.14 00/95] 4.14.4-stable review

2017-12-04 Thread Greg Kroah-Hartman
On Tue, Dec 05, 2017 at 12:31:40PM +0530, Naresh Kamboju wrote:
> On 4 December 2017 at 21:29, Greg Kroah-Hartman
>  wrote:
> > This is the start of the stable review cycle for the 4.14.4 release.
> > There are 95 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> >
> > Responses should be made by Wed Dec  6 16:00:27 UTC 2017.
> > Anything received after that time might be too late.
> >
> > The whole patch series can be found in one patch at:
> > kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.4-rc1.gz
> > or in the git tree and branch at:
> >   git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> > linux-4.14.y
> > and the diffstat can be found below.
> >
> > thanks,
> >
> > greg k-h
> >
> 
> Results from Linaro’s test farm.
> No regressions on arm64, arm and x86_64.

Thanks for testing all 3 of these releases and letting me know.

greg k-h


Re: Writing "+pids" to cgroup.subtree_control flie yields EINVAL

2017-12-04 Thread Michael Kerrisk (man-pages)
[dropping Lennart into CC]

Hello Tejun,

On 12/04/2017 10:47 PM, Tejun Heo wrote:
> Hello, Michael.
> 
> On Mon, Dec 04, 2017 at 10:35:13PM +0100, Michael Kerrisk (man-pages) wrote:
>> I was trying to do some simple testing ot the CPU controller
>> that is merged into 4.15, and ran immediately into some confusion.
>> In the root cgroup on a freshly booted 4.150-rc1, I try the following:
>>
>> # pwd
>> /sys/fs/cgroup/unified
>> # echo '+cpu' > cgroup.subtree_control 
>> sh: echo: write error: Invalid argument
>>
>> What am I missing> I presume I'm missing something obvious, although
>> nothing jumped out at me as I read the cgroups-v2.txt file.
> 
> Checking whether I messed up something really basic... hmmm doesn't
> seem that way.  What do /sys/fs/cgroup/unified/cgroup.controllers and
> /proc/cgroups say?

Oh -- they're all sensible:

In the root cgroup:

# cat cgroup.controllers 
cpu io memory pids

$ cat /proc/cgroups 
#subsys_namehierarchy   num_cgroups enabled
cpuset  0   142 1
cpu 0   142 1
cpuacct 0   142 1
blkio   0   142 1
memory  0   142 1
devices 0   142 1
freezer 0   142 1
net_cls 0   142 1
perf_event  0   142 1
net_prio0   142 1
hugetlb 0   142 1
pids0   142 1

But, I through some trial and error and printk() I worked out

a) If I first move all tasks to the root cgroup, then I can
write '+cpu' to the cgroup.subtree_control file in the root
cgroup.

b) The reason for my initial problems was this test in
the kernel in cpu_cgroup_can_attach():

#ifdef CONFIG_RT_GROUP_SCHED
if (!sched_rt_can_attach(css_tg(css), task))
return -EINVAL;
#else
/* We don't support RT-tasks being in separate groups */
if (task->sched_class != &fair_sched_class)
return -EINVAL;
#endif

I don't have CONFIG_RT_GROUP_SCHED, and the second 'if' was yielding
false because of some SCHED_RR processes that are in some of the nonroot
cgroups created by systemd, namely:

# ps ax -L -o 'pid tid cls rtprio comm'|grep RR
  685   723  RR 99 rtkit-daemon
  972   979  RR  5 alsa-sink-ALC26
  972   982  RR  5 alsa-source-ALC
 1594  1597  RR  5 alsa-sink-ALC26
 1594  1600  RR  5 alsa-source-ALC

So, one solution is to move those processes to the root cgroup,
and then it's possible to write '+pids' to cgroup.subtree_control.

Is enabling CONFIG_RT_GROUP_SCHED also a solution? (I have
not had a chance to test that yet.)

Anyway, it seems like this should be documented somewhere in the
kernel Documentation files, since it may be that others will run
into this as well. I'm not quite sure what should be added to the
documentation. Do you have some idea?

Thanks,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/


Re: [PATCH v2 0/4] lockdep/crossrelease: Apply crossrelease to page locks

2017-12-04 Thread Matthew Wilcox
On Tue, Dec 05, 2017 at 03:19:46PM +0900, Byungchul Park wrote:
> On 12/5/2017 2:46 PM, Byungchul Park wrote:
> > On 12/5/2017 2:30 PM, Matthew Wilcox wrote:
> > > On Mon, Dec 04, 2017 at 02:16:19PM +0900, Byungchul Park wrote:
> > > > For now, wait_for_completion() / complete() works with lockdep, add
> > > > lock_page() / unlock_page() and its family to lockdep support.
> > > > 
> > > > Changes from v1
> > > >   - Move lockdep_map_cross outside of page_ext to make it flexible
> > > >   - Prevent allocating lockdep_map per page by default
> > > >   - Add a boot parameter allowing the allocation for debugging
> > > > 
> > > > Byungchul Park (4):
> > > >    lockdep: Apply crossrelease to PG_locked locks
> > > >    lockdep: Apply lock_acquire(release) on __Set(__Clear)PageLocked
> > > >    lockdep: Move data of CONFIG_LOCKDEP_PAGELOCK from page to page_ext
> > > >    lockdep: Add a boot parameter enabling to track page locks using
> > > >  lockdep and disable it by default
> > > 
> > > I don't like the way you've structured this patch series; first adding
> > > the lockdep map to struct page, then moving it to page_ext.
> > 
> > Hello,
> > 
> > I will make them into one patch.
> 
> I've thought it more.
> 
> Actually I did it because I thought I'd better make it into two
> patches since it makes reviewers easier to review. It doesn't matter
> which one I choose, but I prefer to split it.

I don't know whether it's better to make it all one patch or split it
into multiple patches.  But it makes no sense to introduce it in struct
page, then move it to struct page_ext.


Re: [PATCH v3 1/1] at24: support eeproms that do not auto-rollover reads.

2017-12-04 Thread Sakari Ailus
On Mon, Dec 04, 2017 at 05:24:33PM -0500, Sven Van Asbroeck wrote:
> > If this is truly specific to at24, then vendor prefix would be appropriate,
> > plus it'd go to an at24 specific binding file. However if it isn't I'd just
> > remove the above sentence. I guess the latter?
> 
> Yes, no-read-rollover is truly specific to at24.c, because it applies only
> to i2c multi-address chips. The at25 is spi based so cannot have multiple
> addresses.
> 
> So yes, "at24,no-read-rollover" would perhaps be a better name.
> 
> Regarding an at24 specific binding file. You're saying I should create
> Documentation/devicetree/bindings/eeprom/at24.txt ? Should I indicate
> that at24.txt "inherits from" eeprom.txt? Note that at25.txt does not
> currently do this.

Hmm. I actually missed we didn't have one to begin with. at25.txt exists
and it documents a number of properties specific to at25, so if at24 will
have an at24-specific property, then I think it should go to a separate
file.

Aren't there really other chips which need this? It'd be (a little bit)
easier to just remove the sentence. :-)

-- 
Regards,

Sakari Ailus
sakari.ai...@linux.intel.com


Re: [PATCH v2] mmap.2: MAP_FIXED updated documentation

2017-12-04 Thread John Hubbard
On 12/04/2017 11:08 PM, Michal Hocko wrote:
> On Mon 04-12-17 18:52:27, John Hubbard wrote:
>> On 12/04/2017 03:31 AM, Mike Rapoport wrote:
>>> On Sun, Dec 03, 2017 at 06:14:11PM -0800, john.hubb...@gmail.com wrote:
 From: John Hubbard 

>> [...]
 +.IP
 +Given the above limitations, one of the very few ways to use this option
 +safely is: mmap() a region, without specifying MAP_FIXED. Then, within 
 that
 +region, call mmap(MAP_FIXED) to suballocate regions. This avoids both the
 +portability problem (because the first mmap call lets the kernel pick the
 +address), and the address space corruption problem (because the region 
 being
 +overwritten is already owned by the calling thread).
>>>
>>> Maybe "address space corruption problem caused by implicit calls to mmap"?
>>> The region allocated with the first mmap is not exactly owned by the
>>> thread and a multi-thread application can still corrupt its memory if
>>> different threads use mmap(MAP_FIXED) for overlapping regions.
>>>
>>> My 2 cents.
>>>
>>
>> Hi Mike,
>>
>> Yes, thanks for picking through this, and I agree that the above is 
>> misleading.
>> It should definitely not use the word "owned" at all. Re-doing the whole 
>> paragraph in order to make it all fit together nicely, I get this:
>>
>> "Given the above limitations, one of the very few ways to use this option
>> safely is: mmap() an enclosing region, without specifying MAP_FIXED.
>> Then, within that region, call mmap(MAP_FIXED) to suballocate regions
>> within the enclosing region. This avoids both the portability problem 
>> (because the first mmap call lets the kernel pick the address), and the 
>> address space corruption problem (because implicit calls to mmap will 
>> not affect the already-mapped enclosing region)."
>>
>> ...how's that sound to you? I'll post a v3 soon with this.
> 
> It sounds to me you are trying to tell way to much while actually being
> a bit misleading. Even sub-range MAP_FIXED is not multi-thread safe.
> 
> Really the more corner cases you will try to cover the worse the end
> result will end up. I would just try to be simple here and mention the
> address space corruption issues you've had earlier and be done with it.
> Maybe add a note that some architectures might need a special alignement
> and fail if it is not the case but nothing really specific.
> 

Sure, I can drop the "how to use this safely" section.  It seemed like a good
idea at the time... :)

thanks,
John Hubbard
NVIDIA


Re: [PATCH v2] mmap.2: MAP_FIXED updated documentation

2017-12-04 Thread John Hubbard
On 12/04/2017 11:05 PM, Michal Hocko wrote:
> On Mon 04-12-17 18:14:18, John Hubbard wrote:
>> On 12/04/2017 02:55 AM, Cyril Hrubis wrote:
>>> Hi!
>>> I know that we are not touching the rest of the existing description for
>>> MAP_FIXED however the second sentence in the manual page says that "addr
>>> must be a multiple of the page size." Which however is misleading as
>>> this is not enough on some architectures. Code in the wild seems to
>>> (mis)use SHMLBA for aligment purposes but I'm not sure that we should
>>> advise something like that in the manpages.
>>>
>>> So what about something as:
>>>
>>> "addr must be suitably aligned, for most architectures multiple of page
>>> size is sufficient, however some may impose additional restrictions for
>>> page mapping addresses."
>>>
>>
>> Hi Cyril,
>>
>> Right, so I've been looking into this today, and I think we can go a bit
>> further than that, even. The kernel, as far back as the *original* git
>> commit in 2005, implements mmap on ARM by requiring that the address is
>> aligned to SHMLBA:
>>
>> arch/arm/mm/mmap.c:50:
>>
>>  if (flags & MAP_FIXED) {
>>  if (aliasing && flags & MAP_SHARED &&
>>  (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
>>  return -EINVAL;
>>  return addr;
>>  }
>>
>> So, given that this has been the implementation for the last 12+ years (and
>> probably the whole time, in fact), I think we can be bold enough to use this
>> wording for the second sentence of MAP_FIXED:
>>
>> "addr must be a multiple of SHMLBA (), which in turn is either
>> the system page size (on many architectures) or a multiple of the system
>> page size (on some architectures)."
>>
>> What do you think?
> 
> I am not sure this is a good idea. This is pulling way too many
> implementation details into the man page IMHO. Note that your wording is
> even incorrect because this applies only to shared mappings and on some
> architectures it even requires special memory regions. We do not want
> all that in the man page...
> 

Hi Michal,

OK, so it sounds like Cyril's original wording would be just about right,
after all, like this?

"addr must be suitably aligned. For most architectures multiple of page
size is sufficient; however, some may impose additional restrictions."

(It does seem unfortunate that the man page cannot help the programmer
actually write correct code here. He or she is forced to read the kernel
implementation, in order to figure out the true alignment rules. I was
hoping we could avoid that.)

thanks,
John Hubbard
NVIDIA




Re: [PATCH v3 13/16] iommu/intel-svm: notify page request to guest

2017-12-04 Thread Lu Baolu
Hi,

On 11/18/2017 02:55 AM, Jacob Pan wrote:
> If the source device of a page request has its PASID table pointer
> bond to a guest, the first level page tables are owned by the guest.
> In this case, we shall let guest OS to manage page fault.
>
> This patch uses the IOMMU fault notification API to send notifications,
> possibly via VFIO, to the guest OS. Once guest pages are fault in, guest
> will issue page response which will be passed down via the invalidation
> passdown APIs.
>
> Signed-off-by: Jacob Pan 
> Signed-off-by: Ashok Raj 
> ---
>  drivers/iommu/intel-svm.c | 80 
> ++-
>  include/linux/iommu.h |  1 +
>  2 files changed, 74 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
> index f6697e5..77c25d8 100644
> --- a/drivers/iommu/intel-svm.c
> +++ b/drivers/iommu/intel-svm.c
> @@ -555,6 +555,71 @@ static bool is_canonical_address(u64 addr)
>   return (((saddr << shift) >> shift) == saddr);
>  }
>  
> +static int prq_to_iommu_prot(struct page_req_dsc *req)
> +{
> + int prot = 0;
> +
> + if (req->rd_req)
> + prot |= IOMMU_FAULT_READ;
> + if (req->wr_req)
> + prot |= IOMMU_FAULT_WRITE;
> + if (req->exe_req)
> + prot |= IOMMU_FAULT_EXEC;
> + if (req->priv_req)
> + prot |= IOMMU_FAULT_PRIV;
> +
> + return prot;
> +}
> +
> +static int intel_svm_prq_report(struct device *dev, struct page_req_dsc 
> *desc)
> +{
> + int ret = 0;

It seems that "ret" should be initialized as -EINVAL. Otherwise, this function
will return 0 for devices which have no fault handlers, and all page requests
will be ignored by iommu driver.

> + struct iommu_fault_event event;
> + struct pci_dev *pdev;
> +
> + /**
> +  * If caller does not provide struct device, this is the case where
> +  * guest PASID table is bound to the device. So we need to retrieve
> +  * struct device from the page request descriptor then proceed.
> +  */
> + if (!dev) {
> + pdev = pci_get_bus_and_slot(desc->bus, desc->devfn);
> + if (!pdev) {
> + pr_err("No PCI device found for PRQ [%02x:%02x.%d]\n",
> + desc->bus, PCI_SLOT(desc->devfn),
> + PCI_FUNC(desc->devfn));
> + return -ENODEV;
> + }
> + dev = &pdev->dev;
> + } else if (dev_is_pci(dev)) {
> + pdev = to_pci_dev(dev);
> + pci_dev_get(pdev);
> + } else
> + return -ENODEV;
> +
> + pr_debug("Notify PRQ device [%02x:%02x.%d]\n",
> + desc->bus, PCI_SLOT(desc->devfn),
> + PCI_FUNC(desc->devfn));
> +
> + /* invoke device fault handler if registered */
> + if (iommu_has_device_fault_handler(dev)) {
> + /* Fill in event data for device specific processing */
> + event.type = IOMMU_FAULT_PAGE_REQ;
> + event.addr = desc->addr;
> + event.pasid = desc->pasid;
> + event.page_req_group_id = desc->prg_index;
> + event.prot = prq_to_iommu_prot(desc);
> + event.last_req = desc->lpig;
> + event.pasid_valid = 1;
> + event.iommu_private = desc->private;
> + ret = iommu_report_device_fault(&pdev->dev, &event);
> + }
> +
> + pci_dev_put(pdev);
> +
> + return ret;
> +}
> +
>  static irqreturn_t prq_event_thread(int irq, void *d)
>  {
>   struct intel_iommu *iommu = d;
> @@ -578,7 +643,12 @@ static irqreturn_t prq_event_thread(int irq, void *d)
>   handled = 1;
>  
>   req = &iommu->prq[head / sizeof(*req)];
> -
> + /**
> +  * If prq is to be handled outside iommu driver via receiver of
> +  * the fault notifiers, we skip the page response here.
> +  */
> + if (!intel_svm_prq_report(NULL, req))
> + goto prq_advance;
>   result = QI_RESP_FAILURE;
>   address = (u64)req->addr << VTD_PAGE_SHIFT;
>   if (!req->pasid_present) {
> @@ -649,11 +719,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
>   if (WARN_ON(&sdev->list == &svm->devs))
>   sdev = NULL;
>  
> - if (sdev && sdev->ops && sdev->ops->fault_cb) {
> - int rwxp = (req->rd_req << 3) | (req->wr_req << 2) |
> - (req->exe_req << 1) | (req->priv_req);
> - sdev->ops->fault_cb(sdev->dev, req->pasid, req->addr, 
> req->private, rwxp, result);
> - }
> + intel_svm_prq_report(sdev->dev, req);

Do you mind explaining why we need to report this request twice?

Best regards,
Lu Baolu

>   /* We get here in the error case where the PASID lookup failed,
>  and these can be NULL. Do not use them below this point! */

Re: [patch V4 02/11] LICENSES: Add the GPL 2.0 license

2017-12-04 Thread Greg Kroah-Hartman
On Mon, Dec 04, 2017 at 10:19:29PM +0100, Thomas Gleixner wrote:
> Add the full text of the GPL 2.0 license to the LICENSES directory.  It was
> copied directly from the COPYING file in the kernel source tree as it
> differs from the public available version of the license in various places
> including the FSF.
> 
> Philippe did some research on the GPL2.0 history:
> 
>   There is NO trustworthy version of an official GPL 2.0 text: the FSF
>   official texts are all fubar (if only in small and subtle ways). The FSF
>   texts should be authoritative, but then which one? They published more
>   GPL 2.0 versions than most. So we would be hard pressed to blame SPDX or
>   the OSI for having their own minor variant.
> 
>   Then in digging further, I found the ONE true original GPL with a file
>   time stamp on June 2 1991, 01:50 (AM?, PM? unknown time zone?)  ! in an
>   old GCC archive.
> 
>   For the posterity and everyone's enjoyment I have built a git history
>   of GPL 2.0 Mark1 to Mark6
> 
>   See https://github.com/pombredanne/gpl-history/commits/master/COPYING
> 
>   I also added a shorter history of the Linux COPYING text. The first
>   version in Linus's git tree is based on the very fine and well tuned GPL
>   2 Mark4, the first fully Y2K compliant version of the GPL 2, as you can
>   see from the diffs with the former Mark3: that was dangerously stuck in
>   the last century.
> 
>   The current version in is based on a rare GPL 2.0 Mark5.1 aka "Franklin
>   St", that I do not have in my history yet and spells "Franklin St."
>   rather than "Franklin Street."  Therefore there is likely another GPL 2.0
>   version between Mark4 and Mark5 that I have yet to find and may not have
>   been caught by the archive.org spiders. Here help and patches welcomed:
>   this is likely an important missing link.
> 
>   Further information about this archaelogical research;
>   
>   
> http://lkml.kernel.org/r/CAOFm3uEzRMf261+O-Nm+9HDoEn9RbFjH=5j9i1c2ggmug2g...@mail.gmail.com
> 
> Add the required tags for reference and tooling.
> 
> Signed-off-by: Thomas Gleixner 

Reviewed-by: Greg Kroah-Hartman 


RE: [PATCH] refcount_t: documentation for memory ordering differences

2017-12-04 Thread Reshetova, Elena
 On 11/29/2017 04:36 AM, Elena Reshetova wrote:
> > Some functions from refcount_t API provide different
> > memory ordering guarantees that their atomic counterparts.
> > This adds a document outlining these differences.
> >
> > Signed-off-by: Elena Reshetova 
> > ---
> >  Documentation/core-api/index.rst  |   1 +
> >  Documentation/core-api/refcount-vs-atomic.rst | 129
> ++
> >  2 files changed, 130 insertions(+)
> >  create mode 100644 Documentation/core-api/refcount-vs-atomic.rst
> 
> > diff --git a/Documentation/core-api/refcount-vs-atomic.rst
> b/Documentation/core-api/refcount-vs-atomic.rst
> > new file mode 100644
> > index 000..5619d48
> > --- /dev/null
> > +++ b/Documentation/core-api/refcount-vs-atomic.rst
> > @@ -0,0 +1,129 @@
> > +===
> > +refcount_t API compared to atomic_t
> > +===
> > +
> > +The goal of refcount_t API is to provide a minimal API for implementing
> > +an object's reference counters. While a generic architecture-independent
> > +implementation from lib/refcount.c uses atomic operations underneath,
> > +there are a number of differences between some of the refcount_*() and
> > +atomic_*() functions with regards to the memory ordering guarantees.
> > +This document outlines the differences and provides respective examples
> > +in order to help maintainers validate their code against the change in
> > +these memory ordering guarantees.
> > +
> > +memory-barriers.txt and atomic_t.txt provide more background to the
> > +memory ordering in general and for atomic operations specifically.
> > +
> > +Relevant types of memory ordering
> > +=
> > +
> > +**Note**: the following section only covers some of the memory
> > +ordering types that are relevant for the atomics and reference
> > +counters and used through this document. For a much broader picture
> > +please consult memory-barriers.txt document.
> > +
> > +In the absence of any memory ordering guarantees (i.e. fully unordered)
> > +atomics & refcounters only provide atomicity and
> > +program order (po) relation (on the same CPU). It guarantees that
> > +each atomic_*() and refcount_*() operation is atomic and instructions
> > +are executed in program order on a single CPU.
> > +This is implemented using READ_ONCE()/WRITE_ONCE() and
> > +compare-and-swap primitives.
> > +
> > +A strong (full) memory ordering guarantees that all prior loads and
> > +stores (all po-earlier instructions) on the same CPU are completed
> > +before any po-later instruction is executed on the same CPU.
> > +It also guarantees that all po-earlier stores on the same CPU
> > +and all propagated stores from other CPUs must propagate to all
> > +other CPUs before any po-later instruction is executed on the original
> > +CPU (A-cumulative property). This is implemented using smp_mb().
> 
> I don't know what "A-cumulative property" means, and google search didn't
> either.
> 
> Is it non-cumulative, similar to typical vs. atypical, where atypical
> roughly means non-typical.  Or is it accumlative (something being
> accumulated, summed up, gathered up)?
> 
> Or is it something else.. TBD?


Sorry, I should have mentioned also explicitly in this document where the terms 
are
coming from. I have mentioned in cover letter, but failed to say here. 
I will fix it. 

Thank you for catching! I see that reply was already given to this by Andrea. 

Best Regards,
Elena


> 
> > +A RELEASE memory ordering guarantees that all prior loads and
> > +stores (all po-earlier instructions) on the same CPU are completed
> > +before the operation. It also guarantees that all po-earlier
> > +stores on the same CPU and all propagated stores from other CPUs
> > +must propagate to all other CPUs before the release operation
> > +(A-cumulative property). This is implemented using smp_store_release().
> 
> thanks.
> --
> ~Randy


Re: [PATCH 21/45] usb: typec: remove duplicate includes

2017-12-04 Thread Heikki Krogerus
On Tue, Dec 05, 2017 at 07:34:55AM +0530, Pravin Shedge wrote:
> These duplicate includes have been found with scripts/checkincludes.pl but
> they have been removed manually to avoid removing false positives.
> 
> Signed-off-by: Pravin Shedge 

Acked-by: Heikki Krogerus 

> ---
>  drivers/usb/typec/fusb302/fusb302.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/usb/typec/fusb302/fusb302.c 
> b/drivers/usb/typec/fusb302/fusb302.c
> index 72cb060..a3e4cc9 100644
> --- a/drivers/usb/typec/fusb302/fusb302.c
> +++ b/drivers/usb/typec/fusb302/fusb302.c
> @@ -16,7 +16,6 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 

Thanks,

-- 
heikki


Re: [PATCH net-next V3] tun: add eBPF based queue selection method

2017-12-04 Thread Jason Wang



On 2017年12月05日 08:16, Willem de Bruijn wrote:

On Mon, Dec 4, 2017 at 4:31 AM, Jason Wang  wrote:

This patch introduces an eBPF based queue selection method. With this,
the policy could be offloaded to userspace completely through a new
ioctl TUNSETSTEERINGEBPF.

Signed-off-by: Jason Wang 
---
+static u16 tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *skb)
+{
+   struct tun_steering_prog *prog;
+   u16 ret = 0;
+
+   prog = rcu_dereference(tun->steering_prog);
+   if (prog)
+   ret = bpf_prog_run_clear_cb(prog->prog, skb);

This dereferences tun->steering_prog for a second time. It is safe
in this load balancing case to assign a few extra packets to queue 0.
But the issue can also be avoided by replacing the function with a
direct call in tun_net_xmit:

struct tun_steering_prog *s = rcu_dereference(tun->steering_prog);
if (s)
ret = bpf_prog_run_clear_cb(s->prog, skb) % tun->numqueues;


Right.




  /* Net device start xmit */
-static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
+static void tun_automq_xmit(struct tun_struct *tun, struct sk_buff *skb)
  {
-   struct tun_struct *tun = netdev_priv(dev);
-   int txq = skb->queue_mapping;
-   struct tun_file *tfile;
-   u32 numqueues = 0;
-
-   rcu_read_lock();
-   tfile = rcu_dereference(tun->tfiles[txq]);
-   numqueues = READ_ONCE(tun->numqueues);
-
-   /* Drop packet if interface is not attached */
-   if (txq >= numqueues)
-   goto drop;
-
  #ifdef CONFIG_RPS
-   if (numqueues == 1 && static_key_false(&rps_needed)) {
+   if (tun->numqueues == 1 && static_key_false(&rps_needed)) {
 /* Select queue was not called for the skbuff, so we extract 
the
  * RPS hash and save it into the flow_table here.
  */
@@ -969,6 +986,26 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, 
struct net_device *dev)
 }
 }
  #endif
+}
+
+/* Net device start xmit */
+static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+   struct tun_struct *tun = netdev_priv(dev);
+   int txq = skb->queue_mapping;
+   struct tun_file *tfile;
+   u32 numqueues = 0;
+
+   rcu_read_lock();
+   tfile = rcu_dereference(tun->tfiles[txq]);
+   numqueues = READ_ONCE(tun->numqueues);

Now tun->numqueues is read twice, reversing commit fa35864e0bb7
("tuntap: Fix for a race in accessing numqueues"). I don't see anything
left that would cause a divide by zero after the relevant code was
converted from divide to multiple and subsequently even removed.

But if it's safe to read multiple times, might as well remove the READ_ONCE.


Good point, but READ_ONCE() is not something new, we'd better change 
this in another patch.





@@ -1551,7 +1588,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, 
struct tun_file *tfile,
 int copylen;
 bool zerocopy = false;
 int err;
-   u32 rxhash;
+   u32 rxhash = 0;
 int skb_xdp = 1;
 bool frags = tun_napi_frags_enabled(tun);

@@ -1739,7 +1776,10 @@ static ssize_t tun_get_user(struct tun_struct *tun, 
struct tun_file *tfile,
 rcu_read_unlock();
 }

-   rxhash = __skb_get_hash_symmetric(skb);
+   rcu_read_lock();
+   if (!rcu_dereference(tun->steering_prog))
+   rxhash = __skb_get_hash_symmetric(skb);
+   rcu_read_unlock();

 if (frags) {
 /* Exercise flow dissector code path. */
@@ -1783,7 +1823,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, 
struct tun_file *tfile,
 u64_stats_update_end(&stats->syncp);
 put_cpu_ptr(stats);

-   tun_flow_update(tun, rxhash, tfile);
+   if (rxhash)
+   tun_flow_update(tun, rxhash, tfile);
+

Nit: zero is a valid hash? In which case, an int64_t initialized to -1 is the
safer check.


Looks not? E.g looking at __flow_hash_from_keys() it did:

static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
{
    u32 hash;

    __flow_hash_consistentify(keys);

    hash = __flow_hash_words(flow_keys_hash_start(keys),
                 flow_keys_hash_length(keys), keyval);
    if (!hash)
        hash = 1;

    return hash;
}

Thanks


Re: [PATCH v2] sunxi-rsb: Include OF based modalias in device uevent

2017-12-04 Thread Chen-Yu Tsai
Hi,

On Tue, Nov 28, 2017 at 11:47 PM, Maxime Ripard
 wrote:
> On Mon, Nov 27, 2017 at 08:05:34PM +0100, Stefan Brüns wrote:
>> Include the OF-based modalias in the uevent sent when registering devices
>> on the sunxi RSB bus, so that user space has a chance to autoload the
>> kernel module for the device.
>>
>> Fixes a regression caused by commit 3f241bfa60bd ("arm64: allwinner: a64:
>> pine64: Use dcdc1 regulator for mmc0"). When the axp20x-rsb module for
>> the AXP803 PMIC is built as a module, it is not loaded and the system
>> ends up with an disfunctional MMC controller.
>>

Tags should be:

Fixes: d787dcdb9c8f ("bus: sunxi-rsb: Add driver for Allwinner Reduced
Serial Bus")
Cc: stable  # 4.4.x 7a3b7cd332db of: device:
Export of_device_{get_modalias, uvent_modalias} to modules

>> Cc: stable 
>> Signed-off-by: Stefan Brüns 
>
> Acked-by: Maxime Ripard 

Acked-by: Chen-Yu Tsai 

Maxime, could you merge this as a fix to get it in fast?

ChenYu


Re: [PATCH] checkpatch: warn for use of %px

2017-12-04 Thread Joe Perches
On Tue, 2017-12-05 at 08:17 +1100, Tobin C. Harding wrote:
> Usage of the new %px specifier potentially leaks sensitive
> inforamtion. Printing kernel addresses exposes the kernel layout in

information

> memory, this is potentially exploitable. We have tools in the kernel to
> help us do the right thing. We can have checkpatch warn developers of
> potential dangers of using %px.
> 
> Have checkpatch emit a warning for usage of specifier %px.
> 
> Suggested-by: Andrew Morton 
> Signed-off-by: Tobin C. Harding 
> Co-Developed-by: Joe Perches 
> 
> ---
> 
> Joe,
> 
> Are you happy with this tagging? Needs your signed-off-by still.

Maybe with a few corrections (below)
> 
> Andrew,
> 
> Is it okay to add your Suggested-by tag here?
> 
> I'm not entirely sure when one is supposed to add someones signed-off-by
> tag since the docs state that it should not be added without
> permission. I am also unsure where/when is the best time to request this
> permission.
[]
> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
[]
> @@ -1612,6 +1612,17 @@ sub raw_line {
>   return $line;
>  }
>  
> +sub stat_real {
> + my ($linenr, $lc) = @_;
> +
> + my $stat_real = raw_line($linenr, 0);
> + for (my $count = $linenr + 1; $count <= $lc; $count++) {
> + $stat_real = $stat_real . "\n" . raw_line($count, 0);
> + }
> +
> + return $stat_real;
> +}

If you are going to make a subroutine of this
there are some other places it could be used too.

> +
>  sub cat_vet {
>   my ($vet) = @_;
>   my ($res, $coded);
> @@ -5747,24 +5758,35 @@ sub process {
>   defined $stat &&
>   $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
>   $1 !~ /^_*volatile_*$/) {
> - my $bad_extension = "";
> + my ($specifier, $extension, $stat_real);

My preference is not to define multiple variables on a single line.
I'd rather have:
my $specifier;
my $extension;
my $stat_real;

> + my $bad_specifier = "";
>   my $lc = $stat =~ tr@\n@@;
>   $lc = $lc + $linenr;
>   for (my $count = $linenr; $count <= $lc; $count++) {
>   my $fmt = get_quoted_string($lines[$count - 1], 
> raw_line($count, 0));
>   $fmt =~ s/%%//g;
> - if ($fmt =~ 
> /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNOx]).)/) {
> - $bad_extension = $1;
> - last;
> +
> + while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) {
> + $specifier = $1;
> + $extension = $2;
> + if ($extension !~ 
> /[FfSsBKRraEhMmIiUDdgVCbGNOx]/) {
> + $bad_specifier = $specifier;
> + last;
> + }
> + if ($extension eq "x" && 
> !defined($stat_real)) {
> + if (!defined($stat_real)) {
> + $stat_real = 
> stat_real($linenr, $lc);
> + }
> + WARN("VSPRINTF_SPECIFIER_PX",
> +  "Using vsprintf specifier 
> '\%px' potentially exposes the kernel layout in memory, if you don't _realy_ 
> need the address please consider using '\%p'.\n" . "$here\n$stat_real\n");  

"kernel memory layout" not "kernel layout in memory"
"really" not "_realy_"



Re: [PATCH v9 3/5] perf utils: use pmu->is_uncore to detect PMU UNCORE devices

2017-12-04 Thread Jin, Yao

Hi,

I applied the diff but it's failed.

jinyao@skl:~/skl-ws/perf-dev/lck-4594/src$ patch -p1 < 1.pat
patching file tools/perf/util/pmu.c
patch:  malformed patch at line 41: *head, struct perf_pmu *pmu)

Could you send the patch as attachment to me in another mail thread?

to yao@linux.intel.com
cc yao@intel.com

Thanks
Jin Yao

On 12/5/2017 3:12 PM, Ganapatrao Kulkarni wrote:

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 5ad8a18..57e38fd 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -538,6 +538,34 @@ static bool pmu_is_uncore(const char *name)
  }

  /*
+ *  PMU CORE devices have different name other than cpu in sysfs on some
+ *  platforms. looking for possible sysfs files to identify as core device.
+ */
+static int is_pmu_core(const char *name)
+{
+ struct stat st;
+ char path[PATH_MAX];
+ const char *sysfs = sysfs__mountpoint();
+
+ if (!sysfs)
+ return 0;
+
+ /* Look for cpu sysfs (x86 and others) */
+ scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu", sysfs);
+ if ((stat(path, &st) == 0) &&
+ (strncmp(name, "cpu", strlen("cpu")) == 0))
+ return 1;
+
+ /* Look for cpu sysfs (specific to arm) */
+ scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus",
+ sysfs, name);
+ if (stat(path, &st) == 0)
+ return 1;
+
+ return 0;
+}
+
+/*
   * Return the CPU id as a raw string.
   *
   * Each architecture should provide a more precise id string that
@@ -641,7 +669,7 @@ static void pmu_add_cpu_aliases(struct list_head
*head, struct perf_pmu *pmu)
   break;
   }

- if (pmu->is_uncore) {
+ if (!is_pmu_core(name)) {
   /* check for uncore devices */
   if (pe->pmu == NULL)
   continue;


Re: [PATCH 4.4 00/27] 4.4.104-stable review

2017-12-04 Thread Naresh Kamboju
On 4 December 2017 at 21:29, Greg Kroah-Hartman
 wrote:
> This is the start of the stable review cycle for the 4.4.104 release.
> There are 27 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Wed Dec  6 15:59:33 UTC 2017.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.104-rc1.gz
> or in the git tree and branch at:
>   git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> linux-4.4.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>

Results from Linaro’s test farm.
No regressions on arm64, arm and x86_64.

Summary


kernel: 4.4.104-rc1
git repo: 
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.4.y
git commit: 998ef014deff90a607c74c706b5bed3115931b61
git describe: v4.4.103-28-g998ef014deff
Test details: 
https://qa-reports.linaro.org/lkft/linux-stable-rc-4.4-oe/build/v4.4.103-28-g998ef014deff


No regressions (compared to build v4.4.103-28-ge1e2e6c522e1)

Boards, architectures and test suites:
-

juno-r2 - arm64
* boot - pass: 20,
* kselftest - fail: 1, pass: 27, skip: 25
* libhugetlbfs - pass: 90, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 28, skip: 36
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 60,
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 22,
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 10,
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 936, skip: 159
* ltp-timers-tests - pass: 12,

x15 - arm
* boot - pass: 20,
* kselftest - pass: 26, skip: 28
* libhugetlbfs - pass: 87, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 64,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 60,
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 20, skip: 2
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 13, skip: 1
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 1035, skip: 67
* ltp-timers-tests - pass: 12,

x86_64
* boot - pass: 20,
* kselftest - pass: 39, skip: 31
* libhugetlbfs - pass: 76, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 64,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 61, skip: 1
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 22,
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 9, skip: 1
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 956, skip: 164
* ltp-timers-tests - pass: 12,

And the arm64 hikey results.

Summary


kernel: 4.4.104-rc1
git repo: https://git.linaro.org/lkft/arm64-stable-rc.git
git tag: 4.4.104-rc1-hikey-20171204-67
git commit: fc49d1746dc96bedfe5bf072eecbe84410972db0
git describe: 4.4.104-rc1-hikey-20171204-67
Test details: 
https://qa-reports.linaro.org/lkft/linaro-hikey-stable-rc-4.4-oe/build/4.4.104-rc1-hikey-20171204-67


No regressions (compared to build 4.4.104-rc1-hikey-20171204-66)

Boards, architectures and test suites:
-

hi6220-hikey - arm64
* boot - pass: 20,
* kselftest - pass: 25, skip: 29
* libhugetlbfs - pass: 90, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 28, skip: 36
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 60,
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 21, skip: 1
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 14,
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 979, skip: 124
* ltp-timers-tests - pass: 12,

Documentation - https://collaborate.linaro.org/display/LKFT/Email+Reports

Tested-by: Naresh Kamboju 


Re: [PATCH v2 net-next] net/tcp: trace all TCP/IP state transition with tcp_set_state tracepoint

2017-12-04 Thread Yafang Shao
2017-12-05 3:28 GMT+08:00 Marcelo Ricardo Leitner :
> On Sat, Dec 02, 2017 at 09:36:41AM +, Yafang Shao wrote:
>> The TCP/IP transition from TCP_LISTEN to TCP_SYN_RECV and some other
>> transitions are not traced with tcp_set_state tracepoint.
>>
>> In order to trace the whole tcp lifespans, two helpers are introduced,
>> void __tcp_set_state(struct sock *sk, int state)
>> void __sk_state_store(struct sock *sk, int newstate)
>>
>> When do TCP/IP state transition, we should use these two helpers or use
>> tcp_set_state() other than assigning a value to sk_state directly.
>>
>> Signed-off-by: Yafang Shao 
>>
>> ---
>> v2: test
>> ---
>>  include/net/tcp.h   |  2 ++
>>  net/ipv4/inet_connection_sock.c |  6 +++---
>>  net/ipv4/inet_hashtables.c  |  2 +-
>>  net/ipv4/tcp.c  | 12 
>>  4 files changed, 18 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>> index 85ea578..4f2d015 100644
>> --- a/include/net/tcp.h
>> +++ b/include/net/tcp.h
>> @@ -1247,6 +1247,8 @@ static inline bool tcp_checksum_complete(struct 
>> sk_buff *skb)
>>   "Close Wait","Last ACK","Listen","Closing"
>>  };
>>  #endif
>> +void __sk_state_store(struct sock *sk, int newstate);
>> +void __tcp_set_state(struct sock *sk, int state);
>>  void tcp_set_state(struct sock *sk, int state);
>>
>>  void tcp_done(struct sock *sk);
>> diff --git a/net/ipv4/inet_connection_sock.c 
>> b/net/ipv4/inet_connection_sock.c
>> index 4ca46dc..f3967f1 100644
>> --- a/net/ipv4/inet_connection_sock.c
>> +++ b/net/ipv4/inet_connection_sock.c
>> @@ -783,7 +783,7 @@ struct sock *inet_csk_clone_lock(const struct sock *sk,
>>   if (newsk) {
>>   struct inet_connection_sock *newicsk = inet_csk(newsk);
>>
>> - newsk->sk_state = TCP_SYN_RECV;
>> + __tcp_set_state(newsk, TCP_SYN_RECV);
>>   newicsk->icsk_bind_hash = NULL;
>>
>>   inet_sk(newsk)->inet_dport = inet_rsk(req)->ir_rmt_port;
>> @@ -877,7 +877,7 @@ int inet_csk_listen_start(struct sock *sk, int backlog)
>>* It is OK, because this socket enters to hash table only
>>* after validation is complete.
>>*/
>> - sk_state_store(sk, TCP_LISTEN);
>> + __sk_state_store(sk, TCP_LISTEN);
>>   if (!sk->sk_prot->get_port(sk, inet->inet_num)) {
>>   inet->inet_sport = htons(inet->inet_num);
>>
>> @@ -888,7 +888,7 @@ int inet_csk_listen_start(struct sock *sk, int backlog)
>>   return 0;
>>   }
>>
>> - sk->sk_state = TCP_CLOSE;
>> + __tcp_set_state(sk, TCP_CLOSE);
>>   return err;
>>  }
>>  EXPORT_SYMBOL_GPL(inet_csk_listen_start);
>> diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
>> index e7d15fb..72c15b6 100644
>> --- a/net/ipv4/inet_hashtables.c
>> +++ b/net/ipv4/inet_hashtables.c
>> @@ -430,7 +430,7 @@ bool inet_ehash_nolisten(struct sock *sk, struct sock 
>> *osk)
>>   sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
>>   } else {
>>   percpu_counter_inc(sk->sk_prot->orphan_count);
>> - sk->sk_state = TCP_CLOSE;
>> + __tcp_set_state(sk, TCP_CLOSE);
>>   sock_set_flag(sk, SOCK_DEAD);
>>   inet_csk_destroy_sock(sk);
>>   }
>> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
>> index bf97317..2bc7e04 100644
>> --- a/net/ipv4/tcp.c
>> +++ b/net/ipv4/tcp.c
>> @@ -2036,6 +2036,18 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, 
>> size_t len, int nonblock,
>>  }
>>  EXPORT_SYMBOL(tcp_recvmsg);
>>
>> +void __sk_state_store(struct sock *sk, int newstate)
>> +{
>> + trace_tcp_set_state(sk, sk->sk_state, newstate);
>> + sk_state_store(sk, newstate);
>
> This sounds counter-intuitive, to have a __func() to call func(). It's
> usually the other way around.

Agree to that.

> There is only 1 call to sk_state_store in the stack, what about
> inverting these __ ?
>

Sounds like a good idea.

> I guess you applied the same standard as to the one below, but it's a
> different case.
>
>> +}
>> +
>> +void __tcp_set_state(struct sock *sk, int state)
>> +{
>> + trace_tcp_set_state(sk, sk->sk_state, state);
>> + sk->sk_state = state;
>> +}
>> +
>>  void tcp_set_state(struct sock *sk, int state)
>>  {
>>   int oldstate = sk->sk_state;
>> --
>> 1.8.3.1
>>


Re: [PATCH v9 3/5] perf utils: use pmu->is_uncore to detect PMU UNCORE devices

2017-12-04 Thread Ganapatrao Kulkarni
thanks Jin Yao for point this out.

looks like logic of leveraging uncore device type(which i have changed
in v9) does not go well
with some json events of x86.
can you please try below diff(logic used till v8), which keeps the
original logic of identifying core/cpu PMUs.


diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 5ad8a18..57e38fd 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -538,6 +538,34 @@ static bool pmu_is_uncore(const char *name)
 }

 /*
+ *  PMU CORE devices have different name other than cpu in sysfs on some
+ *  platforms. looking for possible sysfs files to identify as core device.
+ */
+static int is_pmu_core(const char *name)
+{
+ struct stat st;
+ char path[PATH_MAX];
+ const char *sysfs = sysfs__mountpoint();
+
+ if (!sysfs)
+ return 0;
+
+ /* Look for cpu sysfs (x86 and others) */
+ scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu", sysfs);
+ if ((stat(path, &st) == 0) &&
+ (strncmp(name, "cpu", strlen("cpu")) == 0))
+ return 1;
+
+ /* Look for cpu sysfs (specific to arm) */
+ scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus",
+ sysfs, name);
+ if (stat(path, &st) == 0)
+ return 1;
+
+ return 0;
+}
+
+/*
  * Return the CPU id as a raw string.
  *
  * Each architecture should provide a more precise id string that
@@ -641,7 +669,7 @@ static void pmu_add_cpu_aliases(struct list_head
*head, struct perf_pmu *pmu)
  break;
  }

- if (pmu->is_uncore) {
+ if (!is_pmu_core(name)) {
  /* check for uncore devices */
  if (pe->pmu == NULL)
  continue;

i have tried this diff on my x86 PC(haswell) and looks to be ok.
please confirm your testing on skylake.

gkulkarni@gkFc25>perf>> ./perf stat --per-thread -p 12663 -M CPI,IPC sleep 1

 Performance counter stats for process id '12663':

bash-12663   278,886  inst_retired.any:u
bash-12663   482,284  cycles:u
bash-12663   278,886  inst_retired.any:u
bash-12663   483,597
cpu_clk_unhalted.thread:u

   1.000923760 seconds time elapsed


On Tue, Dec 5, 2017 at 7:42 AM, Jin, Yao  wrote:
> Hi Kulkarni, Arnaldo,
>
> This patch has been merged in perf/core branch today.
>
> But I see a regression issue when I run the 'perf stat'.
>
> With bisect checking, I locate to this patch.
>
> commit ad8737a08973f5dca632bdd63cf2abc99670e540
> Author: Ganapatrao Kulkarni 
> Date:   Tue Oct 17 00:02:20 2017 +0530
>
> perf pmu: Use pmu->is_uncore to detect UNCORE devices
>
> For example (on Intel skylake desktop),
>
> 1. The correct output should be (without this patch):
>
> root@skl:/tmp# perf stat --per-thread -p 1754 -M CPI,IPC
> ^C
>  Performance counter stats for process id '1754':
>
>   vmstat-1754  1,882,798  inst_retired.any #
> 0.8 CPI
>   vmstat-1754  1,589,720  cycles
>   vmstat-1754  1,882,798  inst_retired.any #
> 1.2 IPC
>   vmstat-1754  1,589,720  cpu_clk_unhalted.thread
>
>2.647443167 seconds time elapsed
>
> 2. With this patch, the output will be:
>
> root@skl:/tmp# perf stat --per-thread -p 1754 -M CPI,IPC
> ^C
>  Performance counter stats for process id '1754':
>
>   vmstat-1754  1,945,589  inst_retired.any
>   vmstat-1754  inst_retired.any
>   vmstat-1754  1,609,892  cycles
>   vmstat-1754  1,945,589  inst_retired.any
>   vmstat-1754  inst_retired.any
>   vmstat-1754  1,609,892  cpu_clk_unhalted.thread
>   vmstat-1754  cpu_clk_unhalted.thread
>
>3.051274166 seconds time elapsed
>
> Could you please help to take a look?
>
> Thanks
> Jin Yao
>
>
> On 10/17/2017 2:32 AM, Ganapatrao Kulkarni wrote:
>>
>> PMU CORE devices are identified using sysfs filename cpu, however
>> on some platforms(like arm/arm64), PMU CORE sysfs name is not cpu.
>> Hence cpu cannot be used to differentiate PMU CORE/UNCORE devices.
>>
>> commit:
>>   66ec1191 ("perf pmu: Unbreak perf record for arm/arm64 with events with
>> explicit PMU")
>>
>> has introduced pmu->is_uncore, which is set to PMU UNCORE devices only.
>> Adding changes to use pmu->is_uncore to identify UNCORE devices.
>>
>> Acked-by: Will Deacon 
>> Tested-by: Shaokun Zhang 
>> Signed-off-by: Ganapatrao Kulkarni 
>> ---
>>   tools/perf/util/pmu.c | 11 +++
>>   1 file changed, 7 insertions(+), 4 deletions(-)
>>
>> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
>> index 8b17db5..9110718 100644
>> --- a/tools/perf/util/pmu.c
>> +++ b/tools/perf/util/pmu.c
>> @@ -603,7 +603,6 @@ static void pmu_add_cpu_aliases(struct list_head
>> *head, struct perf_pmu *pmu)
>>  */
>> i = 0;
>> while (1) {
>> -   const char *pname;
>> pe = &map->table[i++];
>> if (!pe->name) {
>> @@ -612,9 +611,13 @@ static 

[PATCH RESEND] arm64: fault: avoid send SIGBUS two times

2017-12-04 Thread Dongjiu Geng
If APEI handling the memory error is failed, the do_mem_abort()
and do_sea() will all deliver SIGBUS. In fact, sending one time
can be enough, so correct it.

Signed-off-by: Dongjiu Geng 
---
 arch/arm64/mm/fault.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index fcf2ede3..9e3f7ca 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -570,7 +570,6 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
 {
struct siginfo info;
const struct fault_info *inf;
-   int ret = 0;
 
inf = esr_to_fault_info(esr);
pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
@@ -585,7 +584,7 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
if (interrupts_enabled(regs))
nmi_enter();
 
-   ret = ghes_notify_sea();
+   ghes_notify_sea();
 
if (interrupts_enabled(regs))
nmi_exit();
@@ -600,7 +599,7 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
info.si_addr  = (void __user *)addr;
arm64_notify_die("", regs, &info, esr);
 
-   return ret;
+   return 0;
 }
 
 static const struct fault_info fault_info[] = {
-- 
2.10.1



Re: [PATCH 4.9 00/38] 4.9.67-stable review

2017-12-04 Thread Naresh Kamboju
On 4 December 2017 at 21:29, Greg Kroah-Hartman
 wrote:
> This is the start of the stable review cycle for the 4.9.67 release.
> There are 38 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Wed Dec  6 15:59:56 UTC 2017.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.67-rc1.gz
> or in the git tree and branch at:
>   git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> linux-4.9.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h

Results from Linaro’s test farm.
No regressions on arm64, arm and x86_64.

Summary


kernel: 4.9.67-rc1
git repo: 
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.9.y
git commit: 3efaa252aaafecdd666059be175f88ebd95ea236
git describe: v4.9.66-39-g3efaa252aaaf
Test details: 
https://qa-reports.linaro.org/lkft/linux-stable-rc-4.9-oe/build/v4.9.66-39-g3efaa252aaaf


No regressions (compared to build v4.9.66-39-ga89dba36bba8)

Boards, architectures and test suites:
-

hi6220-hikey - arm64
* boot - pass: 20,
* kselftest - pass: 34, skip: 20
* libhugetlbfs - pass: 90, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 64,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 60,
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 21, skip: 1
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 14,
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 982, skip: 121
* ltp-timers-tests - pass: 12,

juno-r2 - arm64
* boot - pass: 20,
* kselftest - pass: 34, skip: 19
* libhugetlbfs - pass: 90, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 64,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 60,
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 22,
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 10,
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 939, skip: 156
* ltp-timers-tests - pass: 12,

x15 - arm
* boot - pass: 20,
* kselftest - pass: 31, skip: 23
* libhugetlbfs - pass: 87, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 64,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 60,
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 20, skip: 2
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 13, skip: 1
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 1036, skip: 66
* ltp-timers-tests - pass: 12,

x86_64
* boot - pass: 20,
* kselftest - pass: 49, skip: 20
* libhugetlbfs - pass: 76, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 63,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 61, skip: 1
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 18,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 22,
* ltp-io-tests - pass: 2,
* ltp-ipc-tests - pass: 8,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 9, skip: 1
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 957, skip: 163
* ltp-timers-tests - pass: 11,

Documentation - https://collaborate.linaro.org/display/LKFT/Email+Reports

Tested-by: Naresh Kamboju 


Re: [PATCH v2] mmap.2: MAP_FIXED updated documentation

2017-12-04 Thread Michal Hocko
On Mon 04-12-17 18:52:27, John Hubbard wrote:
> On 12/04/2017 03:31 AM, Mike Rapoport wrote:
> > On Sun, Dec 03, 2017 at 06:14:11PM -0800, john.hubb...@gmail.com wrote:
> >> From: John Hubbard 
> >>
> [...]
> >> +.IP
> >> +Given the above limitations, one of the very few ways to use this option
> >> +safely is: mmap() a region, without specifying MAP_FIXED. Then, within 
> >> that
> >> +region, call mmap(MAP_FIXED) to suballocate regions. This avoids both the
> >> +portability problem (because the first mmap call lets the kernel pick the
> >> +address), and the address space corruption problem (because the region 
> >> being
> >> +overwritten is already owned by the calling thread).
> > 
> > Maybe "address space corruption problem caused by implicit calls to mmap"?
> > The region allocated with the first mmap is not exactly owned by the
> > thread and a multi-thread application can still corrupt its memory if
> > different threads use mmap(MAP_FIXED) for overlapping regions.
> > 
> > My 2 cents.
> > 
> 
> Hi Mike,
> 
> Yes, thanks for picking through this, and I agree that the above is 
> misleading.
> It should definitely not use the word "owned" at all. Re-doing the whole 
> paragraph in order to make it all fit together nicely, I get this:
> 
> "Given the above limitations, one of the very few ways to use this option
> safely is: mmap() an enclosing region, without specifying MAP_FIXED.
> Then, within that region, call mmap(MAP_FIXED) to suballocate regions
> within the enclosing region. This avoids both the portability problem 
> (because the first mmap call lets the kernel pick the address), and the 
> address space corruption problem (because implicit calls to mmap will 
> not affect the already-mapped enclosing region)."
> 
> ...how's that sound to you? I'll post a v3 soon with this.

It sounds to me you are trying to tell way to much while actually being
a bit misleading. Even sub-range MAP_FIXED is not multi-thread safe.

Really the more corner cases you will try to cover the worse the end
result will end up. I would just try to be simple here and mention the
address space corruption issues you've had earlier and be done with it.
Maybe add a note that some architectures might need a special alignement
and fail if it is not the case but nothing really specific.
-- 
Michal Hocko
SUSE Labs


Re: [PATCH] skb_array: fix NULL-pointer exception

2017-12-04 Thread Jason Wang



On 2017年12月05日 12:40, Michael S. Tsirkin wrote:

On Tue, Dec 05, 2017 at 11:11:14AM +0800, Jason Wang wrote:


On 2017年12月04日 22:24, George Cherian wrote:

While running a multiple VM testscase with each VM running iperf
traffic between others the following kernel NULL pointer exception
was seen.

Race appears when the tun driver instance of one VM calls skb_array_produce
(from tun_net_xmit) and the the destined VM's skb_array_consume
(from tun_ring_recv), which could run concurrently on another core. Due to
which the sock_wfree gets called again

from the tun_ring_recv context.

OK, so is the implication that there are two concurrent callers for 
tun_ring_recv
on the same device?


I guess not since VM is used (unless there's some misconfiguration).




The fix is to add write/read barrier calls to be sure that we get proper
values in the tun_ring_recv context.

Crash log
[35321.580227] Unable to handle kernel NULL pointer dereference at virtual 
address 0060
[35321.596720] pgd = 809ee552f000
[35321.603723] [0060] *pgd=009f514ac003, *pud=009f54f7c003, 
*pmd=
[35321.620588] Internal error: Oops: 9606 1 SMP
[35321.630461] Modules linked in: xt_CHECKSUM iptable_mangle ipt_MASQUERADE 
nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 
nf_defrag_ipv4 xt_4
[35321.728501] CPU: 114 PID: 5560 Comm: qemu-system-aar Not tainted 
4.11.8-4k-vhe-lse+ #3
[35321.744510] Hardware name: Cavium Inc. Unknown/Unknown, BIOS 1.0 07/24/2017
[35321.758602] task: 80bed7fca880 task.stack: 80beb5128000
[35321.770600] PC is at sock_wfree+0x24/0x80
[35321.778746] LR is at skb_release_head_state+0x68/0xf8
[35321.788979] pc : [] lr : [] pstate: 
40400149
[35321.803930] sp : 80beb512bc30
[35321.810648] x29: 80beb512bc30 x28: 80bed7fca880
[35321.821400] x27: 004e x26: 
[35321.832156] x25: 000c x24: 
[35321.842947] x23: 809ece3e4900 x22: 80beb512be00
[35321.853729] x21: 09138000 x20: 0144
[35321.864507] x19:  x18: 0014
[35321.875276] x17: 9d9689a0 x16: 0828b3f8
[35321.886048] x15: 504d7b00 x14: e90ab50c48680a08
[35321.896824] x13: 010117773f52 x12: 1080d422c00e5db6
[35321.907595] x11: 68c322bd3930cf7a x10: a8c0d07aa8c0ad16
[35321.918352] x9 : 1da4ed90 x8 : b50c48680a080101
[35321.929099] x7 : 17770c521080 x6 : 1d6c13f2
[35321.939865] x5 : 1d6c13f2 x4 : 000e
[35321.950619] x3 : 00085ff97d82 x2 : 
[35321.961376] x1 : 08a772d8 x0 : 0500
[35321.975193] Process qemu-system-aar (pid: 5560, stack limit = 
0x80beb5128000)
[35321.990347] Stack: (0x80beb512bc30 to 0x80beb512c000)
[35322.001982] bc20: 80beb512bc50 08a79238
[35322.017817] bc40: 809e8fd7be00 004e 80beb512bc70 
08a79488
[35322.033651] bc60: 809e8fd7be00 0881307c 80beb512bc90 
08a79678
[35322.049489] bc80: 809e8fd7be00 80beb512be00 80beb512bcb0 
08812f24
[35322.065321] bca0: 809e8fd7be00 004e 80beb512bd50 
088133f0
[35322.081165] bcc0: 809ece3e4900 00011000 80beb512bdd8 
80beb512be00
[35322.097001] bce0: 1d6c13a4 0015 0124 
003f
[35322.112866] bd00: 08bc2000 0847b5ac 0002 
80be0008
[35322.128701] bd20: 00220001 80bed7fc0010 08100c38 

[35322.144539] bd40:  00040b08 80beb512bd80 
08288f80
[35322.160395] bd60: 09138000 809ee7cd3500 00011000 
80beb512beb0
[35322.176255] bd80: 80beb512be30 0828a224 00011000 
809ee7cd3500
[35322.192109] bda0: 1d6c13a4 80beb512beb0 00011000 

[35322.207974] bdc0:  1d6c13a4 00011000 
809ee7cd3500
[35322.223822] bde0: 004e   

[35322.239661] be00: 80be 004e 00010fb2 
80beb512bdc8
[35322.255519] be20: 0001 00040b08 80beb512be70 
0828b464
[35322.271392] be40: 09138000 809ee7cd3501 809ee7cd3500 
1d6c13a4
[35322.287255] be60: 00011000 0015  
080833f0
[35322.303090] be80:  80bef0071000  
9d9689cc
[35322.318951] bea0: 8000 80bef0071000 004e 
00040b08
[35322.334771] bec0: 000e 1d6c13a4 00011000 
9cc89108
[35322.350640] bee0: 0002 9cc89000 9cc896f0 

[35322.366500] bf00: 003f 1da4ed90 a8c0d07aa8c0ad16 
68c322bd3930cf7a
[35322.382358] bf20: 1080d422c00e5db6 010117773f52 e90ab50c48680a08 
000

Re: [PATCH v2] mmap.2: MAP_FIXED updated documentation

2017-12-04 Thread Michal Hocko
On Mon 04-12-17 18:14:18, John Hubbard wrote:
> On 12/04/2017 02:55 AM, Cyril Hrubis wrote:
> > Hi!
> > I know that we are not touching the rest of the existing description for
> > MAP_FIXED however the second sentence in the manual page says that "addr
> > must be a multiple of the page size." Which however is misleading as
> > this is not enough on some architectures. Code in the wild seems to
> > (mis)use SHMLBA for aligment purposes but I'm not sure that we should
> > advise something like that in the manpages.
> > 
> > So what about something as:
> > 
> > "addr must be suitably aligned, for most architectures multiple of page
> > size is sufficient, however some may impose additional restrictions for
> > page mapping addresses."
> > 
> 
> Hi Cyril,
> 
> Right, so I've been looking into this today, and I think we can go a bit
> further than that, even. The kernel, as far back as the *original* git
> commit in 2005, implements mmap on ARM by requiring that the address is
> aligned to SHMLBA:
> 
> arch/arm/mm/mmap.c:50:
> 
>   if (flags & MAP_FIXED) {
>   if (aliasing && flags & MAP_SHARED &&
>   (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
>   return -EINVAL;
>   return addr;
>   }
> 
> So, given that this has been the implementation for the last 12+ years (and
> probably the whole time, in fact), I think we can be bold enough to use this
> wording for the second sentence of MAP_FIXED:
> 
> "addr must be a multiple of SHMLBA (), which in turn is either
> the system page size (on many architectures) or a multiple of the system
> page size (on some architectures)."
> 
> What do you think?

I am not sure this is a good idea. This is pulling way too many
implementation details into the man page IMHO. Note that your wording is
even incorrect because this applies only to shared mappings and on some
architectures it even requires special memory regions. We do not want
all that in the man page...

-- 
Michal Hocko
SUSE Labs


Re: [PATCH 4.14 00/95] 4.14.4-stable review

2017-12-04 Thread Naresh Kamboju
On 4 December 2017 at 21:29, Greg Kroah-Hartman
 wrote:
> This is the start of the stable review cycle for the 4.14.4 release.
> There are 95 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Wed Dec  6 16:00:27 UTC 2017.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.4-rc1.gz
> or in the git tree and branch at:
>   git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> linux-4.14.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>

Results from Linaro’s test farm.
No regressions on arm64, arm and x86_64.

Summary


kernel: 4.14.4-rc1
git repo: 
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.14.y
git commit: 95aa1a118d82e935ec7065345cbaff945d4100bf
git describe: v4.14.3-96-g95aa1a118d82
Test details: 
https://qa-reports.linaro.org/lkft/linux-stable-rc-4.14-oe/build/v4.14.3-96-g95aa1a118d82


No regressions (compared to build v4.14.3-96-gc2bf04f2ec62)

Boards, architectures and test suites:
-

hi6220-hikey - arm64
* boot - pass: 20,
* kselftest - pass: 39, skip: 14
* libhugetlbfs - pass: 90, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 64,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 60,
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 21, skip: 1
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 14,
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 982, skip: 121
* ltp-timers-tests - pass: 12,

juno-r2 - arm64
* boot - pass: 20,
* kselftest - pass: 38, skip: 14
* libhugetlbfs - pass: 90, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 64,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 60,
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 22,
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 10,
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 939, skip: 156
* ltp-timers-tests - pass: 12,

x15 - arm
* boot - pass: 20,
* kselftest - pass: 35, skip: 18
* libhugetlbfs - pass: 87, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 64,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 60,
* ltp-fs_bind-tests - pass: 2,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 20, skip: 2
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 13, skip: 1
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 1036, skip: 66
* ltp-timers-tests - pass: 12,

x86_64
* boot - pass: 20,
* kselftest - pass: 54, skip: 13
* libhugetlbfs - pass: 76, skip: 1
* ltp-cap_bounds-tests - pass: 2,
* ltp-containers-tests - pass: 64,
* ltp-fcntl-locktests-tests - pass: 2,
* ltp-filecaps-tests - pass: 2,
* ltp-fs-tests - pass: 61, skip: 1
* ltp-fs_bind-tests - pass: 1,
* ltp-fs_perms_simple-tests - pass: 19,
* ltp-fsx-tests - pass: 2,
* ltp-hugetlb-tests - pass: 22,
* ltp-io-tests - pass: 3,
* ltp-ipc-tests - pass: 9,
* ltp-math-tests - pass: 11,
* ltp-nptl-tests - pass: 2,
* ltp-pty-tests - pass: 4,
* ltp-sched-tests - pass: 9,
* ltp-securebits-tests - pass: 4,
* ltp-syscalls-tests - pass: 957, skip: 163
* ltp-timers-tests - pass: 12,

Documentation - https://collaborate.linaro.org/display/LKFT/Email+Reports

Tested-by: Naresh Kamboju 


[PATCH] arm64: avoid send SIGBUS two times

2017-12-04 Thread Dongjiu Geng
If APEI handling the memory error is failed,
the SIGBUS will be sent twice. In fact, send
one time can be enough, so correct it.

Signed-off-by: Dongjiu Geng 
---
 arch/arm64/mm/fault.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index fcf2ede3..9e3f7ca 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -570,7 +570,6 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
 {
struct siginfo info;
const struct fault_info *inf;
-   int ret = 0;
 
inf = esr_to_fault_info(esr);
pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
@@ -585,7 +584,7 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
if (interrupts_enabled(regs))
nmi_enter();
 
-   ret = ghes_notify_sea();
+   ghes_notify_sea();
 
if (interrupts_enabled(regs))
nmi_exit();
@@ -600,7 +599,7 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
info.si_addr  = (void __user *)addr;
arm64_notify_die("", regs, &info, esr);
 
-   return ret;
+   return 0;
 }
 
 static const struct fault_info fault_info[] = {
-- 
2.10.1



Re: [PATCH] thermal/drivers/hisi: disable multi alarm support for hi3660 SoC

2017-12-04 Thread Daniel Lezcano
On 05/12/2017 03:02, Eduardo Valentin wrote:
> Hello,
> 
> On Thu, Oct 19, 2017 at 09:31:24AM +0800, Wangtao (Kevin, Kirin) wrote:
>>
>>
>> 在 2017/10/18 23:54, Daniel Lezcano 写道:
>>> On 18/10/2017 11:15, Tao Wang wrote:
 From: Kevin Wangtao 

 multi alarm interrupt forced a re-trigger of power_allocator_throttle
 which changes the PID's actual sampling rate, this isn't optimal for
 IPA, it is best to disable multi alarm support now and sort out this
 issue later.

 Signed-off-by: Kevin Wangtao 
>>>
>>> Did you test the series with this change?
>> Yes
> 
> Is this patch still valid with the latest linus master?

No, it was folded in the next iteration.

All patches for hisilicon are up-to-date.

Thanks.

 -- Daniel


-- 
  Linaro.org │ Open source software for ARM SoCs

Follow Linaro:   Facebook |
 Twitter |
 Blog



Re: [PATCH] SCSI: delay run queue if device is blocked in scsi_dev_queue_ready()

2017-12-04 Thread Ming Lei
On Tue, Dec 05, 2017 at 01:16:24PM +0800, Ming Lei wrote:
> On Mon, Dec 04, 2017 at 11:48:07PM +, Holger Hoffstätte wrote:
> > On Tue, 05 Dec 2017 06:45:08 +0800, Ming Lei wrote:
> > 
> > > On Mon, Dec 04, 2017 at 03:09:20PM +, Bart Van Assche wrote:
> > >> On Sun, 2017-12-03 at 00:31 +0800, Ming Lei wrote:
> > >> > Fixes: 0df21c86bdbf ("scsi: implement .get_budget and .put_budget for 
> > >> > blk-mq")
> > >> 
> > >> It might be safer to revert commit 0df21c86bdbf instead of trying to fix 
> > >> all
> > >> issues introduced by that commit for kernel version v4.15 ...
> > > 
> > > What are all issues in v4.15-rc? Up to now, it is the only issue reported,
> > > and can be fixed by this simple patch, which one can be thought as cleanup
> > > too.
> > 
> > Even with this patch I've encountered at least one hang that
> > seemed related. I'm using most of block/scsi-4.15 on top of 4.14 and
> > the hang in question was on a rotating disk. It could be solved by 
> > activating
> > a different scheduler on the hanging device; all hanging sync/df processes 
> > got
> > unstuck and all was fine again, which leads me to believe that there is at 
> > least
> > one more rare condition where delaying requests (as done in the budget 
> > patch)
> > leads to a hang.
> > 
> > This happened with mq-deadline which I was testing specifically to avoid
> > any BFQ-related side effects.
> 
> OK, this looks a new report.
> 
> Without any log, we can't make any progress, and even we can't guess
> what the issue is related with.
> 
> Could you post your dmesg log(include the hang process stack trace)? And
> dump the debugfs log by the following script when this hang happens?
> 
>   http://people.redhat.com/minlei/tests/tools/dump-blk-info
> 
> BTW, you just need to pass the disk name to the script, such as: /dev/sda.

Thinking of the issue further, this patch only covers case of
scsi_set_blocked(), but don't consider the case in which .get_budget()
is called inside blk_mq_dispatch_rq_list() for request coming from
hctx->dispatch_list.

If .get_budget() is called in both blk_mq_do_dispatch_sched() and
blk_mq_do_dispatch_ctx(), we don't need to run queue if the queue
is idle. But if it is called from blk_mq_dispatch_rq_list() for request
coming from hctx->dispatch_list, we have to run queue if queue is
idle, as before.

So please ignore this patch, and will submit V2 for cover both cases.

Thanks,
Ming


Re: [patch V4 01/11] Documentation: Add license-rules.rst to describe how to properly identify file licenses

2017-12-04 Thread Heiko Carstens
On Mon, Dec 04, 2017 at 10:19:28PM +0100, Thomas Gleixner wrote:
> +3. Syntax:
> +
> +   A  is either an SPDX short form license
> +   identifier found on the SPDX License List, or when multiple licenses
> +   apply, an expression consisting of keywords "AND", "OR", and "WITH"
> +   separating SPDX short form license identifiers surrounded by "(", ")".

Here it is stated that SPDX identifiers using the keyword WITH must be
surrounded by braces.

> +  // SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note)
> +  // SPDX-License-Identifier: (GPL-2.0+ WITH Linux-syscall-note)

Just like this example.

> +   File format examples::
> +
> +  SPDX-Exception-Identifier: Linux-syscall-note
> +  SPDX-URL: https://spdx.org/licenses/Linux-syscall-note.html
> +  SPDX-Licenses: GPL-2.0, GPL-2.0+, GPL-1.0+, LGPL-2.0, LGPL-2.0+, 
> LGPL-2.1, LGPL-2.1+
> +  Usage-Guidance:
> +This exception is used together with one of the above SPDX-Licenses
> + to mark user-space API (uapi) header files so they can be included
> + into non GPL compliant user-space application code.
> +To use this exception add it with the keyword WITH to one of the
> + identifiers in the SPDX-Licenses tag:
> +   SPDX-License-Identifier:  WITH Linux-syscall-note

But here it comes without braces.

> +  Exception-Text:
> +Full exception text
> +
> +   ::
> +
> +  SPDX-Exception-Identifier: GCC-exception-2.0
> +  SPDX-URL: https://spdx.org/licenses/GCC-exception-2.0.html
> +  SPDX-Licenses: GPL-2.0, GPL-2.0+
> +  Usage-Guidance:
> +The "GCC Runtime Library exception 2.0" is used together with one
> + of the above SPDX-Licenses for code imported from the GCC runtime
> + library.
> +To use this exception add it with the keyword WITH to one of the
> + identifiers in the SPDX-Licenses tag:
> +   SPDX-License-Identifier:  WITH GCC-exception-2.0

Here as well.

The whole kernel now got SPDX-License-Identifiers that look like this:

SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note

So this looks inconsistent to me, or did I miss something?



Re: [PATCH V2] thermal/drivers/hisi: Switch to interrupt mode

2017-12-04 Thread Daniel Lezcano
On 05/12/2017 03:00, Eduardo Valentin wrote:
> Hello,
> 
> On Thu, Sep 28, 2017 at 09:32:20AM +0200, Daniel Lezcano wrote:
>> On Thu, Sep 28, 2017 at 02:57:52PM +0800, Leo Yan wrote:
>>> Hi Daniel,
>>>
>>> On Thu, Sep 28, 2017 at 07:13:44AM +0200, Daniel Lezcano wrote:
 At this moment, we have both the interrupt setup and the polling enabled. 
 The
 interrupt does nothing more than forcing an update while the temperature is
 polled every second.

 We can do much better than that, threshold is set to 65C in the DT and the
 passive cooling device enters in the dance when 75C is reached. We need to
 sample the temperature at 65C in order to let the IPA gather enough values 
 for
 the PID computation. If the SoC is running at a temperature below 65C, we 
 will
 be constantly polling for nothing.

 This patch disables the sensor when the temperature is below 65C and 
 enables it
 when passing the threshold. It results the thermal sensor driver will have 
 no
 activity most of the time.

 Cc: Keerthy 
 Cc: Leo Yang 
>>>
>>> s/Yang/Yan :) Have tested this patch on Hikey at my side:
>>
>> Oops sorry :)
>>
>>> Reviewed-by: Leo Yan 
>>> Tested-by: Leo Yan 
>>
> 
> Is this still needed after the latest rework done?

No longer needed.



-- 
  Linaro.org │ Open source software for ARM SoCs

Follow Linaro:   Facebook |
 Twitter |
 Blog



[PATCH 1/2] ARM: dts: keystone-k2g: Add UART 1 and 2 instances

2017-12-04 Thread Vignesh R
From: Franklin S Cooper Jr 

Add DT nodes for two other UART instances of 66AK2G SoC.

Also add power domain and clock domain nodes to UART 0

Signed-off-by: Franklin S Cooper Jr 
Signed-off-by: Vignesh R 
---
 arch/arm/boot/dts/keystone-k2g.dtsi | 29 -
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi 
b/arch/arm/boot/dts/keystone-k2g.dtsi
index ef82c0a6e607..3c48a9f5c882 100644
--- a/arch/arm/boot/dts/keystone-k2g.dtsi
+++ b/arch/arm/boot/dts/keystone-k2g.dtsi
@@ -28,6 +28,8 @@
 
aliases {
serial0 = &uart0;
+   serial1 = &uart1;
+   serial2 = &uart2;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
@@ -114,7 +116,32 @@
reg-io-width = <4>;
reg = <0x02530c00 0x100>;
interrupts = ;
-   clock-frequency = <2>;
+   clocks = <&k2g_clks 0x2c 0>;
+   power-domains = <&k2g_pds 0x2c>;
+   status = "disabled";
+   };
+
+   uart1: serial@02531000 {
+   compatible = "ti,da830-uart", "ns16550a";
+   current-speed = <115200>;
+   reg-shift = <2>;
+   reg-io-width = <4>;
+   reg = <0x02531000 0x100>;
+   interrupts = ;
+   clocks = <&k2g_clks 0x2d 0>;
+   power-domains = <&k2g_pds 0x2d>;
+   status = "disabled";
+   };
+
+   uart2: serial@02531400 {
+   compatible = "ti,da830-uart", "ns16550a";
+   current-speed = <115200>;
+   reg-shift = <2>;
+   reg-io-width = <4>;
+   reg = <0x02531400 0x100>;
+   interrupts = ;
+   clocks = <&k2g_clks 0x2e 0>;
+   power-domains = <&k2g_pds 0x2e>;
status = "disabled";
};
 
-- 
2.15.0



Re: [PATCH] thermal/drivers/hisi: Remove confusing error message

2017-12-04 Thread Daniel Lezcano
On 05/12/2017 02:52, Eduardo Valentin wrote:
> Hello,
> 
> Catching up on old patches.
> On Fri, Jul 07, 2017 at 05:03:52PM +0200, Daniel Lezcano wrote:
>> The sensor id is unknown at init time and we use all id in the authorized
>> MAX_SENSORS interval to register the sensor. On this SoC there is one
>> thermal-zone with one sensor on it. No need to spit on the console everytime 
>> we
>> failed to register thermal sensors, information which is deliberaly known as 
>> it
>> is part of the discovery process.
>>
>>  hisi_thermal f7030700.tsensor: failed to register sensor id 0: -19
>>  hisi_thermal f7030700.tsensor: failed to register thermal sensor: -19
>>  hisi_thermal f7030700.tsensor: failed to register sensor id 1: -19
>>  hisi_thermal f7030700.tsensor: failed to register thermal sensor: -19
>>  hisi_thermal f7030700.tsensor: failed to register sensor id 3: -19
>>  hisi_thermal f7030700.tsensor: failed to register thermal sensor: -19
>>
>> Remove the error messages
> 
> Is this still needed? I am assuming no.

Right, no longer needed.

  -- Daniel

-- 
  Linaro.org │ Open source software for ARM SoCs

Follow Linaro:   Facebook |
 Twitter |
 Blog



[PATCH 0/2] 66AK2G: Add DT entry for UART1 and UART2

2017-12-04 Thread Vignesh R
This series adds DT entry for the remaining two UART instances on 66AK2G
SoC.

Based on linux-next.

Franklin S Cooper Jr (2):
  ARM: dts: keystone-k2g: Add UART 1 and 2 instances
  ARM: dts: keystone-k2g-evm: Enable UART 2

 arch/arm/boot/dts/keystone-k2g-evm.dts | 13 +
 arch/arm/boot/dts/keystone-k2g.dtsi| 29 -
 2 files changed, 41 insertions(+), 1 deletion(-)

-- 
2.15.0



[PATCH 2/2] ARM: dts: keystone-k2g-evm: Enable UART 2

2017-12-04 Thread Vignesh R
From: Franklin S Cooper Jr 

66AK2G GP EVM has a Baseboard Management Controller (BMC) on board.
This controller handles things like setting the SoCs boot mode along
with controlling the on board character LCD display module.

Enable UART2 which communicates with the BMC. This enables userspace
applications to display something on the onboard LCD controlled by the
BMC.

Signed-off-by: Franklin S Cooper Jr 
Signed-off-by: Vignesh R 
---
 arch/arm/boot/dts/keystone-k2g-evm.dts | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/keystone-k2g-evm.dts 
b/arch/arm/boot/dts/keystone-k2g-evm.dts
index 8d100217e38f..9737730ddc21 100644
--- a/arch/arm/boot/dts/keystone-k2g-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2g-evm.dts
@@ -115,6 +115,13 @@
K2G_CORE_IOPAD(0x121c) (BUFFER_CLASS_B | PULL_DISABLE | 
MUX_MODE0) /* qspi_csn0.qspi_csn0 */
>;
};
+
+   uart2_pins: pinmux_uart2_pins {
+   pinctrl-single,pins = <
+   K2G_CORE_IOPAD(0x11ec) (BUFFER_CLASS_B | PULL_DISABLE | 
MUX_MODE0)  /* uart2_rxd.uart2_rxd */
+   K2G_CORE_IOPAD(0x11f0) (BUFFER_CLASS_B | PIN_PULLDOWN | 
MUX_MODE0)  /* uart2_txd.uart2_txd */
+   >;
+   };
 };
 
 &uart0 {
@@ -263,3 +270,9 @@
};
};
 };
+
+&uart2 {
+   pinctrl-names = "default";
+   pinctrl-0 = <&uart2_pins>;
+   status = "okay";
+};
-- 
2.15.0



Re: [PATCH v4 3/5] remoteproc: Pass type of shutdown to subdev remove

2017-12-04 Thread Bjorn Andersson
On Fri 01 Dec 06:50 PST 2017, Arnaud Pouliquen wrote:

> hello Bjorn,
> 
> Sorry for these late remarks/questions
> 

No worries, I'm happy to see you reading the patch!

> 
> On 11/30/2017 02:16 AM, Bjorn Andersson wrote:
[..]
> > diff --git a/drivers/remoteproc/qcom_common.c 
> > b/drivers/remoteproc/qcom_common.c
[..]
> > @@ -785,17 +785,17 @@ static int rproc_probe_subdevices(struct rproc *rproc)
> >  
> >  unroll_registration:
> > list_for_each_entry_continue_reverse(subdev, &rproc->subdevs, node)
> > -   subdev->remove(subdev);
> > +   subdev->remove(subdev, false);
> Why do you need to do a non graceful remove in this case? This could
> lead to side effect like memory leakage...
> 

Regardless of this being true or false resources should always be
reclaimed.

The reason for introducing this is that the modem in the Qualcomm
platforms implements persistent storage and it's preferred to tell it to
flush the latest data to the storage server (on the Linux side) before
pulling the plug. But in the case of a firmware crash this mechanism
will not be operational and there's no point in attempting this
"graceful shutdown".

[..]
> > diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> > index 44e630eb3d94..20a9467744ea 100644
> > --- a/include/linux/remoteproc.h
> > +++ b/include/linux/remoteproc.h
> > @@ -456,7 +456,7 @@ struct rproc_subdev {
> > struct list_head node;
> >  
> > int (*probe)(struct rproc_subdev *subdev);
> > -   void (*remove)(struct rproc_subdev *subdev);
> > +   void (*remove)(struct rproc_subdev *subdev, bool graceful);
> What about adding a new ops instead of a parameter, like a recovery
> callback?
> 

I think that for symmetry purposes it should be probe/remove in both
code paths. A possible alternative to the proposal would be to introduce
an operation "request_shutdown()" the would be called in the proposed
graceful code path.


However, in the Qualcomm SMD and GLINK (conceptually equivalent to
virtio-rpmsg) it is possible to open and close communication channels
and it's conceivable to see that the graceful case would close all
channels cleanly while the non-graceful case would just remove the rpmsg
devices (and leave the channel states/memory as is).

In this case a "request_shutdown()" would complicate things, compared to
the boolean.

Regards,
Bjorn


[PATCH v2 2/2] regulator: sc2731: Add regulator driver to support Spreadtrum SC2731 PMIC

2017-12-04 Thread Erick Chen
Add regulator driver for Spreadtrum SC2731 device.
It has 17 general purpose LDOs, BUCKs generator and
digital output to control regulators.

Signed-off-by: Erick Chen 
Reviewed-by: Baolin Wang 
---
Changes since v1:
- Remove of_device_id table.
- Change subsys_init() to module_init().
- Change the file's license format.
---
 drivers/regulator/Kconfig|7 +
 drivers/regulator/Makefile   |1 +
 drivers/regulator/sc2731-regulator.c |  256 ++
 3 files changed, 264 insertions(+)
 create mode 100644 drivers/regulator/sc2731-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 96cd55f..b27417c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -744,6 +744,13 @@ config REGULATOR_S5M8767
 via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and
 supports DVS mode with 8bits of output voltage control.
 
+config REGULATOR_SC2731
+   tristate "Spreadtrum SC2731 power regulator driver"
+   depends on MFD_SC27XX_PMIC || COMPILE_TEST
+   help
+ This driver provides support for the voltage regulators on the
+ SC2731 PMIC.
+
 config REGULATOR_SKY81452
tristate "Skyworks Solutions SKY81452 voltage regulator"
depends on MFD_SKY81452
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 80ffc57..19fea09 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_REGULATOR_RT5033)+= rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
+obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
 obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
 obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
diff --git a/drivers/regulator/sc2731-regulator.c 
b/drivers/regulator/sc2731-regulator.c
new file mode 100644
index 000..794fcd5
--- /dev/null
+++ b/drivers/regulator/sc2731-regulator.c
@@ -0,0 +1,256 @@
+ //SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 Spreadtrum Communications Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * SC2731 regulator lock register
+ */
+#define SC2731_PWR_WR_PROT_VALUE   0xf0c
+#define SC2731_WR_UNLOCK   0x6e7f
+
+/*
+ * SC2731 enable register
+ */
+#define SC2731_POWER_PD_SW 0xc28
+#define SC2731_LDO_CAMA0_PD0xcfc
+#define SC2731_LDO_CAMA1_PD0xd04
+#define SC2731_LDO_CAMMOT_PD   0xd0c
+#define SC2731_LDO_VLDO_PD 0xd6c
+#define SC2731_LDO_EMMCCORE_PD 0xd2c
+#define SC2731_LDO_SDCORE_PD   0xd74
+#define SC2731_LDO_SDIO_PD 0xd70
+#define SC2731_LDO_WIFIPA_PD   0xd4c
+#define SC2731_LDO_USB33_PD0xd5c
+#define SC2731_LDO_CAMD0_PD0xd7c
+#define SC2731_LDO_CAMD1_PD0xd84
+#define SC2731_LDO_CON_PD  0xd8c
+#define SC2731_LDO_CAMIO_PD0xd94
+#define SC2731_LDO_SRAM_PD 0xd78
+
+/*
+ * SC2731 enable mask
+ */
+#define SC2731_DCDC_CPU0_PD_MASK   BIT(4)
+#define SC2731_DCDC_CPU1_PD_MASK   BIT(3)
+#define SC2731_DCDC_RF_PD_MASK BIT(11)
+#define SC2731_LDO_CAMA0_PD_MASK   BIT(0)
+#define SC2731_LDO_CAMA1_PD_MASK   BIT(0)
+#define SC2731_LDO_CAMMOT_PD_MASK  BIT(0)
+#define SC2731_LDO_VLDO_PD_MASKBIT(0)
+#define SC2731_LDO_EMMCCORE_PD_MASKBIT(0)
+#define SC2731_LDO_SDCORE_PD_MASK  BIT(0)
+#define SC2731_LDO_SDIO_PD_MASKBIT(0)
+#define SC2731_LDO_WIFIPA_PD_MASK  BIT(0)
+#define SC2731_LDO_USB33_PD_MASK   BIT(0)
+#define SC2731_LDO_CAMD0_PD_MASK   BIT(0)
+#define SC2731_LDO_CAMD1_PD_MASK   BIT(0)
+#define SC2731_LDO_CON_PD_MASK BIT(0)
+#define SC2731_LDO_CAMIO_PD_MASK   BIT(0)
+#define SC2731_LDO_SRAM_PD_MASKBIT(0)
+
+/*
+ * SC2731 vsel register
+ */
+#define SC2731_DCDC_CPU0_VOL   0xc54
+#define SC2731_DCDC_CPU1_VOL   0xc64
+#define SC2731_DCDC_RF_VOL 0xcb8
+#define SC2731_LDO_CAMA0_VOL   0xd00
+#define SC2731_LDO_CAMA1_VOL   0xd08
+#define SC2731_LDO_CAMMOT_VOL  0xd10
+#define SC2731_LDO_VLDO_VOL0xd28
+#define SC2731_LDO_EMMCCORE_VOL0xd30
+#define SC2731_LDO_SDCORE_VOL  0xd38
+#define SC2731_LDO_SDIO_VOL0xd40
+#define SC2731_LDO_WIFIPA_VOL  0xd50
+#define SC2731_LDO_USB33_VOL   0xd60
+#define SC2731_LDO_CAMD0_VOL   0xd80
+#define SC2731_LDO_CAMD1_VOL   0xd88
+#define SC2731_LDO_CON_VOL 0xd90
+#define SC2731_LDO_CAMIO_VOL   0xd98
+#define SC2731_LDO_SRAM_VOL0xdB0
+
+/*
+ * SC2731 vsel register mask
+ */
+#define SC2731_DCDC_CPU0_VOL_MASK  GENMASK(8, 0)
+#define SC2731_DCDC_CPU1_VOL_MASK  GENMASK(8, 0)
+#define

[PATCH v2 1/2] dt-bindings: regulator: Add Spreadtrum SC2731 regulator documentation

2017-12-04 Thread Erick Chen
This patch adds support for the Spreadtrum SC2731
voltage regulator device.

Signed-off-by: Erick Chen 
---
Changes since v1:
- Remove reg property.
- Remove regulators sub-node.
---
 .../bindings/regulator/sprd,sc2731-regulator.txt   |   43 
 1 file changed, 43 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/sprd,sc2731-regulator.txt

diff --git 
a/Documentation/devicetree/bindings/regulator/sprd,sc2731-regulator.txt 
b/Documentation/devicetree/bindings/regulator/sprd,sc2731-regulator.txt
new file mode 100644
index 000..63dc078
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/sprd,sc2731-regulator.txt
@@ -0,0 +1,43 @@
+Spreadtrum SC2731 Voltage regulators
+
+The SC2731 integrates low-voltage and low quiescent current DCDC/LDO.
+14 LDO and 3 DCDCs are designed for external use. All DCDCs/LDOs have
+their own bypass (power-down) control signals. External tantalum or MLCC
+ceramic capacitors are recommended to use with these LDOs.
+
+Required properties:
+ - compatible: should be "sprd,sc27xx-regulator".
+
+List of regulators provided by this controller. It is named according to
+its regulator type, BUCK_ and LDO_. The definition for each
+of these nodes is defined using the standard binding for regulators at
+Documentation/devicetree/bindings/regulator/regulator.txt.
+
+The valid names for regulators are:
+BUCK:
+   BUCK_CPU0, BUCK_CPU1, BUCK_RF
+LDO:
+   LDO_CAMA0, LDO_CAMA1, LDO_CAMMOT, LDO_VLDO, LDO_EMMCCORE, LDO_SDCORE,
+   LDO_SDIO, LDO_WIFIPA, LDO_USB33, LDO_CAMD0, LDO_CAMD1, LDO_CON,
+   LDO_CAMIO, LDO_SRAM
+
+Example:
+   regulators {
+   compatible = "sprd,sc27xx-regulator";
+
+   vddarm0: BUCK_CPU0 {
+   regulator-name = "vddarm0";
+   regulator-min-microvolt = <40>;
+   regulator-max-microvolt = <1996875>;
+   regulator-ramp-delay = <25000>;
+   regulator-always-on;
+   };
+
+   vddcama0: LDO_CAMA0 {
+   regulator-name = "vddcama0";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <375>;
+   regulator-enable-ramp-delay = <100>;
+   };
+   ...
+   };
-- 
1.7.9.5



RE: [Bug fix] octeon-i2c driver updates

2017-12-04 Thread Zhang, Sean C. (NSB - CN/Hangzhou)
Hi Jan,

Thanks for your comments, I get your point for the second point (retry of START 
after recovery).

Hi David,
For the issue as the first one, would you give your further comments? Thanks in 
advance.

I have an environment with CN6780 (TWSI core has property: compatible = 
"cavium,octeon-3860-twsi"),
And encounter below problem:
During i2c-octeon driver probing, this TWSI core original status is 0x20 (this 
may induced by uboot),
And octeon_i2c_init_lowlevel() function in octeon_i2c_probe() is not enough to 
recover the I2C bus,
If go without full recovery of octeon_i2c_recovery(), the following 
octeon_i2c_hlc_write(), 
octeon_i2c_hlc_read(), octeon_i2c_hlc_comp_read() and 
octeon_i2c_hlc_comp_write() will goes error,
because these functions has no bus recovery step.
While after replace octeon_i2c_init_lowlevel() with octeon_i2c_recovery() in 
octeon_i2c_probe(), the
problem has gone.

Once more, this octeon_i2c_recovery() can also recover dead lock (I2C slave 
device stuck low SCL) issue,
so I think use octeon_i2c_recovery() instead will be stronger.

BR,
Sean Zhang


-Original Message-
From: Jan Glauber [mailto:jan.glau...@caviumnetworks.com] 
Sent: Friday, December 01, 2017 6:07 PM
To: Zhang, Sean C. (NSB - CN/Hangzhou) 
Cc: david.da...@cavium.com; w...@the-dreams.de; linux-...@vger.kernel.org; 
linux-kernel@vger.kernel.org
Subject: Re: [Bug fix] octeon-i2c driver updates

Hi Sean,

as you try to solve two different issues I suggest that you create one
patch per issue.

For the second point (retry of START after recovery) I would still like
to hear Wolfram's opinion. I would assume that any i2c user should
be well aware of -EAGAIN, so I wonder if it is worth the additional
complexity of the retry logic.

Also, the first issue changes Octeon MIPS which I'm not able to test,
so David needs to be involved here.

thanks,
Jan

On Thu, Nov 30, 2017 at 01:56:09AM +, Zhang, Sean C. (NSB - CN/Hangzhou) 
wrote:
> Hi Jan,
> 
> Any other comments for this patch?
> 
> BR,
> Sean Zhang
> 
> -Original Message-
> From: Zhang, Sean C. (NSB - CN/Hangzhou) 
> Sent: Monday, November 27, 2017 4:38 PM
> To: 'Jan Glauber' 
> Cc: david.da...@cavium.com; w...@the-dreams.de; linux-...@vger.kernel.org; 
> linux-kernel@vger.kernel.org
> Subject: RE: [Bug fix] octeon-i2c driver updates
> 
> Hi Jan,
> 
> There are two points in this patch.
> 
> Point 1. As you see, replaced octeon_i2c_init_lowlevel() by recover bus 
> status if TWSI controller is not IDLE.
> Please take a scenario like this: when system soft reset without I2C slave 
> reset, maybe make this I2C bus
> dead lock occurred (I2C slave device stuck low SCL) in chance. Then during 
> system goes up and I2C slave 
> device creating process, if this I2C slave device has a register with less 
> than 8 bytes to read, but I2C bus was
> still stuck low SCL by last system reset, then the read will failed and this 
> I2C slave device cannot be created.
> If bus recovered before the reading process, this failure can be fixed.
> 
> Function flow explanation shown as below:
> 
> a. System reset without I2C slave device reset
> --make SCL stuck low by I2C slave device
> ..
> b. octeon_i2c_probe()
> -- octeon_i2c_init_lowlevel  //reset TWSI core, but SCL still stuck low by.
> ..
> 
> c. Another I2C slave device creating process
> octeon_i2c_xfer()
> -- octeon_i2c_hlc_comp_read() //failed due to SCL stuck low.
> 
> If full recovery executed in octeon_i2c_probe(), above failure can be avoided.
> 
> 
> Point 2. octeon_i2c_recovery() is used in octeon_i2c_start() error branch, in 
> the case of octeon_i2c_recovery()
> successful, octeon_i2c_start() will return -EAGAIN, and then 
> octeon_i2c_xfer() return with error. I understand this like
> this: if octeon_i2c_recovery() successful, then i2c START signal can be sent 
> again, and all following step can be continue,
> octeon_i2c_xfer() should not return error from this condition.
> 
> BR,
> Sean Zhang
> 
> -Original Message-
> From: Jan Glauber [mailto:jan.glau...@caviumnetworks.com] 
> Sent: Friday, November 24, 2017 9:10 PM
> To: Zhang, Sean C. (NSB - CN/Hangzhou) 
> Cc: david.da...@cavium.com; w...@the-dreams.de; linux-...@vger.kernel.org; 
> linux-kernel@vger.kernel.org
> Subject: Re: [Bug fix] octeon-i2c driver updates
> 
> On Thu, Nov 23, 2017 at 11:42:36AM +, Zhang, Sean C. (NSB - CN/Hangzhou) 
> wrote:
> > Dear Maintainer,
> > 
> > For octeon TWSI controller, I found below two cases, maybe can be improved.
> 
> Hi Sean,
> 
> form the description below this looks like you're fixing a bug. Can you
> elaborate on when the I2C bus dead lock occurs. Is it always happening?
> 
> What I don't like about the patch is that you're removing
> octeon_i2c_init_lowlevel() from the probe and replacing it by _always_
> going through a full recovery. Why is this neccessary?
> 
> Regards,
> Jan
> 
> > 
> > >From 09d9f0ce658d7f6a50d1af352dde619c29bc8bcf Mon Sep 17 00:00:00 2001
> > From: hgt463 
> > Da

[PATCH] writeback: fix comment in __mark_inode_dirty

2017-12-04 Thread Wang Long
Signed-off-by: Wang Long 
---
 fs/fs-writeback.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index cea4836..8d477cf 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -2209,7 +2209,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
trace_writeback_dirty_inode_enqueue(inode);
 
/*
-* If this is the first dirty inode for this bdi,
+* If this is the first dirty inode for this wb,
 * we have to wake-up the corresponding bdi thread
 * to make sure background write-back happens
 * later.
-- 
1.8.3.1



Re: [PATCH v3 12/16] iommu/vt-d: report unrecoverable device faults

2017-12-04 Thread Lu Baolu
Hi,

On 11/18/2017 02:55 AM, Jacob Pan wrote:
> Currently, when device DMA faults are detected by IOMMU the fault
> reasons are printed but the driver of the offending device is

"... but the driver of the offending device is not involved in ..."

Best regards,
Lu Baolu

> involved in fault handling.
> This patch uses per device fault reporting API to send fault event
> data for further processing.
> Offending device is identified by the source ID in VT-d fault reason
> report registers.
>
> Signed-off-by: Liu, Yi L 
> Signed-off-by: Jacob Pan 
> Signed-off-by: Ashok Raj 
> ---
>  drivers/iommu/dmar.c | 94 
> +++-
>  1 file changed, 93 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
> index 38ee91b..b1f67fc2 100644
> --- a/drivers/iommu/dmar.c
> +++ b/drivers/iommu/dmar.c
> @@ -1555,6 +1555,31 @@ static const char *irq_remap_fault_reasons[] =
>   "Blocked an interrupt request due to source-id verification failure",
>  };
>  
> +/* fault data and status */
> +enum intel_iommu_fault_reason {
> + INTEL_IOMMU_FAULT_REASON_SW,
> + INTEL_IOMMU_FAULT_REASON_ROOT_NOT_PRESENT,
> + INTEL_IOMMU_FAULT_REASON_CONTEXT_NOT_PRESENT,
> + INTEL_IOMMU_FAULT_REASON_CONTEXT_INVALID,
> + INTEL_IOMMU_FAULT_REASON_BEYOND_ADDR_WIDTH,
> + INTEL_IOMMU_FAULT_REASON_PTE_WRITE_ACCESS,
> + INTEL_IOMMU_FAULT_REASON_PTE_READ_ACCESS,
> + INTEL_IOMMU_FAULT_REASON_NEXT_PT_INVALID,
> + INTEL_IOMMU_FAULT_REASON_ROOT_ADDR_INVALID,
> + INTEL_IOMMU_FAULT_REASON_CONTEXT_PTR_INVALID,
> + INTEL_IOMMU_FAULT_REASON_NONE_ZERO_RTP,
> + INTEL_IOMMU_FAULT_REASON_NONE_ZERO_CTP,
> + INTEL_IOMMU_FAULT_REASON_NONE_ZERO_PTE,
> + NR_INTEL_IOMMU_FAULT_REASON,
> +};
> +
> +/* fault reasons that are allowed to be reported outside IOMMU subsystem */
> +#define INTEL_IOMMU_FAULT_REASON_ALLOWED \
> + ((1ULL << INTEL_IOMMU_FAULT_REASON_BEYOND_ADDR_WIDTH) | \
> + (1ULL << INTEL_IOMMU_FAULT_REASON_PTE_WRITE_ACCESS) |   \
> + (1ULL << INTEL_IOMMU_FAULT_REASON_PTE_READ_ACCESS))
> +
> +
>  static const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
>  {
>   if (fault_reason >= 0x20 && (fault_reason - 0x20 <
> @@ -1635,6 +1660,69 @@ void dmar_msi_read(int irq, struct msi_msg *msg)
>   raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
>  }
>  
> +static enum iommu_fault_reason to_iommu_fault_reason(u8 reason)
> +{
> + if (reason >= NR_INTEL_IOMMU_FAULT_REASON) {
> + pr_warn("unknown DMAR fault reason %d\n", reason);
> + return IOMMU_FAULT_REASON_UNKNOWN;
> + }
> + switch (reason) {
> + case INTEL_IOMMU_FAULT_REASON_SW:
> + case INTEL_IOMMU_FAULT_REASON_ROOT_NOT_PRESENT:
> + case INTEL_IOMMU_FAULT_REASON_CONTEXT_NOT_PRESENT:
> + case INTEL_IOMMU_FAULT_REASON_CONTEXT_INVALID:
> + case INTEL_IOMMU_FAULT_REASON_BEYOND_ADDR_WIDTH:
> + case INTEL_IOMMU_FAULT_REASON_ROOT_ADDR_INVALID:
> + case INTEL_IOMMU_FAULT_REASON_CONTEXT_PTR_INVALID:
> + return IOMMU_FAULT_REASON_INTERNAL;
> + case INTEL_IOMMU_FAULT_REASON_NEXT_PT_INVALID:
> + case INTEL_IOMMU_FAULT_REASON_PTE_WRITE_ACCESS:
> + case INTEL_IOMMU_FAULT_REASON_PTE_READ_ACCESS:
> + return IOMMU_FAULT_REASON_PERMISSION;
> + default:
> + return IOMMU_FAULT_REASON_UNKNOWN;
> + }
> +}
> +
> +static void report_fault_to_device(struct intel_iommu *iommu, u64 addr, int 
> type,
> + int fault_type, enum intel_iommu_fault_reason 
> reason, u16 sid)
> +{
> + struct iommu_fault_event event;
> + struct pci_dev *pdev;
> + u8 bus, devfn;
> +
> + /* check if fault reason is worth reporting outside IOMMU */
> + if (!((1 << reason) & INTEL_IOMMU_FAULT_REASON_ALLOWED)) {
> + pr_debug("Fault reason %d not allowed to report to device\n",
> + reason);
> + return;
> + }
> +
> + bus = PCI_BUS_NUM(sid);
> + devfn = PCI_DEVFN(PCI_SLOT(sid), PCI_FUNC(sid));
> + /*
> +  * we need to check if the fault reporting is requested for the
> +  * offending device.
> +  */
> + pdev = pci_get_bus_and_slot(bus, devfn);
> + if (!pdev) {
> + pr_warn("No PCI device found for source ID %x\n", sid);
> + return;
> + }
> + /*
> +  * unrecoverable fault is reported per IOMMU, notifier handler can
> +  * resolve PCI device based on source ID.
> +  */
> + event.reason = to_iommu_fault_reason(reason);
> + event.addr = addr;
> + event.type = IOMMU_FAULT_DMA_UNRECOV;
> + event.prot = type ? IOMMU_READ : IOMMU_WRITE;
> + dev_warn(&pdev->dev, "report device unrecoverable fault: %d, %x, %d\n",
> + event.reason, sid, event.type);
> + iommu_report_device_fault(&pdev->dev, &event);
> + pci_dev_put(pdev);
> +}
> +
>  static int dmar_fault

Re: [alsa-devel] [PATCH v4 06/15] soundwire: Add IO transfer

2017-12-04 Thread Vinod Koul
On Sun, Dec 03, 2017 at 09:01:41PM -0600, Pierre-Louis Bossart wrote:
> On 12/3/17 11:04 AM, Vinod Koul wrote:
> >On Fri, Dec 01, 2017 at 05:27:31PM -0600, Pierre-Louis Bossart wrote:

Sorry looks like I missed replying to this one earlier.

> >>>+static inline int find_response_code(enum sdw_command_response resp)
> >>>+{
> >>>+  switch (resp) {
> >>>+  case SDW_CMD_OK:
> >>>+  return 0;
> >>>+
> >>>+  case SDW_CMD_IGNORED:
> >>>+  return -ENODATA;
> >>>+
> >>>+  case SDW_CMD_TIMEOUT:
> >>>+  return -ETIMEDOUT;
> >>>+
> >>>+  default:
> >>>+  return -EIO;
> >>
> >>the 'default' case will handle both SDW_CMD_FAIL (which is a bus event
> >>usually due to bus clash or parity issues) and SDW_CMD_FAIL_OTHER (which is
> >>an imp-def IP event).
> >>
> >>Do they really belong in the same basket? From a debug perspective there is
> >>quite a bit of information lost.
> >
> >at higher level the error handling is same. the information is not lost as
> >it is expected that you would log it at error source.
> 
> I don't understand this. It's certainly not the same for me if you detect an
> electric problem or if the IP is in the weeds. Logging at the source is fine
> but this filtering prevents higher levels from doing anything different.

The point is higher levels like here cant do much than bail out and complain.

Can you point out what would be different behaviour in each of these cases?

> >>>+static inline int do_transfer(struct sdw_bus *bus, struct sdw_msg *msg)
> >>>+{
> >>>+  int retry = bus->prop.err_threshold;
> >>>+  enum sdw_command_response resp;
> >>>+  int ret = 0, i;
> >>>+
> >>>+  for (i = 0; i <= retry; i++) {
> >>>+  resp = bus->ops->xfer_msg(bus, msg);
> >>>+  ret = find_response_code(resp);
> >>>+
> >>>+  /* if cmd is ok or ignored return */
> >>>+  if (ret == 0 || ret == -ENODATA)
> >>
> >>Can you document why you don't retry on a CMD_IGNORED? I know there was a
> >>reason, I just can't remember it.
> >
> >CMD_IGNORED can be okay on broadcast. User of this API can retry all they
> >want!
> 
> So you retry if this is a CMD_FAILED but let higher levels retry for
> CMD_IGNORED, sorry I don't see the logic.

Yes that is right.

If I am doing a broadcast read, lets say for Device Id registers, why in the
world would I want to retry? CMD_IGNORED is a valid response and required to
stop enumeration cycle in that case.

But if I am not expecting a CMD_IGNORED response, I can very well go ahead
and retry from caller. The context is with caller and they can choose to do
appropriate handling.

And I have clarified this couple of times to you already, not sure how many
more times I would have to do that.

> >>Now that I think of it, the retry on TIMEOUT makes no sense to me. The retry
> >>was intended for bus-level issues, where maybe a single bit error causes an
> >>issue without consequences, but the TIMEOUT is a completely different beast,
> >>it's the master IP that doesn't answer really, a completely different case.
> >
> >well in those cases where you have blue wires, it actually helps :)
> 
> Blue wires are not supposed to change electrical behavior. TIMEOUT is only
> an internal SOC level issue, so no I don't get how this helps.
> 
> You have a retry count that is provided in the BIOS/firmware through disco
> properties and it's meant to bus errors. You are abusing the definitions. A
> command failed is supposed to be detected at the frame rate, which is
> typically 20us. a timeout is likely a 100s of ms value, so if you retry on
> top it's going to lock up the bus.

The world is not perfect! A guy debugging setups needs all the help. I do
not see any reason for not to retry. Bus is anyway locked up while a
transfer is ongoing (we serialize transfers).

Now if you feel this should be abhorred, I can change this for timeout.

> >>>+enum sdw_command_response {
> >>>+  SDW_CMD_OK = 0,
> >>>+  SDW_CMD_IGNORED = 1,
> >>>+  SDW_CMD_FAIL = 2,
> >>>+  SDW_CMD_TIMEOUT = 4,
> >>>+  SDW_CMD_FAIL_OTHER = 8,
> >>
> >>Humm, I can't recall if/why this is a mask? does it need to be?
> >
> >mask, not following!
> >
> >Taking a wild guess that you are asking about last error, which is for SW
> >errors like malloc fail etc...
> 
> no, I was asking why this is declared as if it was used for a bitmask, why
> not 0,1,2,3,4?

Oh okay, I think it was something to do with bits for errors, but don see it
helping so I can change it either way...

-- 
~Vinod


[PATCH v3] scripts: leaking_addresses: add support for 32-bit kernel addresses

2017-12-04 Thread kaiwan . billimoria
Currently, leaking_addresses.pl only supports scanning 64 bit
architectures. This is due to how the regular expressions are formed. We
can do better than this. 32 architectures can be supported if we take
into consideration the kernel virtual address split (via the PAGE_OFFSET
kernel configurable).

Add support for ix86 32 bit architectures.
 - Add command line option for page offset.
 - Add command line option for kernel configuration file.
 - Parse kernel config file for page offset (CONFIG_PAGE_OFFSET).
 - Use page offset when checking for kernel virtual addresses.


Signed-off-by: Kaiwan N Billimoria 
---

Note- This patch represents co development by Tobin and Kaiwan (plus 
suggestions from 
Alexander Kapshuk). Applies on Tobin's tree 'leaks' branch on top of commit 
680db1ef560f
(leaking_addresses: fix typo function not called).


 scripts/leaking_addresses.pl | 169 +--
 1 file changed, 148 insertions(+), 21 deletions(-)

diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl
index 2d5336b3e1ea..6b015980d117 100755
--- a/scripts/leaking_addresses.pl
+++ b/scripts/leaking_addresses.pl
@@ -24,6 +24,7 @@ use Cwd 'abs_path';
 use Term::ANSIColor qw(:constants);
 use Getopt::Long qw(:config no_auto_abbrev);
 use Config;
+use feature 'state';
 
 my $P = $0;
 my $V = '0.01';
@@ -37,18 +38,20 @@ my $TIMEOUT = 10;
 # Script can only grep for kernel addresses on the following architectures. If
 # your architecture is not listed here and has a grep'able kernel address 
please
 # consider submitting a patch.
-my @SUPPORTED_ARCHITECTURES = ('x86_64', 'ppc64');
+my @SUPPORTED_ARCHITECTURES = ('x86_64', 'ppc64',  'i[3456]86');
 
 # Command line options.
 my $help = 0;
 my $debug = 0;
-my $raw = 0;
-my $output_raw = "";   # Write raw results to file.
-my $input_raw = "";# Read raw results from file instead of scanning.
+my $raw = 0;   # Show raw output.
+my $output_raw = "";   # Write raw results to file.
+my $input_raw = "";# Read raw results from file instead of 
scanning.
+my $suppress_dmesg = 0;   # Don't show dmesg in output.
+my $squash_by_path = 0;   # Summary report grouped by absolute 
path.
+my $squash_by_filename = 0;# Summary report grouped by filename.
 
-my $suppress_dmesg = 0;# Don't show dmesg in output.
-my $squash_by_path = 0;# Summary report grouped by absolute 
path.
-my $squash_by_filename = 0;# Summary report grouped by filename.
+my $page_offset_32bit = 0; # 32-bit: value of CONFIG_PAGE_OFFSET
+my $kernel_config_file = "";   # Kernel configuration file.
 
 # Do not parse these files (absolute path).
 my @skip_parse_files_abs = ('/proc/kmsg',
@@ -97,14 +100,16 @@ Version: $V
 
 Options:
 
-   -o, --output-raw=  Save results for future processing.
-   -i, --input-raw=   Read results from file instead of scanning.
-   --rawShow raw results (default).
-   --suppress-dmesg Do not show dmesg results.
-   --squash-by-path Show one result per unique path.
-   --squash-by-filename Show one result per unique filename.
-   -d, --debug  Display debugging output.
-   -h, --help, --versionDisplay this help and exit.
+   -o, --output-raw= Save results for future processing.
+   -i, --input-raw=  Read results from file instead of 
scanning.
+   --raw   Show raw results (default).
+   --suppress-dmesgDo not show dmesg results.
+   --squash-by-pathShow one result per unique path.
+   --squash-by-filenameShow one result per unique filename.
+   --page-offset-32bit=   PAGE_OFFSET value (for 32-bit kernels).
+   --kernel-config-file= Kernel configuration file (e.g 
/boot/config)
+   -d, --debug Display debugging output.
+   -h, --help, --version   Display this help and exit.
 
 Examples:
 
@@ -117,7 +122,10 @@ Examples:
# View summary report.
$0 --input-raw scan.out --squash-by-filename
 
-Scans the running (64 bit) kernel for potential leaking addresses.
+   # Scan kernel on a 32-bit system with a 2GB:2GB virtual address split.
+   $0 --page-offset-32bit=0x8000
+
+Scans the running kernel for potential leaking addresses.
 
 EOM
exit($exitcode);
@@ -133,6 +141,8 @@ GetOptions(
'squash-by-path'=> \$squash_by_path,
'squash-by-filename'=> \$squash_by_filename,
'raw'   => \$raw,
+   'page-offset-32bit=o'   => \$page_offset_32bit,
+   'kernel-config-file=s'  => \$kernel_config_file,
 ) or help(1);
 
 help(0) if ($help);
@@ -148,6 +158,7 @@ if (!$input_raw and ($squash_by_path or 
$squash_by_filename)) {
exit(128);
 }
 
+show_detected_architecture() if $debug;
 if (!is_supported_architecture()) {

Re: [PATCH 4.14 00/95] 4.14.4-stable review

2017-12-04 Thread Greg Kroah-Hartman
On Mon, Dec 04, 2017 at 01:29:42PM -0700, Shuah Khan wrote:
> On 12/04/2017 08:59 AM, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 4.14.4 release.
> > There are 95 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> > 
> > Responses should be made by Wed Dec  6 16:00:27 UTC 2017.
> > Anything received after that time might be too late.
> > 
> > The whole patch series can be found in one patch at:
> > kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.4-rc1.gz
> > or in the git tree and branch at:
> >   git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> > linux-4.14.y
> > and the diffstat can be found below.
> > 
> > thanks,
> > 
> > greg k-h
> > 
> 
> Compiled and booted on my test system. No dmesg regressions.

Great, thanks for testing all of these and letting me know.

greg k-h


Re: [PATCH 4.14 00/95] 4.14.4-stable review

2017-12-04 Thread Greg Kroah-Hartman
On Mon, Dec 04, 2017 at 03:46:31PM -0800, Guenter Roeck wrote:
> On Mon, Dec 04, 2017 at 04:59:24PM +0100, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 4.14.4 release.
> > There are 95 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> > 
> > Responses should be made by Wed Dec  6 16:00:27 UTC 2017.
> > Anything received after that time might be too late.
> > 
> 
> Build results:
>   total: 145 pass: 145 fail: 0
> Qemu test results:
>   total: 123 pass: 123 fail: 0
> 
> Details are available at http://kerneltests.org/builders.

Great, thanks for testing all of these and letting me know.

greg k-h


[PATCH v3 08/14] nubus: Clean up whitespace

2017-12-04 Thread Finn Thain
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 include/linux/nubus.h | 54 +--
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/include/linux/nubus.h b/include/linux/nubus.h
index 46e4d983feac..84f2e0fa1898 100644
--- a/include/linux/nubus.h
+++ b/include/linux/nubus.h
@@ -28,9 +28,9 @@ struct nubus_dirent {
 };
 
 struct nubus_board {
-   struct nubus_board* next;
-   struct nubus_dev* first_dev;
-   
+   struct nubus_board *next;
+   struct nubus_dev *first_dev;
+
/* Only 9-E actually exist, though 0-8 are also theoretically
   possible, and 0 is a special case which represents the
   motherboard and onboard peripherals (Ethernet, video) */
@@ -39,10 +39,10 @@ struct nubus_board {
char name[64];
 
/* Format block */
-   unsigned char* fblock;
+   unsigned char *fblock;
/* Root directory (does *not* always equal fblock + doffset!) */
-   unsigned char* directory;
-   
+   unsigned char *directory;
+
unsigned long slot_addr;
/* Offset to root directory (sometimes) */
unsigned long doffset;
@@ -60,7 +60,7 @@ struct nubus_board {
 
 struct nubus_dev {
/* Next link in device list */
-   struct nubus_dev* next;
+   struct nubus_dev *next;
 
/* The functional resource ID of this device */
unsigned char resid;
@@ -70,17 +70,17 @@ struct nubus_dev {
unsigned short type;
unsigned short dr_sw;
unsigned short dr_hw;
-   
+
/* Functional directory */
-   unsigned char* directory;
+   unsigned char *directory;
/* Much of our info comes from here */
-   struct nubus_board* board;
+   struct nubus_board *board;
 };
 
 /* This is all NuBus devices (used to find devices later on) */
-extern struct nubus_dev* nubus_devices;
+extern struct nubus_dev *nubus_devices;
 /* This is all NuBus cards */
-extern struct nubus_board* nubus_boards;
+extern struct nubus_board *nubus_boards;
 
 /* Generic NuBus interface functions, modelled after the PCI interface */
 #ifdef CONFIG_PROC_FS
@@ -91,38 +91,38 @@ static inline void nubus_proc_init(void) {}
 
 int nubus_proc_attach_device(struct nubus_dev *dev);
 /* If we need more precision we can add some more of these */
-struct nubus_dev* nubus_find_type(unsigned short category,
+struct nubus_dev *nubus_find_type(unsigned short category,
  unsigned short type,
- const struct nubus_dev* from);
+ const struct nubus_dev *from);
 /* Might have more than one device in a slot, you know... */
-struct nubus_dev* nubus_find_slot(unsigned int slot,
- const struct nubus_dev* from);
+struct nubus_dev *nubus_find_slot(unsigned int slot,
+ const struct nubus_dev *from);
 
 /* These are somewhat more NuBus-specific.  They all return 0 for
success and -1 for failure, as you'd expect. */
 
 /* The root directory which contains the board and functional
directories */
-int nubus_get_root_dir(const struct nubus_board* board,
-  struct nubus_dir* dir);
+int nubus_get_root_dir(const struct nubus_board *board,
+  struct nubus_dir *dir);
 /* The board directory */
 int nubus_get_board_dir(const struct nubus_board* board,
struct nubus_dir* dir);
 /* The functional directory */
-int nubus_get_func_dir(const struct nubus_dev* dev,
-  struct nubus_dir* dir);
+int nubus_get_func_dir(const struct nubus_dev *dev,
+  struct nubus_dir *dir);
 
 /* These work on any directory gotten via the above */
-int nubus_readdir(struct nubus_dir* dir,
- struct nubus_dirent* ent);
-int nubus_find_rsrc(struct nubus_dir* dir,
+int nubus_readdir(struct nubus_dir *dir,
+ struct nubus_dirent *ent);
+int nubus_find_rsrc(struct nubus_dir *dir,
unsigned char rsrc_type,
-   struct nubus_dirent* ent);
-int nubus_rewinddir(struct nubus_dir* dir);
+   struct nubus_dirent *ent);
+int nubus_rewinddir(struct nubus_dir *dir);
 
 /* Things to do with directory entries */
-int nubus_get_subdir(const struct nubus_dirent* ent,
-struct nubus_dir* dir);
+int nubus_get_subdir(const struct nubus_dirent *ent,
+struct nubus_dir *dir);
 void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
 unsigned int len);
 void nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
-- 
2.13.6



Re: [PATCH 4.14 00/95] 4.14.4-stable review

2017-12-04 Thread Greg Kroah-Hartman
On Mon, Dec 04, 2017 at 03:12:45PM -0600, Tom Gall wrote:
> 
> 
> > On Dec 4, 2017, at 9:59 AM, Greg Kroah-Hartman  
> > wrote:
> > 
> > This is the start of the stable review cycle for the 4.14.4 release.
> > There are 95 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> > 
> > Responses should be made by Wed Dec  6 16:00:27 UTC 2017.
> > Anything received after that time might be too late.
> > 
> > The whole patch series can be found in one patch at:
> > kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.4-rc1.gz
> > or in the git tree and branch at:
> >  git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> > linux-4.14.y
> > and the diffstat can be found below.
> > 
> > thanks,
> > 
> > greg k-h
> > 
> 
> Compiled, booted and ran the following package unit tests without regressions 
> on x86_64
> 
> boringssl : 
>go test target:0/0/5764/5764/5764 PASS
>ssl_test : 10 pass
>crypto_test : 28 pass
> e2fsprogs:
>make check : 340 pass
> sqlite
>make test : 143914 pass
> drm
>make check : 15 pass
>modetest, drmdevice : pass
> alsa-lib
>make check : 2 pass
> bluez
>make check : 25 pass
> libusb
>stress : 4 pass

How do the above tests stress the kernel?  Aren't they just
verifications that the source code in the package is correct?

I guess it proves something, but have you ever seen the above regress in
_any_ kernel release?

I know the drm developers have a huge test suite that they use to verify
their kernel changes, why not use that?

thanks,

greg k-h


[PATCH v3 04/14] nubus: Fix log spam

2017-12-04 Thread Finn Thain
Testing shows that a single Radius PrecisionColor 24X display board,
which has 95 functional resources, produces over a thousand lines of
log messages. Suppress these messages with pr_debug().
Remove some redundant messages relating to nubus_get_subdir() calls.
Fix the format block debug messages as the sequence of entries is
backwards (my bad).
Move the "scanning slots" message to its proper location.

Fixes: 71ae40e4cf33 ("nubus: Clean up printk calls")
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/nubus/nubus.c | 128 ++
 1 file changed, 55 insertions(+), 73 deletions(-)

diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index 3c1d386a4640..2475b48c29d4 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -353,15 +353,15 @@ static int __init nubus_show_display_resource(struct 
nubus_dev *dev,
 {
switch (ent->type) {
case NUBUS_RESID_GAMMADIR:
-   pr_info("gamma directory offset: 0x%06x\n", ent->data);
+   pr_debug("gamma directory offset: 0x%06x\n", ent->data);
break;
case 0x0080 ... 0x0085:
-   pr_info("mode %02X info offset: 0x%06x\n",
-  ent->type, ent->data);
+   pr_debug("mode 0x%02x info offset: 0x%06x\n",
+   ent->type, ent->data);
break;
default:
-   pr_info("unknown resource %02X, data 0x%06x\n",
-  ent->type, ent->data);
+   pr_debug("unknown resource 0x%02x, data 0x%06x\n",
+   ent->type, ent->data);
}
return 0;
 }
@@ -375,12 +375,12 @@ static int __init nubus_show_network_resource(struct 
nubus_dev *dev,
char addr[6];
 
nubus_get_rsrc_mem(addr, ent, 6);
-   pr_info("MAC address: %pM\n", addr);
+   pr_debug("MAC address: %pM\n", addr);
break;
}
default:
-   pr_info("unknown resource %02X, data 0x%06x\n",
-  ent->type, ent->data);
+   pr_debug("unknown resource 0x%02x, data 0x%06x\n",
+   ent->type, ent->data);
}
return 0;
 }
@@ -394,8 +394,8 @@ static int __init nubus_show_cpu_resource(struct nubus_dev 
*dev,
unsigned long meminfo[2];
 
nubus_get_rsrc_mem(&meminfo, ent, 8);
-   pr_info("memory: [ 0x%08lx 0x%08lx ]\n",
-  meminfo[0], meminfo[1]);
+   pr_debug("memory: [ 0x%08lx 0x%08lx ]\n",
+   meminfo[0], meminfo[1]);
break;
}
case NUBUS_RESID_ROMINFO:
@@ -403,13 +403,13 @@ static int __init nubus_show_cpu_resource(struct 
nubus_dev *dev,
unsigned long rominfo[2];
 
nubus_get_rsrc_mem(&rominfo, ent, 8);
-   pr_info("ROM:[ 0x%08lx 0x%08lx ]\n",
-  rominfo[0], rominfo[1]);
+   pr_debug("ROM:[ 0x%08lx 0x%08lx ]\n",
+   rominfo[0], rominfo[1]);
break;
}
default:
-   pr_info("unknown resource %02X, data 0x%06x\n",
-  ent->type, ent->data);
+   pr_debug("unknown resource 0x%02x, data 0x%06x\n",
+   ent->type, ent->data);
}
return 0;
 }
@@ -428,8 +428,8 @@ static int __init nubus_show_private_resource(struct 
nubus_dev *dev,
nubus_show_cpu_resource(dev, ent);
break;
default:
-   pr_info("unknown resource %02X, data 0x%06x\n",
-  ent->type, ent->data);
+   pr_debug("unknown resource 0x%02x, data 0x%06x\n",
+   ent->type, ent->data);
}
return 0;
 }
@@ -442,12 +442,9 @@ nubus_get_functional_resource(struct nubus_board *board, 
int slot,
struct nubus_dirent ent;
struct nubus_dev *dev;
 
-   pr_info("  Function 0x%02x:\n", parent->type);
+   pr_debug("  Functional resource 0x%02x:\n", parent->type);
nubus_get_subdir(parent, &dir);
 
-   pr_debug("%s: parent is 0x%p, dir is 0x%p\n",
-__func__, parent->base, dir.base);
-
/* Actually we should probably panic if this fails */
if ((dev = kzalloc(sizeof(*dev), GFP_ATOMIC)) == NULL)
return NULL;
@@ -466,14 +463,14 @@ nubus_get_functional_resource(struct nubus_board *board, 
int slot,
dev->type = nbtdata[1];
dev->dr_sw= nbtdata[2];
dev->dr_hw= nbtdata[3];
-   pr_info("type: [cat 0x%x type 0x%x sw 0x%x hw 
0x%x]\n",
-   nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
+   pr_debug("type: [cat 0x%x type 0x%x sw 0x%x hw 

[PATCH v3 09/14] nubus: Generalize block resource handling

2017-12-04 Thread Finn Thain
Scrap the specialized code to unpack video mode name resources and
driver resources. It isn't useful.
Instead, add a re-usable function to handle lists of block resources of
any kind, and descend into the video mode table resource directory.
Rename callers as nubus_get_foo(), consistent with their purpose and
with related functions in the same file.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/nubus/nubus.c | 123 ++
 1 file changed, 65 insertions(+), 58 deletions(-)

diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index 041c2be7407f..a7b480534a17 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -331,16 +331,63 @@ EXPORT_SYMBOL(nubus_find_rsrc);
among other things.  The rest of it should go in the /proc code.
For now, we just use it to give verbose boot logs. */
 
-static int __init nubus_show_display_resource(struct nubus_dev *dev,
- const struct nubus_dirent *ent)
+static int __init nubus_get_block_rsrc_dir(struct nubus_board *board,
+   const struct nubus_dirent *parent)
+{
+   struct nubus_dir dir;
+   struct nubus_dirent ent;
+
+   nubus_get_subdir(parent, &dir);
+
+   while (nubus_readdir(&dir, &ent) != -1) {
+   u32 size;
+
+   nubus_get_rsrc_mem(&size, &ent, 4);
+   pr_debug("block (0x%x), size %d\n", ent.type, size);
+   }
+   return 0;
+}
+
+static int __init nubus_get_display_vidmode(struct nubus_board *board,
+const struct nubus_dirent *parent)
+{
+   struct nubus_dir dir;
+   struct nubus_dirent ent;
+
+   nubus_get_subdir(parent, &dir);
+
+   while (nubus_readdir(&dir, &ent) != -1) {
+   switch (ent.type) {
+   case 1: /* mVidParams */
+   case 2: /* mTable */
+   {
+   u32 size;
+
+   nubus_get_rsrc_mem(&size, &ent, 4);
+   pr_debug("block (0x%x), size %d\n", ent.type,
+   size);
+   break;
+   }
+   default:
+   pr_debug("unknown resource 0x%02x, data 
0x%06x\n",
+   ent.type, ent.data);
+   }
+   }
+   return 0;
+}
+
+static int __init nubus_get_display_resource(struct nubus_dev *dev,
+ const struct nubus_dirent *ent)
 {
switch (ent->type) {
case NUBUS_RESID_GAMMADIR:
pr_debug("gamma directory offset: 0x%06x\n", ent->data);
+   nubus_get_block_rsrc_dir(dev->board, ent);
break;
case 0x0080 ... 0x0085:
pr_debug("mode 0x%02x info offset: 0x%06x\n",
ent->type, ent->data);
+   nubus_get_display_vidmode(dev->board, ent);
break;
default:
pr_debug("unknown resource 0x%02x, data 0x%06x\n",
@@ -349,8 +396,8 @@ static int __init nubus_show_display_resource(struct 
nubus_dev *dev,
return 0;
 }
 
-static int __init nubus_show_network_resource(struct nubus_dev *dev,
- const struct nubus_dirent *ent)
+static int __init nubus_get_network_resource(struct nubus_dev *dev,
+ const struct nubus_dirent *ent)
 {
switch (ent->type) {
case NUBUS_RESID_MAC_ADDRESS:
@@ -368,8 +415,8 @@ static int __init nubus_show_network_resource(struct 
nubus_dev *dev,
return 0;
 }
 
-static int __init nubus_show_cpu_resource(struct nubus_dev *dev,
- const struct nubus_dirent *ent)
+static int __init nubus_get_cpu_resource(struct nubus_dev *dev,
+ const struct nubus_dirent *ent)
 {
switch (ent->type) {
case NUBUS_RESID_MEMINFO:
@@ -397,18 +444,18 @@ static int __init nubus_show_cpu_resource(struct 
nubus_dev *dev,
return 0;
 }
 
-static int __init nubus_show_private_resource(struct nubus_dev *dev,
- const struct nubus_dirent *ent)
+static int __init nubus_get_private_resource(struct nubus_dev *dev,
+ const struct nubus_dirent *ent)
 {
switch (dev->category) {
case NUBUS_CAT_DISPLAY:
-   nubus_show_display_resource(dev, ent);
+   nubus_get_display_resource(dev, ent);
break;
case NUBUS_CAT_NETWORK:
-   nubus_show_network_resource(dev, ent);
+   nubus_get_network_resource(dev, ent);
break;
case NUBUS_CAT_CPU:
-   nubus_show_cpu_resource(dev, ent);
+   nubus_get_cpu_resource(dev, ent);
break;
  

[PATCH v3 10/14] nubus: Rework /proc/bus/nubus/s/ implementation

2017-12-04 Thread Finn Thain
The /proc/bus/nubus/s/ directory tree for any slot s is missing a lot
of information. The struct file_operations methods have long been left
unimplemented (hence the familiar compile-time warning, "Need to set
some I/O handlers here").

Slot resources have a complex structure which varies depending on board
function. The logic for interpreting these ROM data structures is found
in nubus.c. Let's not duplicate that logic in proc.c.

Create the /proc/bus/nubus/s/ inodes while scanning slot s. During
descent through slot resource subdirectories, call the new
nubus_proc_add_foo() functions to create the procfs inodes.

Also add a new function, nubus_seq_write_rsrc_mem(), to write the
contents of a particular slot resource to a given seq_file. This is
used by the procfs file_operations methods, to finally give userspace
access to slot ROM information, such as the available video modes.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/nubus/nubus.c | 118 --
 drivers/nubus/proc.c  | 223 ++
 include/linux/nubus.h |  37 -
 3 files changed, 259 insertions(+), 119 deletions(-)

diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index a7b480534a17..b0d8aa721173 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -146,7 +147,7 @@ static inline void *nubus_rom_addr(int slot)
return (void *)(0xF100 + (slot << 24));
 }
 
-static unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
+unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
 {
unsigned char *p = nd->base;
 
@@ -173,8 +174,8 @@ void nubus_get_rsrc_mem(void *dest, const struct 
nubus_dirent *dirent,
 }
 EXPORT_SYMBOL(nubus_get_rsrc_mem);
 
-void nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
-unsigned int len)
+unsigned int nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
+unsigned int len)
 {
char *t = dest;
unsigned char *p = nubus_dirptr(dirent);
@@ -189,9 +190,33 @@ void nubus_get_rsrc_str(char *dest, const struct 
nubus_dirent *dirent,
}
if (len > 0)
*t = '\0';
+   return t - dest;
 }
 EXPORT_SYMBOL(nubus_get_rsrc_str);
 
+void nubus_seq_write_rsrc_mem(struct seq_file *m,
+  const struct nubus_dirent *dirent,
+  unsigned int len)
+{
+   unsigned long buf[32];
+   unsigned int buf_size = sizeof(buf);
+   unsigned char *p = nubus_dirptr(dirent);
+
+   /* If possible, write out full buffers */
+   while (len >= buf_size) {
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(buf); i++)
+   buf[i] = nubus_get_rom(&p, sizeof(buf[0]),
+  dirent->mask);
+   seq_write(m, buf, buf_size);
+   len -= buf_size;
+   }
+   /* If not, write out individual bytes */
+   while (len--)
+   seq_putc(m, nubus_get_rom(&p, 1, dirent->mask));
+}
+
 int nubus_get_root_dir(const struct nubus_board *board,
   struct nubus_dir *dir)
 {
@@ -326,35 +351,35 @@ EXPORT_SYMBOL(nubus_find_rsrc);
looking at, and print out lots and lots of information from the
resource blocks. */
 
-/* FIXME: A lot of this stuff will eventually be useful after
-   initialization, for intelligently probing Ethernet and video chips,
-   among other things.  The rest of it should go in the /proc code.
-   For now, we just use it to give verbose boot logs. */
-
 static int __init nubus_get_block_rsrc_dir(struct nubus_board *board,
+   struct proc_dir_entry *procdir,
const struct nubus_dirent *parent)
 {
struct nubus_dir dir;
struct nubus_dirent ent;
 
nubus_get_subdir(parent, &dir);
+   dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
 
while (nubus_readdir(&dir, &ent) != -1) {
u32 size;
 
nubus_get_rsrc_mem(&size, &ent, 4);
pr_debug("block (0x%x), size %d\n", ent.type, size);
+   nubus_proc_add_rsrc_mem(dir.procdir, &ent, size);
}
return 0;
 }
 
 static int __init nubus_get_display_vidmode(struct nubus_board *board,
+struct proc_dir_entry *procdir,
 const struct nubus_dirent *parent)
 {
struct nubus_dir dir;
struct nubus_dirent ent;
 
nubus_get_subdir(parent, &dir);
+   dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
 
while (nubus_readdir(&dir, &ent) != -1) {
switch (ent.type) {
@@ -366,37 +391,42 @@ static int __init nubus_get_di

[PATCH v3 11/14] nubus: Rename struct nubus_dev

2017-12-04 Thread Finn Thain
It is misleading to call a functional resource a "device". In adopting
the Linux Driver Model, the struct device will be embedded in struct
nubus_board. That will compound the terminlogy problem because drivers
will bind with boards, not with functional resources. Avoid this by
renaming struct nubus_dev as struct nubus_rsrc. "Functional resource"
is the vendor's terminology so this helps avoid confusion.

Cc: Bartlomiej Zolnierkiewicz 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/net/ethernet/8390/mac8390.c |  26 
 drivers/net/ethernet/natsemi/macsonic.c |  22 +++
 drivers/nubus/nubus.c   | 105 
 drivers/nubus/proc.c|  15 ++---
 drivers/video/fbdev/macfb.c |   2 +-
 include/linux/nubus.h   |  30 +
 6 files changed, 98 insertions(+), 102 deletions(-)

diff --git a/drivers/net/ethernet/8390/mac8390.c 
b/drivers/net/ethernet/8390/mac8390.c
index 9497f18eaba0..929ff6419621 100644
--- a/drivers/net/ethernet/8390/mac8390.c
+++ b/drivers/net/ethernet/8390/mac8390.c
@@ -123,7 +123,8 @@ enum mac8390_access {
 };
 
 extern int mac8390_memtest(struct net_device *dev);
-static int mac8390_initdev(struct net_device *dev, struct nubus_dev *ndev,
+static int mac8390_initdev(struct net_device *dev,
+  struct nubus_rsrc *ndev,
   enum mac8390_type type);
 
 static int mac8390_open(struct net_device *dev);
@@ -169,11 +170,11 @@ static void word_memcpy_tocard(unsigned long tp, const 
void *fp, int count);
 static void word_memcpy_fromcard(void *tp, unsigned long fp, int count);
 static u32 mac8390_msg_enable;
 
-static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev)
+static enum mac8390_type __init mac8390_ident(struct nubus_rsrc *fres)
 {
-   switch (dev->dr_sw) {
+   switch (fres->dr_sw) {
case NUBUS_DRSW_3COM:
-   switch (dev->dr_hw) {
+   switch (fres->dr_hw) {
case NUBUS_DRHW_APPLE_SONIC_NB:
case NUBUS_DRHW_APPLE_SONIC_LC:
case NUBUS_DRHW_SONNET:
@@ -184,7 +185,7 @@ static enum mac8390_type __init mac8390_ident(struct 
nubus_dev *dev)
break;
 
case NUBUS_DRSW_APPLE:
-   switch (dev->dr_hw) {
+   switch (fres->dr_hw) {
case NUBUS_DRHW_ASANTE_LC:
return MAC8390_NONE;
case NUBUS_DRHW_CABLETRON:
@@ -201,7 +202,7 @@ static enum mac8390_type __init mac8390_ident(struct 
nubus_dev *dev)
case NUBUS_DRSW_TECHWORKS:
case NUBUS_DRSW_DAYNA2:
case NUBUS_DRSW_DAYNA_LC:
-   if (dev->dr_hw == NUBUS_DRHW_CABLETRON)
+   if (fres->dr_hw == NUBUS_DRHW_CABLETRON)
return MAC8390_CABLETRON;
else
return MAC8390_APPLE;
@@ -212,7 +213,7 @@ static enum mac8390_type __init mac8390_ident(struct 
nubus_dev *dev)
break;
 
case NUBUS_DRSW_KINETICS:
-   switch (dev->dr_hw) {
+   switch (fres->dr_hw) {
case NUBUS_DRHW_INTERLAN:
return MAC8390_INTERLAN;
default:
@@ -225,8 +226,8 @@ static enum mac8390_type __init mac8390_ident(struct 
nubus_dev *dev)
 * These correspond to Dayna Sonic cards
 * which use the macsonic driver
 */
-   if (dev->dr_hw == NUBUS_DRHW_SMC9194 ||
-   dev->dr_hw == NUBUS_DRHW_INTERLAN)
+   if (fres->dr_hw == NUBUS_DRHW_SMC9194 ||
+   fres->dr_hw == NUBUS_DRHW_INTERLAN)
return MAC8390_NONE;
else
return MAC8390_DAYNA;
@@ -289,7 +290,8 @@ static int __init mac8390_memsize(unsigned long membase)
return i * 0x1000;
 }
 
-static bool __init mac8390_init(struct net_device *dev, struct nubus_dev *ndev,
+static bool __init mac8390_init(struct net_device *dev,
+   struct nubus_rsrc *ndev,
enum mac8390_type cardtype)
 {
struct nubus_dir dir;
@@ -394,7 +396,7 @@ static bool __init mac8390_init(struct net_device *dev, 
struct nubus_dev *ndev,
 struct net_device * __init mac8390_probe(int unit)
 {
struct net_device *dev;
-   struct nubus_dev *ndev = NULL;
+   struct nubus_rsrc *ndev = NULL;
int err = -ENODEV;
struct ei_device *ei_local;
 
@@ -489,7 +491,7 @@ static const struct net_device_ops mac8390_netdev_ops = {
 };
 
 static int __init mac8390_initdev(struct net_device *dev,
- struct nubus_dev *ndev,
+ struct nubus_rsrc *ndev,
  enum mac8390_type type)
 {
static u32 fwrd4_offsets[16] = {
diff --git a/drivers/net/ethernet/natsemi/macsonic.c 
b/drivers/net/ethernet/natsemi

Re: [PATCH v3 10/16] iommu: introduce device fault report API

2017-12-04 Thread Lu Baolu
Hi,

On 11/18/2017 02:55 AM, Jacob Pan wrote:
> Traditionally, device specific faults are detected and handled within
> their own device drivers. When IOMMU is enabled, faults such as DMA
> related transactions are detected by IOMMU. There is no generic
> reporting mechanism to report faults back to the in-kernel device
> driver or the guest OS in case of assigned devices.
>
> Faults detected by IOMMU is based on the transaction's source ID which
> can be reported at per device basis, regardless of the device type is a
> PCI device or not.
>
> The fault types include recoverable (e.g. page request) and
> unrecoverable faults(e.g. access error). In most cases, faults can be
> handled by IOMMU drivers internally. The primary use cases are as
> follows:
> 1. page request fault originated from an SVM capable device that is
> assigned to guest via vIOMMU. In this case, the first level page tables
> are owned by the guest. Page request must be propagated to the guest to
> let guest OS fault in the pages then send page response. In this
> mechanism, the direct receiver of IOMMU fault notification is VFIO,
> which can relay notification events to QEMU or other user space
> software.
>
> 2. faults need more subtle handling by device drivers. Other than
> simply invoke reset function, there are needs to let device driver
> handle the fault with a smaller impact.
>
> This patchset is intended to create a generic fault report API such
> that it can scale as follows:
> - all IOMMU types
> - PCI and non-PCI devices
> - recoverable and unrecoverable faults
> - VFIO and other other in kernel users
> - DMA & IRQ remapping (TBD)
> The original idea was brought up by David Woodhouse and discussions
> summarized at https://lwn.net/Articles/608914/.
>
> Signed-off-by: Jacob Pan 
> Signed-off-by: Ashok Raj 
> ---
>  drivers/iommu/iommu.c | 63 
> ++-
>  include/linux/iommu.h | 36 +
>  2 files changed, 98 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 829e9e9..97b7990 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -581,6 +581,12 @@ int iommu_group_add_device(struct iommu_group *group, 
> struct device *dev)
>   goto err_free_name;
>   }
>  
> + dev->iommu_param = kzalloc(sizeof(struct iommu_fault_param), 
> GFP_KERNEL);
> + if (!dev->iommu_param) {
> + ret = -ENOMEM;
> + goto err_free_name;
> + }
> +
>   kobject_get(group->devices_kobj);
>  
>   dev->iommu_group = group;
> @@ -657,7 +663,7 @@ void iommu_group_remove_device(struct device *dev)
>   sysfs_remove_link(&dev->kobj, "iommu_group");
>  
>   trace_remove_device_from_group(group->id, dev);
> -
> + kfree(dev->iommu_param);
>   kfree(device->name);
>   kfree(device);
>   dev->iommu_group = NULL;
> @@ -791,6 +797,61 @@ int iommu_group_unregister_notifier(struct iommu_group 
> *group,
>  }
>  EXPORT_SYMBOL_GPL(iommu_group_unregister_notifier);
>  
> +int iommu_register_device_fault_handler(struct device *dev,
> + iommu_dev_fault_handler_t handler,
> + void *data)
> +{
> + struct iommu_param *idata = dev->iommu_param;
> +
> + /*
> +  * Device iommu_param should have been allocated when device is
> +  * added to its iommu_group.
> +  */
> + if (!idata)
> + return -EINVAL;
> + /* Only allow one fault handler registered for each device */
> + if (idata->fault_param)
> + return -EBUSY;
> + get_device(dev);
> + idata->fault_param =
> + kzalloc(sizeof(struct iommu_fault_param), GFP_KERNEL);
> + if (!idata->fault_param)
> + return -ENOMEM;
> + idata->fault_param->handler = handler;
> + idata->fault_param->data = data;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(iommu_register_device_fault_handler);
> +
> +int iommu_unregister_device_fault_handler(struct device *dev)
> +{
> + struct iommu_param *idata = dev->iommu_param;
> +
> + if (!idata)
> + return -EINVAL;
> +
> + kfree(idata->fault_param);
> + idata->fault_param = NULL;
> + put_device(dev);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(iommu_unregister_device_fault_handler);
> +
> +
> +int iommu_report_device_fault(struct device *dev, struct iommu_fault_event 
> *evt)
> +{
> + /* we only report device fault if there is a handler registered */
> + if (!dev->iommu_param || !dev->iommu_param->fault_param ||
> + !dev->iommu_param->fault_param->handler)

Can this replaced by:

if (!iommu_has_device_fault_handler(dev))

?

Best regards,
Lu Baolu

> + return -ENOSYS;
> +
> + return dev->iommu_param->fault_param->handler(evt,
> + 
> dev->iommu_param->fault_param->data);
> +}
> +EXPORT_SYMBOL_GPL(iommu_report_device_f

[PATCH v3 06/14] nubus: Call proc_mkdir() not more than once per slot directory

2017-12-04 Thread Finn Thain
This patch fixes the following WARNING.

proc_dir_entry 'nubus/a' already registered
Modules linked in:
CPU: 0 PID: 1 Comm: swapper Tainted: GW   
4.13.0-00036-gd57552077387 #1
Stack from 01c1bd9c:
01c1bd9c 003c2c8b 01c1bdc0 0001b0fe  00322f4a 01c43a20 01c43b0c
01c8c420 01c1bde8 0001b1b8 003a4ac3 0148 000faa26 0009 
01c1bde0 003a4b6c 01c1bdfc 01c1be20 000faa26 003a4ac3 0148 003a4b6c
01c43a71 01c8c471 01c1 00326430 0043d00c 0005 01c71a00 0020bce0
00322964 01c1be38 000fac04 01c43a20 01c8c420 01c1bee0 01c8c420 01c1be50
000fac4c 01c1bee0  01c43a20  01c1bee8 0020bd26 01c1bee0
Call Trace: [<0001b0fe>] __warn+0xae/0xde
 [<00322f4a>] memcmp+0x0/0x5c
 [<0001b1b8>] warn_slowpath_fmt+0x2e/0x36
 [<000faa26>] proc_register+0xbe/0xd8
 [<000faa26>] proc_register+0xbe/0xd8
 [<00326430>] sprintf+0x0/0x20
 [<0020bce0>] nubus_proc_attach_device+0x0/0x1b8
 [<00322964>] strcpy+0x0/0x22
 [<000fac04>] proc_mkdir_data+0x64/0x96
 [<000fac4c>] proc_mkdir+0x16/0x1c
 [<0020bd26>] nubus_proc_attach_device+0x46/0x1b8
 [<0020bce0>] nubus_proc_attach_device+0x0/0x1b8
 [<00322964>] strcpy+0x0/0x22
 [<1ba6>] kernel_pg_dir+0xba6/0x1000
 [<004339a2>] proc_bus_nubus_add_devices+0x1a/0x2e
 [<000faa40>] proc_create_data+0x0/0xf2
 [<0003297c>] parse_args+0x0/0x2d4
 [<00433a08>] nubus_proc_init+0x52/0x5a
 [<00433944>] nubus_init+0x0/0x44
 [<00433982>] nubus_init+0x3e/0x44
 [<20dc>] do_one_initcall+0x38/0x196
 [<20a4>] do_one_initcall+0x0/0x196
 [<0003297c>] parse_args+0x0/0x2d4
 [<00322964>] strcpy+0x0/0x22
 [<00040004>] __up_read+0xe/0x40
 [<004231d4>] repair_env_string+0x0/0x7a
 [<0042312e>] kernel_init_freeable+0xee/0x194
 [<00423146>] kernel_init_freeable+0x106/0x194
 [<00433944>] nubus_init+0x0/0x44
 [<000a6000>] kfree+0x0/0x156
 [<0032768c>] kernel_init+0x0/0xda
 [<00327698>] kernel_init+0xc/0xda
 [<0032768c>] kernel_init+0x0/0xda
 [<2a90>] ret_from_kernel_thread+0xc/0x14
---[ end trace 14a6d619908ea253 ]---
[ cut here ]

This gets repeated with each additional functional reasource.

The problem here is the call to proc_mkdir() when the directory already
exists. Each nubus_board gets a directory, such as /proc/bus/nubus/s/
where s is the hex slot number. Therefore, store the 'procdir' pointer
in struct nubus_board instead of struct nubus_dev.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/nubus/proc.c  | 6 +-
 include/linux/nubus.h | 5 +++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/nubus/proc.c b/drivers/nubus/proc.c
index fc20dbcd3b9a..91211192f36f 100644
--- a/drivers/nubus/proc.c
+++ b/drivers/nubus/proc.c
@@ -134,9 +134,13 @@ int nubus_proc_attach_device(struct nubus_dev *dev)
return -1;
}

+   if (dev->board->procdir)
+   return 0;
+
/* Create a directory */
snprintf(name, sizeof(name), "%x", dev->board->slot);
-   e = dev->procdir = proc_mkdir(name, proc_bus_nubus_dir);
+   e = proc_mkdir(name, proc_bus_nubus_dir);
+   dev->board->procdir = e;
if (!e)
return -ENOMEM;
 
diff --git a/include/linux/nubus.h b/include/linux/nubus.h
index bffd09a07326..474f304485ec 100644
--- a/include/linux/nubus.h
+++ b/include/linux/nubus.h
@@ -53,13 +53,14 @@ struct nubus_board {
unsigned char rev;
unsigned char format;
unsigned char lanes;
+
+   /* Directory entry in /proc/bus/nubus */
+   struct proc_dir_entry *procdir;
 };
 
 struct nubus_dev {
/* Next link in device list */
struct nubus_dev* next;
-   /* Directory entry in /proc/bus/nubus */
-   struct proc_dir_entry* procdir;
 
/* The functional resource ID of this device */
unsigned char resid;
-- 
2.13.6



[PATCH v3 07/14] nubus: Remove redundant code

2017-12-04 Thread Finn Thain
Eliminate unused values from struct nubus_dev to save wasted memory
(a Radius PrecisionColor 24X card has about 95 functional resources
and up to six such cards may be fitted). Also remove redundant static
variable initialization, an unreachable !MACH_IS_MAC conditional,
the unused nubus_find_device() function, the bogus get_nubus_list()
prototype and the pointless card_present temporary variable.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/nubus/nubus.c | 57 ---
 drivers/nubus/proc.c  |  2 --
 include/linux/nubus.h | 17 +--
 3 files changed, 23 insertions(+), 53 deletions(-)

diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index 2919a5c7321a..041c2be7407f 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -282,23 +282,6 @@ EXPORT_SYMBOL(nubus_rewinddir);
 /* Driver interface functions, more or less like in pci.c */
 
 struct nubus_dev*
-nubus_find_device(unsigned short category, unsigned short type,
- unsigned short dr_hw, unsigned short dr_sw,
- const struct nubus_dev *from)
-{
-   struct nubus_dev *itor = from ? from->next : nubus_devices;
-
-   while (itor) {
-   if (itor->category == category && itor->type == type &&
-   itor->dr_hw == dr_hw && itor->dr_sw == dr_sw)
-   return itor;
-   itor = itor->next;
-   }
-   return NULL;
-}
-EXPORT_SYMBOL(nubus_find_device);
-
-struct nubus_dev*
 nubus_find_type(unsigned short category, unsigned short type,
const struct nubus_dev *from)
 {
@@ -469,8 +452,10 @@ nubus_get_functional_resource(struct nubus_board *board, 
int slot,
}
case NUBUS_RESID_NAME:
{
-   nubus_get_rsrc_str(dev->name, &ent, sizeof(dev->name));
-   pr_debug("name: %s\n", dev->name);
+   char name[64];
+
+   nubus_get_rsrc_str(name, &ent, sizeof(name));
+   pr_debug("name: %s\n", name);
break;
}
case NUBUS_RESID_DRVRDIR:
@@ -479,32 +464,39 @@ nubus_get_functional_resource(struct nubus_board *board, 
int slot,
   use this :-) */
struct nubus_dir drvr_dir;
struct nubus_dirent drvr_ent;
+   unsigned char *driver;
 
nubus_get_subdir(&ent, &drvr_dir);
nubus_readdir(&drvr_dir, &drvr_ent);
-   dev->driver = nubus_dirptr(&drvr_ent);
-   pr_debug("driver at: 0x%p\n", dev->driver);
+   driver = nubus_dirptr(&drvr_ent);
+   pr_debug("driver at: 0x%p\n", driver);
break;
}
case NUBUS_RESID_MINOR_BASEOS:
+   {
/* We will need this in order to support
   multiple framebuffers.  It might be handy
   for Ethernet as well */
-   nubus_get_rsrc_mem(&dev->iobase, &ent, 4);
-   pr_debug("memory offset: 0x%08lx\n", dev->iobase);
+   u32 base_offset;
+
+   nubus_get_rsrc_mem(&base_offset, &ent, 4);
+   pr_debug("memory offset: 0x%08x\n", base_offset);
break;
+   }
case NUBUS_RESID_MINOR_LENGTH:
+   {
/* Ditto */
-   nubus_get_rsrc_mem(&dev->iosize, &ent, 4);
-   pr_debug("memory length: 0x%08lx\n", dev->iosize);
+   u32 length;
+
+   nubus_get_rsrc_mem(&length, &ent, 4);
+   pr_debug("memory length: 0x%08x\n", length);
break;
+   }
case NUBUS_RESID_FLAGS:
-   dev->flags = ent.data;
-   pr_debug("flags: 0x%06x\n", dev->flags);
+   pr_debug("flags: 0x%06x\n", ent.data);
break;
case NUBUS_RESID_HWDEVID:
-   dev->hwdevid = ent.data;
-   pr_debug("hwdevid: 0x%06x\n", dev->hwdevid);
+   pr_debug("hwdevid: 0x%06x\n", ent.data);
break;
default:
/* Local/Private resources have their own
@@ -796,11 +788,8 @@ static void __init nubus_probe_slot(int slot)
 
rp = nubus_rom_addr(slot);
for (i = 4; i; i--) {
-   int card_present;
-
rp--;
-   card_present = hwreg_present(rp);
-   if (!card_present)
+   if (!hwreg_present(rp))
continue;
 

[PATCH v3 12/14] nubus: Adopt standard linked list implementation

2017-12-04 Thread Finn Thain
This increases code re-use and improves readability.

Cc: Bartlomiej Zolnierkiewicz 
Signed-off-by: Finn Thain 
Tested-by: Stan Johnson 
---
 drivers/net/ethernet/8390/mac8390.c |  7 +++--
 drivers/net/ethernet/cirrus/mac89x0.c   |  6 +++--
 drivers/net/ethernet/natsemi/macsonic.c |  8 +++---
 drivers/nubus/nubus.c   | 45 -
 drivers/nubus/proc.c| 11 +++-
 drivers/video/fbdev/macfb.c |  8 +++---
 include/linux/nubus.h   | 15 +--
 7 files changed, 40 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ethernet/8390/mac8390.c 
b/drivers/net/ethernet/8390/mac8390.c
index 929ff6419621..2f91ce8dc614 100644
--- a/drivers/net/ethernet/8390/mac8390.c
+++ b/drivers/net/ethernet/8390/mac8390.c
@@ -416,8 +416,11 @@ struct net_device * __init mac8390_probe(int unit)
if (unit >= 0)
sprintf(dev->name, "eth%d", unit);
 
-   while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET,
-  ndev))) {
+   for_each_func_rsrc(ndev) {
+   if (ndev->category != NUBUS_CAT_NETWORK ||
+   ndev->type != NUBUS_TYPE_ETHERNET)
+   continue;
+
/* Have we seen it already? */
if (slots & (1 << ndev->board->slot))
continue;
diff --git a/drivers/net/ethernet/cirrus/mac89x0.c 
b/drivers/net/ethernet/cirrus/mac89x0.c
index f910f0f386d6..977d4c2c759d 100644
--- a/drivers/net/ethernet/cirrus/mac89x0.c
+++ b/drivers/net/ethernet/cirrus/mac89x0.c
@@ -187,6 +187,7 @@ struct net_device * __init mac89x0_probe(int unit)
unsigned long ioaddr;
unsigned short sig;
int err = -ENODEV;
+   struct nubus_rsrc *fres;
 
if (!MACH_IS_MAC)
return ERR_PTR(-ENODEV);
@@ -207,8 +208,9 @@ struct net_device * __init mac89x0_probe(int unit)
/* We might have to parameterize this later */
slot = 0xE;
/* Get out now if there's a real NuBus card in slot E */
-   if (nubus_find_slot(slot, NULL) != NULL)
-   goto out;
+   for_each_func_rsrc(fres)
+   if (fres->board->slot == slot)
+   goto out;
 
/* The pseudo-ISA bits always live at offset 0x300 (gee,
wonder why...) */
diff --git a/drivers/net/ethernet/natsemi/macsonic.c 
b/drivers/net/ethernet/natsemi/macsonic.c
index 14f3fb50dc21..313fe5e0184b 100644
--- a/drivers/net/ethernet/natsemi/macsonic.c
+++ b/drivers/net/ethernet/natsemi/macsonic.c
@@ -464,9 +464,11 @@ static int mac_nubus_sonic_probe(struct net_device *dev)
int reg_offset, dma_bitmode;
 
/* Find the first SONIC that hasn't been initialized already */
-   while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK,
-  NUBUS_TYPE_ETHERNET, ndev)) != NULL)
-   {
+   for_each_func_rsrc(ndev) {
+   if (ndev->category != NUBUS_CAT_NETWORK ||
+   ndev->type != NUBUS_TYPE_ETHERNET)
+   continue;
+
/* Have we seen it already? */
if (slots & (1slot))
continue;
diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index 324f6e4407c8..380f320c050f 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -32,7 +32,7 @@
 
 /* Globals */
 
-struct nubus_rsrc *nubus_func_rsrcs;
+LIST_HEAD(nubus_func_rsrcs);
 struct nubus_board *nubus_boards;
 
 /* Meaning of "bytelanes":
@@ -305,33 +305,20 @@ EXPORT_SYMBOL(nubus_rewinddir);
 
 /* Driver interface functions, more or less like in pci.c */
 
-struct nubus_rsrc *nubus_find_type(unsigned short category, unsigned short 
type,
-   const struct nubus_rsrc *from)
+struct nubus_rsrc *nubus_first_rsrc_or_null(void)
 {
-   struct nubus_rsrc *itor = from ? from->next : nubus_func_rsrcs;
-
-   while (itor) {
-   if (itor->category == category && itor->type == type)
-   return itor;
-   itor = itor->next;
-   }
-   return NULL;
+   return list_first_entry_or_null(&nubus_func_rsrcs, struct nubus_rsrc,
+   list);
 }
-EXPORT_SYMBOL(nubus_find_type);
+EXPORT_SYMBOL(nubus_first_rsrc_or_null);
 
-struct nubus_rsrc *nubus_find_slot(unsigned int slot,
-   const struct nubus_rsrc *from)
+struct nubus_rsrc *nubus_next_rsrc_or_null(struct nubus_rsrc *from)
 {
-   struct nubus_rsrc *itor = from ? from->next : nubus_func_rsrcs;
-
-   while (itor) {
-   if (itor->board->slot == slot)
-   return itor;
-   itor = itor->next;
-   }
-   return NULL;
+   if (list_is_last(&from->list, &nubus_func_rsrcs))
+   return NULL;
+   return list_next_entry(from, list);
 }
-EXPORT_SYMBOL(nubus_find_slot);
+EXPORT_SYMBOL(

[PATCH v3 05/14] nubus: Validate slot resource IDs

2017-12-04 Thread Finn Thain
While we are here, include the slot number in the related error messages.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/nubus/nubus.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index 2475b48c29d4..2919a5c7321a 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -616,7 +616,7 @@ static int __init nubus_get_board_resource(struct 
nubus_board *board, int slot,
nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
nbtdata[2] != 0 || nbtdata[3] != 0)
-   pr_err("this sResource is not a board 
resource!\n");
+   pr_err("Slot %X: sResource is not a board 
resource!\n", slot);
break;
}
case NUBUS_RESID_NAME:
@@ -671,6 +671,7 @@ static struct nubus_board * __init nubus_add_board(int 
slot, int bytelanes)
unsigned long dpat;
struct nubus_dir dir;
struct nubus_dirent ent;
+   int prev_resid = -1;
 
/* Move to the start of the format block */
rp = nubus_rom_addr(slot);
@@ -710,10 +711,10 @@ static struct nubus_board * __init nubus_add_board(int 
slot, int bytelanes)
 
/* Directory offset should be small and negative... */
if (!(board->doffset & 0x00FF))
-   pr_warn("Dodgy doffset!\n");
+   pr_warn("Slot %X: Dodgy doffset!\n", slot);
dpat = nubus_get_rom(&rp, 4, bytelanes);
if (dpat != NUBUS_TEST_PATTERN)
-   pr_warn("Wrong test pattern %08lx!\n", dpat);
+   pr_warn("Slot %X: Wrong test pattern %08lx!\n", slot, dpat);
 
/*
 *  I wonder how the CRC is meant to work -
@@ -739,12 +740,15 @@ static struct nubus_board * __init nubus_add_board(int 
slot, int bytelanes)
   for each of them. */
if (nubus_readdir(&dir, &ent) == -1) {
/* We can't have this! */
-   pr_err("Board resource not found!\n");
+   pr_err("Slot %X: Board resource not found!\n", slot);
return NULL;
-   } else {
-   nubus_get_board_resource(board, slot, &ent);
}
 
+   if (ent.type < 1 || ent.type > 127)
+   pr_warn("Slot %X: Board resource ID is invalid!\n", slot);
+
+   nubus_get_board_resource(board, slot, &ent);
+
while (nubus_readdir(&dir, &ent) != -1) {
struct nubus_dev *dev;
struct nubus_dev **devp;
@@ -753,6 +757,15 @@ static struct nubus_board * __init nubus_add_board(int 
slot, int bytelanes)
if (dev == NULL)
continue;
 
+   /* Resources should appear in ascending ID order. This sanity
+* check prevents duplicate resource IDs.
+*/
+   if (dev->resid <= prev_resid) {
+   kfree(dev);
+   continue;
+   }
+   prev_resid = dev->resid;
+
/* We zeroed this out above */
if (board->first_dev == NULL)
board->first_dev = dev;
-- 
2.13.6



[PATCH 1/2] KVM: MMU: Fix infinite loop when there is no available mmu page

2017-12-04 Thread Wanpeng Li
From: Wanpeng Li 

The below test case can cause infinite loop in kvm when ept=0.

#include 
#include 
#include 
#include 
#include 
#include 
#include 

long r[5];
int main()
{
r[2] = open("/dev/kvm", O_RDONLY);
r[3] = ioctl(r[2], KVM_CREATE_VM, 0);
r[4] = ioctl(r[3], KVM_CREATE_VCPU, 7);
ioctl(r[4], KVM_RUN, 0);
}

It doesn't setup the memory regions, mmu_alloc_shadow/direct_roots() in 
kvm return 1 when kvm fails to allocate root page table which can result 
in beblow infinite loop:

vcpu_run() {
for (;;) {
r = vcpu_enter_guest()::kvm_mmu_reload() returns 1 
if (r <= 0)
break;
if (need_resched())
cond_resched();
  }
}

This patch fixes it by returning -ENOSPC when there is no available kvm mmu 
page for root page table.

Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Fixes: 26eeb53cf0f (KVM: MMU: Bail out immediately if there is no available mmu 
page)
Signed-off-by: Wanpeng Li 
---
 arch/x86/kvm/mmu.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index c9aaa18..89da688 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -3395,7 +3395,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
spin_lock(&vcpu->kvm->mmu_lock);
if(make_mmu_pages_available(vcpu) < 0) {
spin_unlock(&vcpu->kvm->mmu_lock);
-   return 1;
+   return -ENOSPC;
}
sp = kvm_mmu_get_page(vcpu, 0, 0,
vcpu->arch.mmu.shadow_root_level, 1, ACC_ALL);
@@ -3410,7 +3410,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
spin_lock(&vcpu->kvm->mmu_lock);
if (make_mmu_pages_available(vcpu) < 0) {
spin_unlock(&vcpu->kvm->mmu_lock);
-   return 1;
+   return -ENOSPC;
}
sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT),
i << 30, PT32_ROOT_LEVEL, 1, ACC_ALL);
@@ -3450,7 +3450,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
spin_lock(&vcpu->kvm->mmu_lock);
if (make_mmu_pages_available(vcpu) < 0) {
spin_unlock(&vcpu->kvm->mmu_lock);
-   return 1;
+   return -ENOSPC;
}
sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
vcpu->arch.mmu.shadow_root_level, 0, ACC_ALL);
@@ -3487,7 +3487,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
spin_lock(&vcpu->kvm->mmu_lock);
if (make_mmu_pages_available(vcpu) < 0) {
spin_unlock(&vcpu->kvm->mmu_lock);
-   return 1;
+   return -ENOSPC;
}
sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL,
  0, ACC_ALL);
-- 
2.7.4



[PATCH 2/2] KVM: X86: Fix load RFLAGS w/o the fixed bit

2017-12-04 Thread Wanpeng Li
From: Wanpeng Li 

 *** Guest State ***
 CR0: actual=0x0030, shadow=0x6010, 
gh_mask=fff7
 CR4: actual=0x2050, shadow=0x, 
gh_mask=e871
 CR3 = 0xfffbc000
 RSP = 0x  RIP = 0x
 RFLAGS=0x DR7 = 0x0400
^^

The failed vmentry is triggered by the following testcase when ept=Y:

#include 
#include 
#include 
#include 
#include 
#include 
#include 

long r[5];
int main()
{
r[2] = open("/dev/kvm", O_RDONLY);
r[3] = ioctl(r[2], KVM_CREATE_VM, 0);
r[4] = ioctl(r[3], KVM_CREATE_VCPU, 7);
struct kvm_regs regs = {
.rflags = 0,
};
ioctl(r[4], KVM_SET_REGS, ®s);
ioctl(r[4], KVM_RUN, 0);
}

X86 RFLAGS bit 1 is fixed set, userspace can simply clearing bit 1 
of RFLAGS with KVM_SET_REGS ioctl which results in vmentry fails.
This patch fixes it by catching userspace set RFLAGS w/o the fixes 
bit and bailing out immediately.

Suggested-by: Jim Mattson 
Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Cc: Jim Mattson 
Signed-off-by: Wanpeng Li 
---
 virt/kvm/kvm_main.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index c01cff0..7100833 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2602,6 +2602,11 @@ static long kvm_vcpu_ioctl(struct file *filp,
r = PTR_ERR(kvm_regs);
goto out;
}
+   r = -EINVAL;
+   if (!(kvm_regs->rflags & X86_EFLAGS_FIXED)) {
+   kfree(kvm_regs);
+   goto out;
+   }
r = kvm_arch_vcpu_ioctl_set_regs(vcpu, kvm_regs);
kfree(kvm_regs);
break;
-- 
2.7.4



[PATCH v3 13/14] nubus: Add expansion_type values for various Mac models

2017-12-04 Thread Finn Thain
Add an expansion slot attribute to allow drivers to properly handle
cards like Comm Slot cards and PDS cards without declaration ROMs.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 arch/m68k/include/asm/macintosh.h   |   9 ++-
 arch/m68k/mac/config.c  | 110 +---
 drivers/net/ethernet/natsemi/macsonic.c |   8 +--
 3 files changed, 54 insertions(+), 73 deletions(-)

diff --git a/arch/m68k/include/asm/macintosh.h 
b/arch/m68k/include/asm/macintosh.h
index f42c27400dbc..9b840c03ebb7 100644
--- a/arch/m68k/include/asm/macintosh.h
+++ b/arch/m68k/include/asm/macintosh.h
@@ -33,7 +33,7 @@ struct mac_model
char ide_type;
char scc_type;
char ether_type;
-   char nubus_type;
+   char expansion_type;
char floppy_type;
 };
 
@@ -73,8 +73,11 @@ struct mac_model
 #define MAC_ETHER_SONIC1
 #define MAC_ETHER_MACE 2
 
-#define MAC_NO_NUBUS   0
-#define MAC_NUBUS  1
+#define MAC_EXP_NONE   0
+#define MAC_EXP_PDS1 /* Accepts only a PDS card */
+#define MAC_EXP_NUBUS  2 /* Accepts only NuBus card(s) */
+#define MAC_EXP_PDS_NUBUS  3 /* Accepts PDS card and/or NuBus card(s) */
+#define MAC_EXP_PDS_COMM   4 /* Accepts PDS card or Comm Slot card */
 
 #define MAC_FLOPPY_IWM 0
 #define MAC_FLOPPY_SWIM_ADDR1  1
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 16cd5cea5207..d3d435248a24 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -212,7 +212,7 @@ static struct mac_model mac_data_table[] = {
.via_type   = MAC_VIA_II,
.scsi_type  = MAC_SCSI_OLD,
.scc_type   = MAC_SCC_II,
-   .nubus_type = MAC_NUBUS,
+   .expansion_type = MAC_EXP_NUBUS,
.floppy_type= MAC_FLOPPY_IWM,
},
 
@@ -227,7 +227,7 @@ static struct mac_model mac_data_table[] = {
.via_type   = MAC_VIA_II,
.scsi_type  = MAC_SCSI_OLD,
.scc_type   = MAC_SCC_II,
-   .nubus_type = MAC_NUBUS,
+   .expansion_type = MAC_EXP_NUBUS,
.floppy_type= MAC_FLOPPY_IWM,
}, {
.ident  = MAC_MODEL_IIX,
@@ -236,7 +236,7 @@ static struct mac_model mac_data_table[] = {
.via_type   = MAC_VIA_II,
.scsi_type  = MAC_SCSI_OLD,
.scc_type   = MAC_SCC_II,
-   .nubus_type = MAC_NUBUS,
+   .expansion_type = MAC_EXP_NUBUS,
.floppy_type= MAC_FLOPPY_SWIM_ADDR2,
}, {
.ident  = MAC_MODEL_IICX,
@@ -245,7 +245,7 @@ static struct mac_model mac_data_table[] = {
.via_type   = MAC_VIA_II,
.scsi_type  = MAC_SCSI_OLD,
.scc_type   = MAC_SCC_II,
-   .nubus_type = MAC_NUBUS,
+   .expansion_type = MAC_EXP_NUBUS,
.floppy_type= MAC_FLOPPY_SWIM_ADDR2,
}, {
.ident  = MAC_MODEL_SE30,
@@ -254,7 +254,7 @@ static struct mac_model mac_data_table[] = {
.via_type   = MAC_VIA_II,
.scsi_type  = MAC_SCSI_OLD,
.scc_type   = MAC_SCC_II,
-   .nubus_type = MAC_NUBUS,
+   .expansion_type = MAC_EXP_PDS,
.floppy_type= MAC_FLOPPY_SWIM_ADDR2,
},
 
@@ -272,7 +272,7 @@ static struct mac_model mac_data_table[] = {
.via_type   = MAC_VIA_IICI,
.scsi_type  = MAC_SCSI_OLD,
.scc_type   = MAC_SCC_II,
-   .nubus_type = MAC_NUBUS,
+   .expansion_type = MAC_EXP_NUBUS,
.floppy_type= MAC_FLOPPY_SWIM_ADDR2,
}, {
.ident  = MAC_MODEL_IIFX,
@@ -281,7 +281,7 @@ static struct mac_model mac_data_table[] = {
.via_type   = MAC_VIA_IICI,
.scsi_type  = MAC_SCSI_IIFX,
.scc_type   = MAC_SCC_IOP,
-   .nubus_type = MAC_NUBUS,
+   .expansion_type = MAC_EXP_PDS_NUBUS,
.floppy_type= MAC_FLOPPY_SWIM_IOP,
}, {
.ident  = MAC_MODEL_IISI,
@@ -290,7 +290,7 @@ static struct mac_model mac_data_table[] = {
.via_type   = MAC_VIA_IICI,
.scsi_type  = MAC_SCSI_OLD,
.scc_type   = MAC_SCC_II,
-   .nubus_type = MAC_NUBUS,
+   .expansion_type = MAC_EXP_PDS_NUBUS,
.floppy_type= MAC_FLOPPY_SWIM_ADDR2,
}, {
.ident  = MAC_MODEL_IIVI,
@@ -299,7 +299,7 @@ static struct mac_model mac_data_table[] = {
.via_type   = MAC_VIA_IICI,
.scsi_type  = MAC_SCSI_LC,
.scc_type   = MAC_

[PATCH v3 14/14] nubus: Add support for the driver model

2017-12-04 Thread Finn Thain
This patch brings basic support for the Linux Driver Model to the
NuBus subsystem.

For flexibility, the matching of boards with drivers is left up to the
drivers. This is also the approach taken by NetBSD. A board may have
many functions, and drivers may have to consider many functional
resources and board resources in order to match a device.

This implementation does not bind drivers to resources (nor does it bind
many drivers to the same board). Apple's NuBus declaration ROM design
is flexible enough to allow that, but I don't see a need to support it
as we don't use the "slot zero" resources (in the main logic board ROM).

Eliminate the global nubus_boards linked list by rewriting the procfs
board iterator around bus_for_each_dev(). Hence the nubus device refcount
can be used to determine the lifespan of board objects.

Cc: Greg Kroah-Hartman 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 

---
The conversion of Mac network drivers from the Space.c convention to
the Driver Model takes place in a separate patch series, archived at
https://lkml.org/lkml/2017/11/11/25
That series motivates parts of this design, such as the definition of
'for_each_board_func_rsrc'.
---
 drivers/nubus/Makefile |   2 +-
 drivers/nubus/bus.c| 119 +
 drivers/nubus/nubus.c  |  24 +-
 drivers/nubus/proc.c   |  55 +--
 include/linux/nubus.h  |  33 --
 5 files changed, 163 insertions(+), 70 deletions(-)
 create mode 100644 drivers/nubus/bus.c

diff --git a/drivers/nubus/Makefile b/drivers/nubus/Makefile
index 21bda2031e7e..6d063cde39d1 100644
--- a/drivers/nubus/Makefile
+++ b/drivers/nubus/Makefile
@@ -2,6 +2,6 @@
 # Makefile for the nubus specific drivers.
 #
 
-obj-y   := nubus.o
+obj-y := nubus.o bus.o
 
 obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/drivers/nubus/bus.c b/drivers/nubus/bus.c
new file mode 100644
index ..b5045e639b4d
--- /dev/null
+++ b/drivers/nubus/bus.c
@@ -0,0 +1,119 @@
+/*
+ * Bus implementation for the NuBus subsystem.
+ *
+ * Copyright (C) 2017 Finn Thain
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define to_nubus_board(d)   container_of(d, struct nubus_board, dev)
+#define to_nubus_driver(d)  container_of(d, struct nubus_driver, driver)
+
+static int nubus_bus_match(struct device *dev, struct device_driver *driver)
+{
+   return 1;
+}
+
+static int nubus_device_probe(struct device *dev)
+{
+   struct nubus_driver *ndrv = to_nubus_driver(dev->driver);
+   int err = -ENODEV;
+
+   if (ndrv->probe)
+   err = ndrv->probe(to_nubus_board(dev));
+   return err;
+}
+
+static int nubus_device_remove(struct device *dev)
+{
+   struct nubus_driver *ndrv = to_nubus_driver(dev->driver);
+   int err = -ENODEV;
+
+   if (dev->driver && ndrv->remove)
+   err = ndrv->remove(to_nubus_board(dev));
+   return err;
+}
+
+struct bus_type nubus_bus_type = {
+   .name   = "nubus",
+   .match  = nubus_bus_match,
+   .probe  = nubus_device_probe,
+   .remove = nubus_device_remove,
+};
+EXPORT_SYMBOL(nubus_bus_type);
+
+int nubus_driver_register(struct nubus_driver *ndrv)
+{
+   ndrv->driver.bus = &nubus_bus_type;
+   return driver_register(&ndrv->driver);
+}
+EXPORT_SYMBOL(nubus_driver_register);
+
+void nubus_driver_unregister(struct nubus_driver *ndrv)
+{
+   driver_unregister(&ndrv->driver);
+}
+EXPORT_SYMBOL(nubus_driver_unregister);
+
+static struct device nubus_parent = {
+   .init_name  = "nubus",
+};
+
+int __init nubus_bus_register(void)
+{
+   int err;
+
+   err = device_register(&nubus_parent);
+   if (err)
+   return err;
+
+   err = bus_register(&nubus_bus_type);
+   if (!err)
+   return 0;
+
+   device_unregister(&nubus_parent);
+   return err;
+}
+
+static void nubus_device_release(struct device *dev)
+{
+   struct nubus_board *board = to_nubus_board(dev);
+   struct nubus_rsrc *fres, *tmp;
+
+   list_for_each_entry_safe(fres, tmp, &nubus_func_rsrcs, list)
+   if (fres->board == board) {
+   list_del(&fres->list);
+   kfree(fres);
+   }
+   kfree(board);
+}
+
+int nubus_device_register(struct nubus_board *board)
+{
+   board->dev.parent = &nubus_parent;
+   board->dev.release = nubus_device_release;
+   board->dev.bus = &nubus_bus_type;
+   dev_set_name(&board->dev, "slot.%X", board->slot);
+   return device_register(&board->dev);
+}
+
+static int nubus_print_device_name_fn(struct device *dev, void *data)
+{
+   struct nubus_board *board = to_nubus_board(dev);
+   struct seq_file *m = data;
+
+   seq_printf(m, "Slot %X: %s\n", board->slot, board->name);
+   return 0;
+}
+
+int nubus_proc_show(struct seq_file *m, void *data)
+{
+   return bus_f

[PATCH v3 03/14] nubus: Use static functions where possible

2017-12-04 Thread Finn Thain
This fixes a couple of warnings from 'make W=1':
drivers/nubus/nubus.c:790: warning: no previous prototype for 'nubus_probe_slot'
drivers/nubus/nubus.c:824: warning: no previous prototype for 'nubus_scan_bus'

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/nubus/nubus.c | 4 ++--
 include/linux/nubus.h | 1 -
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index 566dc563e7e8..3c1d386a4640 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -793,7 +793,7 @@ static struct nubus_board * __init nubus_add_board(int 
slot, int bytelanes)
return board;
 }
 
-void __init nubus_probe_slot(int slot)
+static void __init nubus_probe_slot(int slot)
 {
unsigned char dp;
unsigned char *rp;
@@ -827,7 +827,7 @@ void __init nubus_probe_slot(int slot)
}
 }
 
-void __init nubus_scan_bus(void)
+static void __init nubus_scan_bus(void)
 {
int slot;
 
diff --git a/include/linux/nubus.h b/include/linux/nubus.h
index a6edf7838e22..bffd09a07326 100644
--- a/include/linux/nubus.h
+++ b/include/linux/nubus.h
@@ -92,7 +92,6 @@ extern struct nubus_dev* nubus_devices;
 extern struct nubus_board* nubus_boards;
 
 /* Generic NuBus interface functions, modelled after the PCI interface */
-void nubus_scan_bus(void);
 #ifdef CONFIG_PROC_FS
 extern void nubus_proc_init(void);
 #else
-- 
2.13.6



[PATCH v3 01/14] nubus: Avoid array underflow and overflow

2017-12-04 Thread Finn Thain
Check array indices. Avoid sprintf. Use buffers of sufficient size.
Use appropriate types for array length parameters.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/nubus/nubus.c | 29 +
 drivers/nubus/proc.c  | 12 ++--
 include/linux/nubus.h | 10 --
 3 files changed, 27 insertions(+), 24 deletions(-)

diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index b793727cd4f7..566dc563e7e8 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -161,7 +161,7 @@ static unsigned char *nubus_dirptr(const struct 
nubus_dirent *nd)
pointed to with offsets) out of the card ROM. */
 
 void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
-   int len)
+unsigned int len)
 {
unsigned char *t = (unsigned char *)dest;
unsigned char *p = nubus_dirptr(dirent);
@@ -173,18 +173,22 @@ void nubus_get_rsrc_mem(void *dest, const struct 
nubus_dirent *dirent,
 }
 EXPORT_SYMBOL(nubus_get_rsrc_mem);
 
-void nubus_get_rsrc_str(void *dest, const struct nubus_dirent *dirent,
-   int len)
+void nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
+unsigned int len)
 {
-   unsigned char *t = (unsigned char *)dest;
+   char *t = dest;
unsigned char *p = nubus_dirptr(dirent);
 
-   while (len) {
-   *t = nubus_get_rom(&p, 1, dirent->mask);
-   if (!*t++)
+   while (len > 1) {
+   unsigned char c = nubus_get_rom(&p, 1, dirent->mask);
+
+   if (!c)
break;
+   *t++ = c;
len--;
}
+   if (len > 0)
+   *t = '\0';
 }
 EXPORT_SYMBOL(nubus_get_rsrc_str);
 
@@ -468,7 +472,7 @@ nubus_get_functional_resource(struct nubus_board *board, 
int slot,
}
case NUBUS_RESID_NAME:
{
-   nubus_get_rsrc_str(dev->name, &ent, 64);
+   nubus_get_rsrc_str(dev->name, &ent, sizeof(dev->name));
pr_info("name: %s\n", dev->name);
break;
}
@@ -528,7 +532,7 @@ static int __init nubus_get_vidnames(struct nubus_board 
*board,
/* Don't know what this is yet */
u16 id;
/* Longest one I've seen so far is 26 characters */
-   char name[32];
+   char name[36];
};
 
pr_info("video modes supported:\n");
@@ -598,8 +602,8 @@ static int __init nubus_get_vendorinfo(struct nubus_board 
*board,
char name[64];
 
/* These are all strings, we think */
-   nubus_get_rsrc_str(name, &ent, 64);
-   if (ent.type > 5)
+   nubus_get_rsrc_str(name, &ent, sizeof(name));
+   if (ent.type < 1 || ent.type > 5)
ent.type = 5;
pr_info("%s: %s\n", vendor_fields[ent.type - 1], name);
}
@@ -633,7 +637,8 @@ static int __init nubus_get_board_resource(struct 
nubus_board *board, int slot,
break;
}
case NUBUS_RESID_NAME:
-   nubus_get_rsrc_str(board->name, &ent, 64);
+   nubus_get_rsrc_str(board->name, &ent,
+  sizeof(board->name));
pr_info("name: %s\n", board->name);
break;
case NUBUS_RESID_ICON:
diff --git a/drivers/nubus/proc.c b/drivers/nubus/proc.c
index 004a122ac0ff..fc20dbcd3b9a 100644
--- a/drivers/nubus/proc.c
+++ b/drivers/nubus/proc.c
@@ -73,10 +73,10 @@ static void nubus_proc_subdir(struct nubus_dev* dev,
 
/* Some of these are directories, others aren't */
while (nubus_readdir(dir, &ent) != -1) {
-   char name[8];
+   char name[9];
struct proc_dir_entry* e;

-   sprintf(name, "%x", ent.type);
+   snprintf(name, sizeof(name), "%x", ent.type);
e = proc_create(name, S_IFREG | S_IRUGO | S_IWUSR, parent,
&nubus_proc_subdir_fops);
if (!e)
@@ -95,11 +95,11 @@ static void nubus_proc_populate(struct nubus_dev* dev,
/* We know these are all directories (board resource + one or
   more functional resources) */
while (nubus_readdir(root, &ent) != -1) {
-   char name[8];
+   char name[9];
struct proc_dir_entry* e;
struct nubus_dir dir;

-   sprintf(name, "%x", ent.type);
+   snprintf(name, sizeof(name), "%x", ent.type);
e = proc_mkdir(name, parent);
if (!e) return;
 
@@ -119,7 +119,7 @@ int nubus_proc_attach_device(struct nubus_dev *dev)
 {
struct proc_dir_entry *e;
  

[PATCH v3 02/14] nubus: Fix up header split

2017-12-04 Thread Finn Thain
Due to the '#ifdef __KERNEL__' being located in the wrong place, some
definitions from the kernel API were placed in the UAPI header during
the scripted header split. Fix this. Also, remove the duplicate comment
which is only relevant to the UAPI header.

Fixes: 607ca46e97a1 ("UAPI: (Scripted) Disintegrate include/linux")
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 include/linux/nubus.h  | 27 +++
 include/uapi/linux/nubus.h | 23 ---
 2 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/include/linux/nubus.h b/include/linux/nubus.h
index 18c300222362..a6edf7838e22 100644
--- a/include/linux/nubus.h
+++ b/include/linux/nubus.h
@@ -5,16 +5,28 @@
   Originally written by Alan Cox.
 
   Hacked to death by C. Scott Ananian and David Huggins-Daines.
-  
-  Some of the constants in here are from the corresponding
-  NetBSD/OpenBSD header file, by Allen Briggs.  We figured out the
-  rest of them on our own. */
+*/
+
 #ifndef LINUX_NUBUS_H
 #define LINUX_NUBUS_H
 
 #include 
 #include 
 
+struct nubus_dir {
+   unsigned char *base;
+   unsigned char *ptr;
+   int done;
+   int mask;
+};
+
+struct nubus_dirent {
+   unsigned char *base;
+   unsigned char type;
+   __u32 data; /* Actually 24 bits used */
+   int mask;
+};
+
 struct nubus_board {
struct nubus_board* next;
struct nubus_dev* first_dev;
@@ -130,4 +142,11 @@ void nubus_get_rsrc_mem(void *dest, const struct 
nubus_dirent *dirent,
 unsigned int len);
 void nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
 unsigned int maxlen);
+
+/* Returns a pointer to the "standard" slot space. */
+static inline void *nubus_slot_addr(int slot)
+{
+   return (void *)(0xF000 | (slot << 24));
+}
+
 #endif /* LINUX_NUBUS_H */
diff --git a/include/uapi/linux/nubus.h b/include/uapi/linux/nubus.h
index f3776cc80f4d..48031e7858f1 100644
--- a/include/uapi/linux/nubus.h
+++ b/include/uapi/linux/nubus.h
@@ -221,27 +221,4 @@ enum nubus_display_res_id {
NUBUS_RESID_SIXTHMODE   = 0x0085
 };
 
-struct nubus_dir
-{
-   unsigned char *base;
-   unsigned char *ptr;
-   int done;
-   int mask;
-};
-
-struct nubus_dirent
-{
-   unsigned char *base;
-   unsigned char type;
-   __u32 data; /* Actually 24bits used */
-   int mask;
-};
-
-
-/* We'd like to get rid of this eventually.  Only daynaport.c uses it now. */
-static inline void *nubus_slot_addr(int slot)
-{
-   return (void *)(0xF000|(slot<<24));
-}
-
 #endif /* _UAPILINUX_NUBUS_H */
-- 
2.13.6



[PATCH v3 00/14] Modernization and fixes for NuBus subsystem

2017-12-04 Thread Finn Thain
This series begins with cleanups and fixes for the NuBus subsystem and
finishes with a patch to add support for the Linux Driver Model.
The next series, which requires this one, modernizes the NuBus drivers.

Changes since v1:
- Added the missing NULL check in nubus_device_remove().
- Squashed the two /proc/bus/nubus/s/ patches into one patch.
- Combined the two sets of /proc/bus/nubus file operations into one set.
- Used the name 'nubus_rsrc' instead of 'nubus_functional_resource'.
- Used the name 'nubus_device_register' instead of 'nubus_device_add'.
- Dropped the unused EXPORT_SYMBOL(nubus_seq_write_rsrc_mem).
- Replaced licensing text in the new file with SPDX-License-Identifier.

Changes since v2:
- Implemented an idiomatic device release function for nubus boards.
- Removed the global nubus_boards linked list.
- Removed nubus_board pointer from proc dir entry private data to improve
  modularity.
- Adopted the standard linked list implementation.
- Disambiguated unrecognized and empty resources under /proc/bus/nubus.
- Reduced redundancy in proc dir entry private data to save some memory.
- Replaced /proc/nubus custom seq file ops with single_open().


Finn Thain (14):
  nubus: Avoid array underflow and overflow
  nubus: Fix up header split
  nubus: Use static functions where possible
  nubus: Fix log spam
  nubus: Validate slot resource IDs
  nubus: Call proc_mkdir() not more than once per slot directory
  nubus: Remove redundant code
  nubus: Clean up whitespace
  nubus: Generalize block resource handling
  nubus: Rework /proc/bus/nubus/s/ implementation
  nubus: Rename struct nubus_dev
  nubus: Adopt standard linked list implementation
  nubus: Add expansion_type values for various Mac models
  nubus: Add support for the driver model

 arch/m68k/include/asm/macintosh.h   |   9 +-
 arch/m68k/mac/config.c  | 110 +++
 drivers/net/ethernet/8390/mac8390.c |  33 +-
 drivers/net/ethernet/cirrus/mac89x0.c   |   6 +-
 drivers/net/ethernet/natsemi/macsonic.c |  38 ++-
 drivers/nubus/Makefile  |   2 +-
 drivers/nubus/bus.c | 119 +++
 drivers/nubus/nubus.c   | 544 +---
 drivers/nubus/proc.c| 282 -
 drivers/video/fbdev/macfb.c |  10 +-
 include/linux/nubus.h   | 185 +++
 include/uapi/linux/nubus.h  |  23 --
 12 files changed, 763 insertions(+), 598 deletions(-)
 create mode 100644 drivers/nubus/bus.c

-- 
2.13.6



Re: [PATCH v2 0/4] lockdep/crossrelease: Apply crossrelease to page locks

2017-12-04 Thread Byungchul Park

On 12/5/2017 2:46 PM, Byungchul Park wrote:

On 12/5/2017 2:30 PM, Matthew Wilcox wrote:

On Mon, Dec 04, 2017 at 02:16:19PM +0900, Byungchul Park wrote:

For now, wait_for_completion() / complete() works with lockdep, add
lock_page() / unlock_page() and its family to lockdep support.

Changes from v1
  - Move lockdep_map_cross outside of page_ext to make it flexible
  - Prevent allocating lockdep_map per page by default
  - Add a boot parameter allowing the allocation for debugging

Byungchul Park (4):
   lockdep: Apply crossrelease to PG_locked locks
   lockdep: Apply lock_acquire(release) on __Set(__Clear)PageLocked
   lockdep: Move data of CONFIG_LOCKDEP_PAGELOCK from page to page_ext
   lockdep: Add a boot parameter enabling to track page locks using
 lockdep and disable it by default


I don't like the way you've structured this patch series; first adding
the lockdep map to struct page, then moving it to page_ext.


Hello,

I will make them into one patch.


I've thought it more.

Actually I did it because I thought I'd better make it into two
patches since it makes reviewers easier to review. It doesn't matter
which one I choose, but I prefer to split it.

But, if you are strongly against it, then I will follow you.

--
Thanks,
Byungchul


Re: Regression in e1000e since Kernel 4.14.3

2017-12-04 Thread Greg KH
On Tue, Dec 05, 2017 at 07:18:34AM +0100, Greg KH wrote:
> On Tue, Dec 05, 2017 at 12:47:10AM +0100, Gabriel C wrote:
> > On 04.12.2017 23:10, rwar...@gmx.de wrote:
> > 
> > > Hallo
> > > 
> > > someone and I got an regression with e1000e since kernel 4.14.3 and it 
> > > seems there is 4.14.4 on the way without a fix.
> > > 
> > > 
> > > bug report is here:
> > > 
> > > https://bugzilla.kernel.org/show_bug.cgi?id=198047
> > 
> > ( added stable and netdev to CC )
> > 
> > Yes I have a box with e1000e and it seems something at least breaks NM 
> > after 4.14.3.
> 
> Again, can people try 4.14.5-rc1?  It should be resolved there.

Oops, that would be 4.14.4-rc1.  Any why do you say above that is on the
way without a fix, did you test it?

thanks,

greg k-h


Re: PROBLEM: Asus C201 video mode problems on HDMI hotplug (regression)

2017-12-04 Thread Nick Bowler
On 2017-12-04 13:33 -0500, Nick Bowler wrote:
> On 2017-12-04 10:04 +, Jose Abreu wrote:
> > Hmmm, my first thought was that audio is being configured first
> > because of the phy lock wait time, I've seen this happening before.
> >
> > Lets try this:
> > - Disable all alsa clients (e.g. pulseaudio, ...) so that no one
> > tries to configure audio.
> > - Plug out/in the cable until the issue appears
> > - When the issue appears use aplay to play audio through the HDMI
> > output
> > - Repeat several times with different audio rates and with no
> > resample (you can use the plughw interface in aplay).
> 
> OK, I will give it a try later this evening.

Using the above sequence on unpatched 4.15-rc1 it seems there is no
sound when starting audio output after the pink bar is visible.

However I am not confident of the results here, restarting aplay
with different sample rates (or even restarting with the same rate)
is causing some weird effects on my setup so I want to check the test
setup with some different source devices.

Cheers,
  Nick


Re: Regression in e1000e since Kernel 4.14.3

2017-12-04 Thread Greg KH
On Tue, Dec 05, 2017 at 12:47:10AM +0100, Gabriel C wrote:
> On 04.12.2017 23:10, rwar...@gmx.de wrote:
> 
> > Hallo
> > 
> > someone and I got an regression with e1000e since kernel 4.14.3 and it 
> > seems there is 4.14.4 on the way without a fix.
> > 
> > 
> > bug report is here:
> > 
> > https://bugzilla.kernel.org/show_bug.cgi?id=198047
> 
> ( added stable and netdev to CC )
> 
> Yes I have a box with e1000e and it seems something at least breaks NM after 
> 4.14.3.

Again, can people try 4.14.5-rc1?  It should be resolved there.

thanks,

greg k-h


Re: [PATCH] thermal: tegra: delete unneeded of_node_put

2017-12-04 Thread Julia Lawall


On Mon, 4 Dec 2017, Eduardo Valentin wrote:

> On Mon, Jul 17, 2017 at 04:42:38PM +0200, Julia Lawall wrote:
> >
> >
> > On Mon, 17 Jul 2017, Jon Hunter wrote:
> >
> > >
> > > On 15/07/17 09:42, Julia Lawall wrote:
> > > > Device node iterators perform an of_node_put on each iteration, so 
> > > > putting
> > > > an of_node_put before a continue results in a double put.
> > > >
> > > > The semantic match that finds this problem is as follows
> > > > (http://coccinelle.lip6.fr):
> > > >
> > > > // 
> > > > @@
> > > > expression e1;
> > > > local idexpression child;
> > > > iterator name for_each_child_of_node;
> > > > @@
> > > >
> > > >  for_each_child_of_node(e1,child) {
> > > >... when != of_node_get(child)
> > > > *  of_node_put(child);
> > > >...
> > > > *  continue;
> > > > }
> > > > // 
> > > >
> > > > Furthermore, the call to thermal_of_cooling_device_register immediately
> > > > calls __thermal_cooling_device_register with the same arguments.  The
> > > > latter function stores the device node argument, which is the second
> > > > argument of for_each_child_of_node, in the returned 
> > > > thermal_cooling_device
> > > > structure.  This returned structure is then stored in the cdev field of
> > > > stc.  Thus it seems that the second argument of for_each_child_of_node
> > > > escapes the scope of the for_each_child_of_node, so an explicit 
> > > > of_node_get
> > > > on success of thermal_of_cooling_device_register is also needed.
> > > >
> > > > Signed-off-by: Julia Lawall 
> > > >
> > > > ---
> > > >  drivers/thermal/tegra/soctherm.c |2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/thermal/tegra/soctherm.c 
> > > > b/drivers/thermal/tegra/soctherm.c
> > > > index 7d2db23..10f4fdd 100644
> > > > --- a/drivers/thermal/tegra/soctherm.c
> > > > +++ b/drivers/thermal/tegra/soctherm.c
> > > > @@ -1014,7 +1014,6 @@ static void soctherm_init_hw_throt_cdev(struct 
> > > > platform_device *pdev)
> > > > tcd = thermal_of_cooling_device_register(np_stcc,
> > > >  (char *)name, 
> > > > ts,
> > > >  
> > > > &throt_cooling_ops);
> > > > -   of_node_put(np_stcc);
> > > > if (IS_ERR_OR_NULL(tcd)) {
> > > > dev_err(dev,
> > > > "throttle-cfg: %s: failed to register 
> > > > cooling device\n",
> > > > @@ -1022,6 +1021,7 @@ static void soctherm_init_hw_throt_cdev(struct 
> > > > platform_device *pdev)
> > > > continue;
> > > > }
> > > >
> > > > +   of_node_get(np_stcc);
> > > > stc->cdev = tcd;
> > > > stc->init = true;
> > > > }
> > >
> > > Thanks for fixing this. However, I am wondering if it is better for the
> > > 'of_node_get' to be placed within the
> > > thermal_of_cooling_device_register() function as it seems a bit odd if
> > > the caller needs to know that this is being stored for later use.
> > >
> > > Also, taking a quick look, I see a couple other drivers calling
> > > thermal_of_cooling_device_register() and they are also not calling
> > > of_node_get on success. So it maybe easier to fix placing it in the
> > > thermal_of_cooling_device_register() function.
> >
> > I'm not an expert, but I had the impression that from some call sites, the
> > get would have been done already, because the argument is already stored
> > in some structure.  I can check more exhaustively.
>
> Julia, I agree with Jon here. Better if fixed in the API itself. Are you
> still planning on sending a fix for this?

This has fallen off my stack, and I'mnot sure that Ican get to it in the
short term.

julia


[PATCH v6 01/11] perf util: Define a structure for per-thread shadow stats

2017-12-04 Thread Jin Yao
Perf has a set of static variables to record the runtime shadow
metrics stats.

While if we want to record the runtime shadow stats for per-thread,
it will be the limitation. This patch creates a structure and the
next patches will use this structure to update the runtime shadow
stats for per-thread.

Signed-off-by: Jin Yao 
---
 tools/perf/util/stat-shadow.c | 11 ---
 tools/perf/util/stat.h| 43 ++-
 2 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 57ec225..93aac27 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -9,17 +9,6 @@
 #include "expr.h"
 #include "metricgroup.h"
 
-enum {
-   CTX_BIT_USER= 1 << 0,
-   CTX_BIT_KERNEL  = 1 << 1,
-   CTX_BIT_HV  = 1 << 2,
-   CTX_BIT_HOST= 1 << 3,
-   CTX_BIT_IDLE= 1 << 4,
-   CTX_BIT_MAX = 1 << 5,
-};
-
-#define NUM_CTX CTX_BIT_MAX
-
 /*
  * AGGR_GLOBAL: Use CPU 0
  * AGGR_SOCKET: Use first CPU of socket
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index eefca5c..c685c41 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -5,6 +5,7 @@
 #include 
 #include 
 #include "xyarray.h"
+#include "rblist.h"
 
 struct stats
 {
@@ -43,6 +44,47 @@ enum aggr_mode {
AGGR_UNSET,
 };
 
+enum {
+   CTX_BIT_USER= 1 << 0,
+   CTX_BIT_KERNEL  = 1 << 1,
+   CTX_BIT_HV  = 1 << 2,
+   CTX_BIT_HOST= 1 << 3,
+   CTX_BIT_IDLE= 1 << 4,
+   CTX_BIT_MAX = 1 << 5,
+};
+
+#define NUM_CTX CTX_BIT_MAX
+
+enum stat_type {
+   STAT_NONE = 0,
+   STAT_NSECS,
+   STAT_CYCLES,
+   STAT_STALLED_CYCLES_FRONT,
+   STAT_STALLED_CYCLES_BACK,
+   STAT_BRANCHES,
+   STAT_CACHEREFS,
+   STAT_L1_DCACHE,
+   STAT_L1_ICACHE,
+   STAT_LL_CACHE,
+   STAT_ITLB_CACHE,
+   STAT_DTLB_CACHE,
+   STAT_CYCLES_IN_TX,
+   STAT_TRANSACTION,
+   STAT_ELISION,
+   STAT_TOPDOWN_TOTAL_SLOTS,
+   STAT_TOPDOWN_SLOTS_ISSUED,
+   STAT_TOPDOWN_SLOTS_RETIRED,
+   STAT_TOPDOWN_FETCH_BUBBLES,
+   STAT_TOPDOWN_RECOVERY_BUBBLES,
+   STAT_SMI_NUM,
+   STAT_APERF,
+   STAT_MAX
+};
+
+struct runtime_stat {
+   struct rblist value_list;
+};
+
 struct perf_stat_config {
enum aggr_mode  aggr_mode;
boolscale;
@@ -92,7 +134,6 @@ struct perf_stat_output_ctx {
bool force_header;
 };
 
-struct rblist;
 void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
   double avg, int cpu,
   struct perf_stat_output_ctx *out,
-- 
2.7.4



[PATCH v6 04/11] perf util: Update per-thread shadow stats

2017-12-04 Thread Jin Yao
The functions perf_stat__update_shadow_stats() is called
to update the shadow stats on a set of static variables.

But the static variables are the limitations to be extended
to support per-thread shadow stats.

This patch lets the perf_stat__update_shadow_stats() support
to update the shadow stats on a input parameter 'stat' and
uses update_runtime_stat() to update the stats. It will not
directly update the static variables as before.

Signed-off-by: Jin Yao 
---
 tools/perf/builtin-script.c   |  3 +-
 tools/perf/builtin-stat.c |  3 +-
 tools/perf/util/stat-shadow.c | 86 +--
 tools/perf/util/stat.c|  8 ++--
 tools/perf/util/stat.h|  2 +-
 5 files changed, 68 insertions(+), 34 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 39d8b55..81b3950 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1548,7 +1548,8 @@ static void perf_sample__fprint_metric(struct perf_script 
*script,
val = sample->period * evsel->scale;
perf_stat__update_shadow_stats(evsel,
   val,
-  sample->cpu);
+  sample->cpu,
+  &rt_stat);
evsel_script(evsel)->val = val;
if (evsel_script(evsel->leader)->gnum == evsel->leader->nr_members) {
for_each_group_member (ev2, evsel->leader) {
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a027b47..3f4a2c2 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1214,7 +1214,8 @@ static void aggr_update_shadow(void)
val += perf_counts(counter->counts, cpu, 
0)->val;
}
perf_stat__update_shadow_stats(counter, val,
-  
first_shadow_cpu(counter, id));
+   first_shadow_cpu(counter, id),
+   &rt_stat);
}
}
 }
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index e60c321..11c921d 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -116,19 +116,29 @@ static void saved_value_delete(struct rblist *rblist 
__maybe_unused,
 
 static struct saved_value *saved_value_lookup(struct perf_evsel *evsel,
  int cpu,
- bool create)
+ bool create,
+ enum stat_type type,
+ int ctx,
+ struct runtime_stat *stat)
 {
+   struct rblist *rblist;
struct rb_node *nd;
struct saved_value dm = {
.cpu = cpu,
.evsel = evsel,
+   .type = type,
+   .ctx = ctx,
+   .stat = stat,
};
-   nd = rblist__find(&runtime_saved_values, &dm);
+
+   rblist = &stat->value_list;
+
+   nd = rblist__find(rblist, &dm);
if (nd)
return container_of(nd, struct saved_value, rb_node);
if (create) {
-   rblist__add_node(&runtime_saved_values, &dm);
-   nd = rblist__find(&runtime_saved_values, &dm);
+   rblist__add_node(rblist, &dm);
+   nd = rblist__find(rblist, &dm);
if (nd)
return container_of(nd, struct saved_value, rb_node);
}
@@ -217,13 +227,24 @@ void perf_stat__reset_shadow_stats(void)
}
 }
 
+static void update_runtime_stat(struct runtime_stat *stat,
+   enum stat_type type,
+   int ctx, int cpu, u64 count)
+{
+   struct saved_value *v = saved_value_lookup(NULL, cpu, true,
+  type, ctx, stat);
+
+   if (v)
+   update_stats(&v->stats, count);
+}
+
 /*
  * Update various tracking values we maintain to print
  * more semantic information such as miss/hit ratios,
  * instruction rates, etc:
  */
 void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count,
-   int cpu)
+   int cpu, struct runtime_stat *stat)
 {
int ctx = evsel_context(counter);
 
@@ -231,50 +252,58 @@ void perf_stat__update_shadow_stats(struct perf_evsel 
*counter, u64 count,
 
if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK) ||
perf_evsel__match(counter, SOFTWARE, SW_CPU_CLOCK))
-   update_stats(&runtime_nsecs_stats[cpu], count);
+   update_runtime_stat(stat, STAT_NSECS, 0, cpu, count);
else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
-   update_stats(&runtime_cycles_

[PATCH v6 02/11] perf stat: Extend rbtree to support per-thread shadow stats

2017-12-04 Thread Jin Yao
Previously the rbtree was used to link generic metrics.

This patches adds new ctx/type/stat into rbtree keys because we
will use this rbtree to maintain shadow metrics to replace original
a couple of static arrays for supporting per-thread shadow stats.

Signed-off-by: Jin Yao 
---
 tools/perf/util/stat-shadow.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 93aac27..528be3e 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -45,7 +45,10 @@ struct stats walltime_nsecs_stats;
 struct saved_value {
struct rb_node rb_node;
struct perf_evsel *evsel;
+   enum stat_type type;
+   int ctx;
int cpu;
+   struct runtime_stat *stat;
struct stats stats;
 };
 
@@ -58,6 +61,30 @@ static int saved_value_cmp(struct rb_node *rb_node, const 
void *entry)
 
if (a->cpu != b->cpu)
return a->cpu - b->cpu;
+
+   /*
+* Previously the rbtree was used to link generic metrics.
+* The keys were evsel/cpu. Now the rbtree is extended to support
+* per-thread shadow stats. For shadow stats case, the keys
+* are cpu/type/ctx/stat (evsel is NULL). For generic metrics
+* case, the keys are still evsel/cpu (type/ctx/stat are 0 or NULL).
+*/
+   if (a->type != b->type)
+   return a->type - b->type;
+
+   if (a->ctx != b->ctx)
+   return a->ctx - b->ctx;
+
+   if (a->evsel == NULL && b->evsel == NULL) {
+   if (a->stat == b->stat)
+   return 0;
+
+   if ((char *)a->stat < (char *)b->stat)
+   return -1;
+
+   return 1;
+   }
+
if (a->evsel == b->evsel)
return 0;
if ((char *)a->evsel < (char *)b->evsel)
-- 
2.7.4



[PATCH v6 05/11] perf util: Print per-thread shadow stats

2017-12-04 Thread Jin Yao
The function perf_stat__print_shadow_statss() is called
to print the shadow stats on a set of static variables.

But the static variables are the limitations to support
per-thread shadow stats.

This patch lets the perf_stat__print_shadow_stats() support
to print the shadow stats from a input parameter 'stat'.

It will not directly get value from static variable. Instead,
it now uses runtime_stat_avg() and runtime_stat_n() to get and
compute the values.

Signed-off-by: Jin Yao 
---
 tools/perf/builtin-script.c   |   3 +-
 tools/perf/builtin-stat.c |  24 +++--
 tools/perf/util/stat-shadow.c | 209 ++
 tools/perf/util/stat.h|   3 +-
 4 files changed, 152 insertions(+), 87 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 81b3950..fac6f05 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1557,7 +1557,8 @@ static void perf_sample__fprint_metric(struct perf_script 
*script,
  evsel_script(ev2)->val,
  sample->cpu,
  &ctx,
- NULL);
+ NULL,
+ &rt_stat);
}
evsel_script(evsel->leader)->gnum = 0;
}
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 3f4a2c2..1edc082 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1097,7 +1097,8 @@ static void abs_printout(int id, int nr, struct 
perf_evsel *evsel, double avg)
 }
 
 static void printout(int id, int nr, struct perf_evsel *counter, double uval,
-char *prefix, u64 run, u64 ena, double noise)
+char *prefix, u64 run, u64 ena, double noise,
+struct runtime_stat *stat)
 {
struct perf_stat_output_ctx out;
struct outstate os = {
@@ -1190,7 +1191,8 @@ static void printout(int id, int nr, struct perf_evsel 
*counter, double uval,
 
perf_stat__print_shadow_stats(counter, uval,
first_shadow_cpu(counter, id),
-   &out, &metric_events);
+   &out, &metric_events,
+   stat);
if (!csv_output && !metric_only) {
print_noise(counter, noise);
print_running(run, ena);
@@ -1335,7 +1337,8 @@ static void print_aggr(char *prefix)
fprintf(output, "%s", prefix);
 
uval = val * counter->scale;
-   printout(id, nr, counter, uval, prefix, run, ena, 1.0);
+   printout(id, nr, counter, uval, prefix, run, ena, 1.0,
+&rt_stat);
if (!metric_only)
fputc('\n', output);
}
@@ -1365,7 +1368,8 @@ static void print_aggr_thread(struct perf_evsel *counter, 
char *prefix)
fprintf(output, "%s", prefix);
 
uval = val * counter->scale;
-   printout(thread, 0, counter, uval, prefix, run, ena, 1.0);
+   printout(thread, 0, counter, uval, prefix, run, ena, 1.0,
+&rt_stat);
fputc('\n', output);
}
 }
@@ -1402,7 +1406,8 @@ static void print_counter_aggr(struct perf_evsel 
*counter, char *prefix)
fprintf(output, "%s", prefix);
 
uval = cd.avg * counter->scale;
-   printout(-1, 0, counter, uval, prefix, cd.avg_running, cd.avg_enabled, 
cd.avg);
+   printout(-1, 0, counter, uval, prefix, cd.avg_running, cd.avg_enabled,
+cd.avg, &rt_stat);
if (!metric_only)
fprintf(output, "\n");
 }
@@ -1441,7 +1446,8 @@ static void print_counter(struct perf_evsel *counter, 
char *prefix)
fprintf(output, "%s", prefix);
 
uval = val * counter->scale;
-   printout(cpu, 0, counter, uval, prefix, run, ena, 1.0);
+   printout(cpu, 0, counter, uval, prefix, run, ena, 1.0,
+&rt_stat);
 
fputc('\n', output);
}
@@ -1473,7 +1479,8 @@ static void print_no_aggr_metric(char *prefix)
run = perf_counts(counter->counts, cpu, 0)->run;
 
uval = val * counter->scale;
-   printout(cpu, 0, counter, uval, prefix, run, ena, 1.0);
+   printout(cpu, 0, counter, uval, prefix, run, ena, 1.0,
+&rt_stat);
}
fputc('\n', stat_config.output);
}
@@ -1529,7 +1536,8 @@ static void print_metric_headers(const char *prefix, bool 
no_indent)
perf_stat__print_shadow_stats(coun

[PATCH v6 06/11] perf util: Remove a set of shadow stats static variables

2017-12-04 Thread Jin Yao
In previous patches, we have reconstructed the code and let
it not access the static variables directly.

This patch removes these static variables.

Signed-off-by: Jin Yao 
---
 tools/perf/util/stat-shadow.c | 68 ++-
 tools/perf/util/stat.h|  1 +
 2 files changed, 16 insertions(+), 53 deletions(-)

diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 0d34d5e..3b929fb 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -16,28 +16,6 @@
  * AGGR_NONE: Use matching CPU
  * AGGR_THREAD: Not supported?
  */
-static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
-static struct stats runtime_cycles_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_stalled_cycles_front_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_stalled_cycles_back_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_branches_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_cacherefs_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_l1_dcache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_l1_icache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_ll_cache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_itlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_dtlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_topdown_total_slots[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_topdown_slots_issued[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_topdown_slots_retired[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_topdown_fetch_bubbles[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_topdown_recovery_bubbles[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_smi_num_stats[NUM_CTX][MAX_NR_CPUS];
-static struct stats runtime_aperf_stats[NUM_CTX][MAX_NR_CPUS];
-static struct rblist runtime_saved_values;
 static bool have_frontend_stalled;
 
 struct runtime_stat rt_stat;
@@ -163,10 +141,6 @@ void runtime_stat__exit(struct runtime_stat *stat)
 void perf_stat__init_shadow_stats(void)
 {
have_frontend_stalled = pmu_have_event("cpu", 
"stalled-cycles-frontend");
-   rblist__init(&runtime_saved_values);
-   runtime_saved_values.node_cmp = saved_value_cmp;
-   runtime_saved_values.node_new = saved_value_new;
-   runtime_saved_values.node_delete = saved_value_delete;
runtime_stat__init(&rt_stat);
 }
 
@@ -188,36 +162,13 @@ static int evsel_context(struct perf_evsel *evsel)
return ctx;
 }
 
-void perf_stat__reset_shadow_stats(void)
+static void reset_stat(struct runtime_stat *stat)
 {
+   struct rblist *rblist;
struct rb_node *pos, *next;
 
-   memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
-   memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
-   memset(runtime_stalled_cycles_front_stats, 0, 
sizeof(runtime_stalled_cycles_front_stats));
-   memset(runtime_stalled_cycles_back_stats, 0, 
sizeof(runtime_stalled_cycles_back_stats));
-   memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
-   memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
-   memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
-   memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
-   memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
-   memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
-   memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
-   memset(runtime_cycles_in_tx_stats, 0,
-   sizeof(runtime_cycles_in_tx_stats));
-   memset(runtime_transaction_stats, 0,
-   sizeof(runtime_transaction_stats));
-   memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
-   memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
-   memset(runtime_topdown_total_slots, 0, 
sizeof(runtime_topdown_total_slots));
-   memset(runtime_topdown_slots_retired, 0, 
sizeof(runtime_topdown_slots_retired));
-   memset(runtime_topdown_slots_issued, 0, 
sizeof(runtime_topdown_slots_issued));
-   memset(runtime_topdown_fetch_bubbles, 0, 
sizeof(runtime_topdown_fetch_bubbles));
-   memset(runtime_topdown_recovery_bubbles, 0, 
sizeof(runtime_topdown_recovery_bubbles));
-   memset(runtime_smi_num_stats, 0, sizeof(runtime_smi_num_stats));
-   memset(runtime_aperf_stats, 0, sizeof(runtime_aperf_stats));
-
-   next = rb_first(&runtime_saved_values.entries);
+   rblist = &stat->value_list;
+   next = rb_first(&rblist->entries);
while (next) {
pos = next;
next = rb_next(pos);
@@ -227,6 +178,17 @@ void perf_stat__reset_

[PATCH v6 09/11] perf util: Enumerate all threads from /proc

2017-12-04 Thread Jin Yao
This patch calls thread_map__new_all_cpus() to enumerate all
threads from /proc if per-thread flag is enabled.

Signed-off-by: Jin Yao 
---
 tools/perf/tests/thread-map.c | 2 +-
 tools/perf/util/evlist.c  | 3 ++-
 tools/perf/util/thread_map.c  | 5 -
 tools/perf/util/thread_map.h  | 2 +-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c
index dbcb6a1..4de1939 100644
--- a/tools/perf/tests/thread-map.c
+++ b/tools/perf/tests/thread-map.c
@@ -105,7 +105,7 @@ int test__thread_map_remove(struct test *test 
__maybe_unused, int subtest __mayb
TEST_ASSERT_VAL("failed to allocate map string",
asprintf(&str, "%d,%d", getpid(), getppid()) >= 0);
 
-   threads = thread_map__new_str(str, NULL, 0);
+   threads = thread_map__new_str(str, NULL, 0, false);
 
TEST_ASSERT_VAL("failed to allocate thread_map",
threads);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 68c1f95..9c396ac 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1100,7 +1100,8 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, 
struct target *target)
struct cpu_map *cpus;
struct thread_map *threads;
 
-   threads = thread_map__new_str(target->pid, target->tid, target->uid);
+   threads = thread_map__new_str(target->pid, target->tid, target->uid,
+ target->per_thread);
 
if (!threads)
return -1;
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 2b65385..3e1038f 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -323,7 +323,7 @@ struct thread_map *thread_map__new_by_tid_str(const char 
*tid_str)
 }
 
 struct thread_map *thread_map__new_str(const char *pid, const char *tid,
-  uid_t uid)
+  uid_t uid, bool per_thread)
 {
if (pid)
return thread_map__new_by_pid_str(pid);
@@ -331,6 +331,9 @@ struct thread_map *thread_map__new_str(const char *pid, 
const char *tid,
if (!tid && uid != UINT_MAX)
return thread_map__new_by_uid(uid);
 
+   if (per_thread)
+   return thread_map__new_all_cpus();
+
return thread_map__new_by_tid_str(tid);
 }
 
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
index 07a765f..0a806b9 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -31,7 +31,7 @@ struct thread_map *thread_map__get(struct thread_map *map);
 void thread_map__put(struct thread_map *map);
 
 struct thread_map *thread_map__new_str(const char *pid,
-   const char *tid, uid_t uid);
+   const char *tid, uid_t uid, bool per_thread);
 
 struct thread_map *thread_map__new_by_tid_str(const char *tid_str);
 
-- 
2.7.4



[PATCH v6 03/11] perf util: Create the runtime_stat init/exit function

2017-12-04 Thread Jin Yao
It mainly initializes and releases the rblist which is
defined in struct runtime_stat.

For the original rblist 'runtime_saved_values', it's still
kept there for keeping the patch bisectable.

The rblist 'runtime_saved_values' will be removed in later
patch at switching time.

Signed-off-by: Jin Yao 
---
 tools/perf/util/stat-shadow.c | 17 +
 tools/perf/util/stat.h|  3 +++
 2 files changed, 20 insertions(+)

diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 528be3e..e60c321 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -40,6 +40,7 @@ static struct stats runtime_aperf_stats[NUM_CTX][MAX_NR_CPUS];
 static struct rblist runtime_saved_values;
 static bool have_frontend_stalled;
 
+struct runtime_stat rt_stat;
 struct stats walltime_nsecs_stats;
 
 struct saved_value {
@@ -134,6 +135,21 @@ static struct saved_value *saved_value_lookup(struct 
perf_evsel *evsel,
return NULL;
 }
 
+void runtime_stat__init(struct runtime_stat *stat)
+{
+   struct rblist *rblist = &stat->value_list;
+
+   rblist__init(rblist);
+   rblist->node_cmp = saved_value_cmp;
+   rblist->node_new = saved_value_new;
+   rblist->node_delete = saved_value_delete;
+}
+
+void runtime_stat__exit(struct runtime_stat *stat)
+{
+   rblist__exit(&stat->value_list);
+}
+
 void perf_stat__init_shadow_stats(void)
 {
have_frontend_stalled = pmu_have_event("cpu", 
"stalled-cycles-frontend");
@@ -141,6 +157,7 @@ void perf_stat__init_shadow_stats(void)
runtime_saved_values.node_cmp = saved_value_cmp;
runtime_saved_values.node_new = saved_value_new;
runtime_saved_values.node_delete = saved_value_delete;
+   runtime_stat__init(&rt_stat);
 }
 
 static int evsel_context(struct perf_evsel *evsel)
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index c685c41..5a0ebdc 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -117,12 +117,15 @@ bool __perf_evsel_stat__is(struct perf_evsel *evsel,
 
 void perf_stat_evsel_id_init(struct perf_evsel *evsel);
 
+extern struct runtime_stat rt_stat;
 extern struct stats walltime_nsecs_stats;
 
 typedef void (*print_metric_t)(void *ctx, const char *color, const char *unit,
   const char *fmt, double val);
 typedef void (*new_line_t )(void *ctx);
 
+void runtime_stat__init(struct runtime_stat *stat);
+void runtime_stat__exit(struct runtime_stat *stat);
 void perf_stat__init_shadow_stats(void);
 void perf_stat__reset_shadow_stats(void);
 void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count,
-- 
2.7.4



[PATCH v6 00/11] perf stat: Enable '--per-thread' on all thread

2017-12-04 Thread Jin Yao
v6:
---
Update according to Arnaldo's comments.

1. In 'perf util: Define a structure for runtime shadow stats'
Remove '#include "evsel.h"'

2. In 'perf stat: Extend rbtree to support per-thread shadow stats'
Change patch subject to 'perf stat: Extend rbtree to support per-thread shadow 
stats'.

3. Split the 'perf util: Update and print per-thread shadow stats' to 2 patches.
  perf util: Update per-thread shadow stats
  perf util: Print per-thread shadow stats

4. Rebase to latest perf/core branch
Because 3 patches have been merged yet so remove them in this patch series.

Update the patch 'perf util: Enumerate all threads from /proc' in rebase.

v5:
---
Update according to Arnaldo's comments.

Try to replace '_reset' with '_exit' and '_free' with '_delete'.

1. In 'perf util: Create rblist__exit() function', 
rblist__reset() -> rblist__exit()

2. In 'perf util: Create the runtime_stat init/exit function'
runtime_stat__free() -> runtime_stat__exit()

I don't change the name to runtime_stat__delete() because
it doesn't free the object in this function. So maybe '__exit'
is better.

3. In 'perf stat: Allocate shadow stats buffer for threads'
runtime_stat_alloc() -> runtime_stat_new()
runtime_stat_free() -> runtime_stat_delete()

v4:
---
Update according to Jiri's comments. The major modification is:

Move struct perf_stat_config::*stats|stats_num to
'perf stat: Allocate shadow stats buffer for threads'.

I also move the code of updating/printing per-thread stats
from 'perf util: Update and print per-thread shadow stats'
and 'perf stat: Allocate shadow stats buffer for threads'
to a new patch 'perf stat: Update or print per-thread stats'.
That should be more clear for patch reading.

Impacted patch:
---
  perf util: Define a structure for runtime shadow stats
  perf util: Update and print per-thread shadow stats
  perf stat: Allocate shadow stats buffer for threads
  perf stat: Update or print per-thread stats
  perf stat: Resort '--per-thread' result

v3:
---
Update according to Jiri's comments. The major modifications are:

1. Fix the crash issue when performing the git bisect.
   Move the removing of runtime_saved_values to the switching point
   (perf util: Remove a set of shadow stats static variables).

2. Still add struct perf_stat_config::*stats|stats_num in earlier
   patch because 'stats' will be used in
   'perf util: Update and print per-thread shadow stats'.
   If it's moved to 'perf stat: Allocate shadow stats buffer for threads',
   the compilation would be failed.

3. v = container_of(rb_node,
struct saved_value,
rb_node);

   Let this code to be one line.

Impacted patch:
---
  perf util: Add rbtree node_delete ops
  perf util: Create the runtime_stat init/free function
  perf util: Update and print per-thread shadow stats
  perf util: Remove a set of shadow stats static variables

v2:
---
Update according to Jiri's comments. The major modifications are:

1. Remove unnecessary memset for runtime_stat and
   walltime_nsecs_stats.

2. Remove init_saved_rblist/free_saved_rblist and move the codes
   to runtime_stat__init/runtime_stat__free.

3. Change function name from perf_stat__init_runtime_stat/
   perf_stat__free_runtime_stat to runtime_stat__init/
   runtime_stat__free

4. Create a new patch 'perf util: Extend rbtree to support shadow stats'
   to add new ctx/type/stat into rbtree keys for supporting per-thread
   shadow stats. It also comment in here on the cases where evsel is
   defined and when not.

5. Pass &rt_stat directly to perf_stat__update_shadow_stats, replace
   original parameter NULL.

6. Move the code of shadow stat updating for per-thread case to config->stats
   allocation/usage patch.

7. Add BUG_ON(!rb_node) in saved_value_delete.

8. s/stat_num/stats_num/ or s/stats/stat/ in struct perf_stat_config.

9. Rebase to latest perf/core branch.

Impacted patch:
---
  perf util: Define a structure for runtime shadow metrics stats
  perf util: Extend rbtree to support shadow stats
  perf util: Add rbtree node_delete ops
  perf util: Update and print per-thread shadow stats
  perf stat: Allocate shadow stats buffer for threads
  perf stat: Remove --per-thread pid/tid limitation
  perf stat: Resort '--per-thread' result

Initial post:
-

perf stat --per-thread is useful to break down data per thread.
But it currently requires specifying --pid/--tid to limit it to a process.

For analysis it would be useful to do it globally for the whole system.

1. Currently, if we perform 'perf stat --per-thread' without pid/tid,
perf returns error:

root@skl:/tmp# perf stat --per-thread
The --per-thread option is only available when monitoring via -p -t options.
-p, --pidstat events on existing process id
-t, --tidstat events on existing thread id

2. With this patch series, it returns data per thread with shadow metrics.
   (run "vmstat 1" in following example)

root@skl:/tmp# 

[PATCH v6 11/11] perf stat: Resort '--per-thread' result

2017-12-04 Thread Jin Yao
There are many threads reported if we enable '--per-thread'
globally.

1. Most of the threads are not counted or counting value 0.
This patch removes these threads.

2. We also resort the threads in display according to the
counting value. It's useful for user to see the hottest
threads easily.

For example, the new results would be:

root@skl:/tmp# perf stat --per-thread
^C
 Performance counter stats for 'system wide':

perf-24165  4.302433  cpu-clock (msec)  #   
 0.001 CPUs utilized
  vmstat-23127  1.562215  cpu-clock (msec)  #   
 0.000 CPUs utilized
  irqbalance-2780   0.827851  cpu-clock (msec)  #   
 0.000 CPUs utilized
sshd-23111  0.278308  cpu-clock (msec)  #   
 0.000 CPUs utilized
thermald-2841   0.230880  cpu-clock (msec)  #   
 0.000 CPUs utilized
sshd-23058  0.207306  cpu-clock (msec)  #   
 0.000 CPUs utilized
 kworker/0:2-19991  0.133983  cpu-clock (msec)  #   
 0.000 CPUs utilized
   kworker/u16:1-18249  0.125636  cpu-clock (msec)  #   
 0.000 CPUs utilized
   rcu_sched-8  0.085533  cpu-clock (msec)  #   
 0.000 CPUs utilized
   kworker/u16:2-23146  0.077139  cpu-clock (msec)  #   
 0.000 CPUs utilized
   gmain-2700   0.041789  cpu-clock (msec)  #   
 0.000 CPUs utilized
 kworker/4:1-15354  0.028370  cpu-clock (msec)  #   
 0.000 CPUs utilized
 kworker/6:0-17528  0.023895  cpu-clock (msec)  #   
 0.000 CPUs utilized
kworker/4:1H-1887   0.013209  cpu-clock (msec)  #   
 0.000 CPUs utilized
 kworker/5:2-31362  0.011627  cpu-clock (msec)  #   
 0.000 CPUs utilized
  watchdog/0-11 0.010892  cpu-clock (msec)  #   
 0.000 CPUs utilized
 kworker/3:2-12870  0.010220  cpu-clock (msec)  #   
 0.000 CPUs utilized
 ksoftirqd/0-7  0.008869  cpu-clock (msec)  #   
 0.000 CPUs utilized
  watchdog/1-14 0.008476  cpu-clock (msec)  #   
 0.000 CPUs utilized
  watchdog/7-50 0.002944  cpu-clock (msec)  #   
 0.000 CPUs utilized
  watchdog/3-26 0.002893  cpu-clock (msec)  #   
 0.000 CPUs utilized
  watchdog/4-32 0.002759  cpu-clock (msec)  #   
 0.000 CPUs utilized
  watchdog/2-20 0.002429  cpu-clock (msec)  #   
 0.000 CPUs utilized
  watchdog/6-44 0.001491  cpu-clock (msec)  #   
 0.000 CPUs utilized
  watchdog/5-38 0.001477  cpu-clock (msec)  #   
 0.000 CPUs utilized
   rcu_sched-810  context-switches  #   
 0.117 M/sec
   kworker/u16:1-18249 7  context-switches  #   
 0.056 M/sec
sshd-23111 4  context-switches  #   
 0.014 M/sec
  vmstat-23127 4  context-switches  #   
 0.003 M/sec
perf-24165 4  context-switches  #   
 0.930 K/sec
 kworker/0:2-19991 3  context-switches  #   
 0.022 M/sec
   kworker/u16:2-23146 3  context-switches  #   
 0.039 M/sec
 kworker/4:1-15354 2  context-switches  #   
 0.070 M/sec
 kworker/6:0-17528 2  context-switches  #   
 0.084 M/sec
sshd-23058 2  context-switches  #   
 0.010 M/sec
 ksoftirqd/0-7 1  context-switches  #   
 0.113 M/sec
  watchdog/0-111  context-switches  #   
 0.092 M/sec
  watchdog/1-141  context-switches  #   
 0.118 M/sec
  watchdog/2-201  context-switches  #   
 0.412 M/sec
  watchdog/3-261  context-switches  #   
 0.346 M/sec
  watchdog/4-321  context-switches  #   
 0.362 M/sec
  watchdog/5-381  context-switches  #   
 0.677 M/sec
  watchdog/6-441  context-switches  #   
 0.671 M/sec
  watchdog/7-501  context-switches  #   
 0.340 M/sec
kworker/4:1H-1887  1  context-switches  #   
 0.076 M/sec
thermald-2841  1  context-switches  #   
 0.004 M/sec
   gmain-2700  1  

[PATCH v6 08/11] perf stat: Update or print per-thread stats

2017-12-04 Thread Jin Yao
If the stats pointer in stat_config structure is not null, it will
update the per-thread stats or print the per-thread stats on this
buffer.

Signed-off-by: Jin Yao 
---
 tools/perf/builtin-stat.c |  9 +++--
 tools/perf/util/stat.c| 11 ---
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8ff3348..23d5618 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1373,8 +1373,13 @@ static void print_aggr_thread(struct perf_evsel 
*counter, char *prefix)
fprintf(output, "%s", prefix);
 
uval = val * counter->scale;
-   printout(thread, 0, counter, uval, prefix, run, ena, 1.0,
-&rt_stat);
+
+   if (stat_config.stats)
+   printout(thread, 0, counter, uval, prefix, run, ena,
+1.0, &stat_config.stats[thread]);
+   else
+   printout(thread, 0, counter, uval, prefix, run, ena,
+1.0, &rt_stat);
fputc('\n', output);
}
 }
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 78abfd4..32235657 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -280,9 +280,14 @@ process_counter_values(struct perf_stat_config *config, 
struct perf_evsel *evsel
if (config->aggr_mode == AGGR_NONE)
perf_stat__update_shadow_stats(evsel, count->val, cpu,
   &rt_stat);
-   if (config->aggr_mode == AGGR_THREAD)
-   perf_stat__update_shadow_stats(evsel, count->val, 0,
-  &rt_stat);
+   if (config->aggr_mode == AGGR_THREAD) {
+   if (config->stats)
+   perf_stat__update_shadow_stats(evsel,
+   count->val, 0, &config->stats[thread]);
+   else
+   perf_stat__update_shadow_stats(evsel,
+   count->val, 0, &rt_stat);
+   }
break;
case AGGR_GLOBAL:
aggr->val += count->val;
-- 
2.7.4



[PATCH v6 10/11] perf stat: Remove --per-thread pid/tid limitation

2017-12-04 Thread Jin Yao
Currently, if we execute 'perf stat --per-thread' without specifying
pid/tid, perf will return error.

root@skl:/tmp# perf stat --per-thread
The --per-thread option is only available when monitoring via -p -t options.
-p, --pidstat events on existing process id
-t, --tidstat events on existing thread id

This patch removes this limitation. If no pid/tid specified, it returns
all threads (get threads from /proc).

Note that it doesn't support cpu_list yet so if it's a cpu_list case,
then skip.

Signed-off-by: Jin Yao 
---
 tools/perf/builtin-stat.c | 23 +++
 tools/perf/util/target.h  |  7 +++
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 23d5618..167c35c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -277,7 +277,7 @@ static int create_perf_stat_counter(struct perf_evsel 
*evsel)
attr->enable_on_exec = 1;
}
 
-   if (target__has_cpu(&target))
+   if (target__has_cpu(&target) && !target__has_per_thread(&target))
return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
 
return perf_evsel__open_per_thread(evsel, evsel_list->threads);
@@ -340,7 +340,7 @@ static int read_counter(struct perf_evsel *counter)
int nthreads = thread_map__nr(evsel_list->threads);
int ncpus, cpu, thread;
 
-   if (target__has_cpu(&target))
+   if (target__has_cpu(&target) && !target__has_per_thread(&target))
ncpus = perf_evsel__nr_cpus(counter);
else
ncpus = 1;
@@ -2744,12 +2744,16 @@ int cmd_stat(int argc, const char **argv)
run_count = 1;
}
 
-   if ((stat_config.aggr_mode == AGGR_THREAD) && 
!target__has_task(&target)) {
-   fprintf(stderr, "The --per-thread option is only available "
-   "when monitoring via -p -t options.\n");
-   parse_options_usage(NULL, stat_options, "p", 1);
-   parse_options_usage(NULL, stat_options, "t", 1);
-   goto out;
+   if ((stat_config.aggr_mode == AGGR_THREAD) &&
+   !target__has_task(&target)) {
+   if (!target.system_wide || target.cpu_list) {
+   fprintf(stderr, "The --per-thread option is only "
+   "available when monitoring via -p -t -a "
+   "options or only --per-thread.\n");
+   parse_options_usage(NULL, stat_options, "p", 1);
+   parse_options_usage(NULL, stat_options, "t", 1);
+   goto out;
+   }
}
 
/*
@@ -2773,6 +2777,9 @@ int cmd_stat(int argc, const char **argv)
 
target__validate(&target);
 
+   if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide))
+   target.per_thread = true;
+
if (perf_evlist__create_maps(evsel_list, &target) < 0) {
if (target__has_task(&target)) {
pr_err("Problems finding threads of monitor\n");
diff --git a/tools/perf/util/target.h b/tools/perf/util/target.h
index 446aa7a..6ef01a8 100644
--- a/tools/perf/util/target.h
+++ b/tools/perf/util/target.h
@@ -64,6 +64,11 @@ static inline bool target__none(struct target *target)
return !target__has_task(target) && !target__has_cpu(target);
 }
 
+static inline bool target__has_per_thread(struct target *target)
+{
+   return target->system_wide && target->per_thread;
+}
+
 static inline bool target__uses_dummy_map(struct target *target)
 {
bool use_dummy = false;
@@ -73,6 +78,8 @@ static inline bool target__uses_dummy_map(struct target 
*target)
else if (target__has_task(target) ||
 (!target__has_cpu(target) && !target->uses_mmap))
use_dummy = true;
+   else if (target__has_per_thread(target))
+   use_dummy = true;
 
return use_dummy;
 }
-- 
2.7.4



[PATCH v6 07/11] perf stat: Allocate shadow stats buffer for threads

2017-12-04 Thread Jin Yao
After perf_evlist__create_maps() being executed, we can get all
threads from /proc. And via thread_map__nr(), we can also get
the number of threads.

With the number of threads, the patch allocates a buffer which
will record the shadow stats for these threads.

The buffer pointer is saved in stat_config.

Signed-off-by: Jin Yao 
---
 tools/perf/builtin-stat.c | 46 +-
 tools/perf/util/stat.h|  2 ++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 1edc082..8ff3348 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -214,8 +214,13 @@ static inline void diff_timespec(struct timespec *r, 
struct timespec *a,
 
 static void perf_stat__reset_stats(void)
 {
+   int i;
+
perf_evlist__reset_stats(evsel_list);
perf_stat__reset_shadow_stats();
+
+   for (i = 0; i < stat_config.stats_num; i++)
+   perf_stat__reset_shadow_per_stat(&stat_config.stats[i]);
 }
 
 static int create_perf_stat_counter(struct perf_evsel *evsel)
@@ -2496,6 +2501,35 @@ int process_cpu_map_event(struct perf_tool *tool,
return set_maps(st);
 }
 
+static int runtime_stat_new(struct perf_stat_config *config, int nthreads)
+{
+   int i;
+
+   config->stats = calloc(nthreads, sizeof(struct runtime_stat));
+   if (!config->stats)
+   return -1;
+
+   config->stats_num = nthreads;
+
+   for (i = 0; i < nthreads; i++)
+   runtime_stat__init(&config->stats[i]);
+
+   return 0;
+}
+
+static void runtime_stat_delete(struct perf_stat_config *config)
+{
+   int i;
+
+   if (!config->stats)
+   return;
+
+   for (i = 0; i < config->stats_num; i++)
+   runtime_stat__exit(&config->stats[i]);
+
+   free(config->stats);
+}
+
 static const char * const stat_report_usage[] = {
"perf stat report []",
NULL,
@@ -2751,8 +2785,15 @@ int cmd_stat(int argc, const char **argv)
 * Initialize thread_map with comm names,
 * so we could print it out on output.
 */
-   if (stat_config.aggr_mode == AGGR_THREAD)
+   if (stat_config.aggr_mode == AGGR_THREAD) {
thread_map__read_comms(evsel_list->threads);
+   if (target.system_wide) {
+   if (runtime_stat_new(&stat_config,
+   thread_map__nr(evsel_list->threads))) {
+   goto out;
+   }
+   }
+   }
 
if (interval && interval < 100) {
if (interval < 10) {
@@ -2842,5 +2883,8 @@ int cmd_stat(int argc, const char **argv)
sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
 
perf_evlist__delete(evsel_list);
+
+   runtime_stat_delete(&stat_config);
+
return status;
 }
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 27d7a18..06475c4 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -90,6 +90,8 @@ struct perf_stat_config {
boolscale;
FILE*output;
unsigned intinterval;
+   struct runtime_stat *stats;
+   int stats_num;
 };
 
 void update_stats(struct stats *stats, u64 val);
-- 
2.7.4



Re: [PATCH 1/1] mm/page_owner: ignore everything below the IRQ entry point

2017-12-04 Thread kbuild test robot
Hi Maninder,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on mmotm/master]
[also build test ERROR on v4.15-rc2 next-20171204]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Maninder-Singh/mm-page_owner-ignore-everything-below-the-IRQ-entry-point/20171205-122901
base:   git://git.cmpxchg.org/linux-mmotm.git master
config: tile-allmodconfig (attached as .config)
compiler: tilegx-linux-gcc (GCC) 5.5.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=tile 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/interrupt.h:22:0,
from include/linux/kernel_stat.h:9,
from mm//swap.c:18:
>> arch/tile/include/asm/sections.h:18:29: error: redefinition of 
>> 'arch_is_kernel_data'
#define arch_is_kernel_data arch_is_kernel_data
^
>> arch/tile/include/asm/sections.h:38:19: note: in expansion of macro 
>> 'arch_is_kernel_data'
static inline int arch_is_kernel_data(unsigned long addr)
  ^
   In file included from include/linux/stacktrace.h:6:0,
from include/linux/lockdep.h:29,
from include/linux/spinlock_types.h:18,
from include/linux/spinlock.h:82,
from include/linux/mmzone.h:8,
from include/linux/gfp.h:6,
from include/linux/mm.h:10,
from mm//swap.c:16:
   include/asm-generic/sections.h:70:19: note: previous definition of 
'arch_is_kernel_data' was here
static inline int arch_is_kernel_data(unsigned long addr)
  ^

vim +/arch_is_kernel_data +18 arch/tile/include/asm/sections.h

867e359b Chris Metcalf 2010-05-28  17  
867e359b Chris Metcalf 2010-05-28 @18  #define arch_is_kernel_data 
arch_is_kernel_data
867e359b Chris Metcalf 2010-05-28  19  
867e359b Chris Metcalf 2010-05-28  20  #include 
867e359b Chris Metcalf 2010-05-28  21  
4a556f4f Chris Metcalf 2013-08-07  22  extern char vdso_start[], vdso_end[];
4a556f4f Chris Metcalf 2013-08-07  23  #ifdef CONFIG_COMPAT
4a556f4f Chris Metcalf 2013-08-07  24  extern char vdso32_start[], vdso32_end[];
4a556f4f Chris Metcalf 2013-08-07  25  #endif
0707ad30 Chris Metcalf 2010-06-25  26  
0707ad30 Chris Metcalf 2010-06-25  27  /* Not exactly sections, but PC 
comparison points in the code. */
0707ad30 Chris Metcalf 2010-06-25  28  extern char __rt_sigreturn[], 
__rt_sigreturn_end[];
2f9ac29e Chris Metcalf 2013-08-06  29  #ifdef __tilegx__
2f9ac29e Chris Metcalf 2013-08-06  30  extern char __start_unalign_asm_code[], 
__end_unalign_asm_code[];
2f9ac29e Chris Metcalf 2013-08-06  31  #else
0707ad30 Chris Metcalf 2010-06-25  32  extern char sys_cmpxchg[], 
__sys_cmpxchg_end[];
0707ad30 Chris Metcalf 2010-06-25  33  extern char __sys_cmpxchg_grab_lock[];
0707ad30 Chris Metcalf 2010-06-25  34  extern char __start_atomic_asm_code[], 
__end_atomic_asm_code[];
0707ad30 Chris Metcalf 2010-06-25  35  #endif
867e359b Chris Metcalf 2010-05-28  36  
40a3b8df Jiang Liu 2013-07-03  37  /* Handle the discontiguity between 
_sdata and _text. */
867e359b Chris Metcalf 2010-05-28 @38  static inline int 
arch_is_kernel_data(unsigned long addr)
867e359b Chris Metcalf 2010-05-28  39  {
867e359b Chris Metcalf 2010-05-28  40   return addr >= (unsigned long)_sdata &&
867e359b Chris Metcalf 2010-05-28  41   addr < (unsigned long)_end;
867e359b Chris Metcalf 2010-05-28  42  }
867e359b Chris Metcalf 2010-05-28  43  

:: The code at line 18 was first introduced by commit
:: 867e359b97c970a60626d5d76bbe2a8fadbf38fb arch/tile: core support for 
Tilera 32-bit chips.

:: TO: Chris Metcalf 
:: CC: Chris Metcalf 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH v10 3/6] clk: qcom: Add A53 PLL support

2017-12-04 Thread Bjorn Andersson
On Fri 01 Dec 09:02 PST 2017, Georgi Djakov wrote:

> The CPUs on Qualcomm MSM8916-based platforms are clocked by two PLLs,
> a primary (A53) CPU PLL and a secondary fixed-rate GPLL0. These sources
> are connected to a mux and half-integer divider, which is feeding the
> CPU cores.
> 
> This patch adds support for the primary CPU PLL which generates the
> higher range of frequencies above 1GHz.
> 
> Signed-off-by: Georgi Djakov 
> Acked-by: Rob Herring 

Acked-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  .../devicetree/bindings/clock/qcom,a53pll.txt  |  22 +
>  drivers/clk/qcom/Kconfig   |  10 ++
>  drivers/clk/qcom/Makefile  |   1 +
>  drivers/clk/qcom/a53-pll.c | 109 
> +
>  4 files changed, 142 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/qcom,a53pll.txt
>  create mode 100644 drivers/clk/qcom/a53-pll.c
> 
> diff --git a/Documentation/devicetree/bindings/clock/qcom,a53pll.txt 
> b/Documentation/devicetree/bindings/clock/qcom,a53pll.txt
> new file mode 100644
> index ..e3fa8118eaee
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/qcom,a53pll.txt
> @@ -0,0 +1,22 @@
> +Qualcomm MSM8916 A53 PLL Binding
> +
> +The A53 PLL on MSM8916 platforms is the main CPU PLL used used for 
> frequencies
> +above 1GHz.
> +
> +Required properties :
> +- compatible : Shall contain only one of the following:
> +
> + "qcom,msm8916-a53pll"
> +
> +- reg : shall contain base register location and length
> +
> +- #clock-cells : must be set to <0>
> +
> +Example:
> +
> + a53pll: clock@b016000 {
> + compatible = "qcom,msm8916-a53pll";
> + reg = <0xb016000 0x40>;
> + #clock-cells = <0>;
> + };
> +
> diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
> index 9f6c278deead..81ac7b9378fe 100644
> --- a/drivers/clk/qcom/Kconfig
> +++ b/drivers/clk/qcom/Kconfig
> @@ -12,6 +12,16 @@ config COMMON_CLK_QCOM
>   select REGMAP_MMIO
>   select RESET_CONTROLLER
>  
> +config QCOM_A53PLL
> + bool "MSM8916 A53 PLL"
> + depends on COMMON_CLK_QCOM
> + default ARCH_QCOM
> + help
> +   Support for the A53 PLL on MSM8916 devices. It provides
> +   the CPU with frequencies above 1GHz.
> +   Say Y if you want to support higher CPU frequencies on MSM8916
> +   devices.
> +
>  config QCOM_CLK_RPM
>   tristate "RPM based Clock Controller"
>   depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
> diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
> index 26410d31446b..e767c60c24ec 100644
> --- a/drivers/clk/qcom/Makefile
> +++ b/drivers/clk/qcom/Makefile
> @@ -32,5 +32,6 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
>  obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
>  obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
>  obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
> +obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
>  obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
>  obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
> diff --git a/drivers/clk/qcom/a53-pll.c b/drivers/clk/qcom/a53-pll.c
> new file mode 100644
> index ..b2bb8e9437f1
> --- /dev/null
> +++ b/drivers/clk/qcom/a53-pll.c
> @@ -0,0 +1,109 @@
> +/*
> + * Copyright (c) 2017, Linaro Limited
> + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "clk-pll.h"
> +#include "clk-regmap.h"
> +
> +static const struct pll_freq_tbl a53pll_freq[] = {
> + {  99840, 52, 0x0, 0x1, 0 },
> + { 109440, 57, 0x0, 0x1, 0 },
> + { 115200, 62, 0x0, 0x1, 0 },
> + { 120960, 63, 0x0, 0x1, 0 },
> + { 124800, 65, 0x0, 0x1, 0 },
> + { 136320, 71, 0x0, 0x1, 0 },
> + { 140160, 73, 0x0, 0x1, 0 },
> +};
> +
> +static const struct regmap_config a53pll_regmap_config = {
> + .reg_bits   = 32,
> + .reg_stride = 4,
> + .val_bits   = 32,
> + .max_register   = 0x40,
> + .fast_io= true,
> +};
> +
> +static int qcom_a53pll_remove(struct platform_device *pdev)
> +{
> + of_clk_del_provider(pdev->dev.of_node);
> + return 0;
> +}
> +
> +static int qcom_a53pll_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct regmap *regmap;
> + struct resource *res;
> + struct clk_pll *pll;
> + void __iomem *base;
> + struct clk_init_data init = { };
> + int ret;
> +
> + pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
> + if (!pll)
> + return -ENOMEM;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + base = devm_ioremap_resource(dev, res);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + regmap = devm_regmap_init_mmio(dev, base, &a53pll_regmap_conf

Re: [PATCH v10 2/6] mailbox: qcom: Create APCS child device for clock controller

2017-12-04 Thread Bjorn Andersson
On Fri 01 Dec 09:02 PST 2017, Georgi Djakov wrote:

> There is a clock controller functionality provided by the APCS hardware
> block of msm8916 devices. The device-tree would represent an APCS node
> with both mailbox and clock provider properties.
> Create a platform child device for the clock controller functionality so
> the driver can probe and use APCS as parent.
> 
> Signed-off-by: Georgi Djakov 

Acked-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  drivers/mailbox/qcom-apcs-ipc-mailbox.c | 11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c 
> b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
> index ab344bc6fa63..57bde0dfd12f 100644
> --- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c
> +++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
> @@ -29,6 +29,7 @@ struct qcom_apcs_ipc {
>  
>   struct regmap *regmap;
>   unsigned long offset;
> + struct platform_device *clk;
>  };
>  
>  static const struct regmap_config apcs_regmap_config = {
> @@ -96,6 +97,14 @@ static int qcom_apcs_ipc_probe(struct platform_device 
> *pdev)
>   return ret;
>   }
>  
> + if (of_device_is_compatible(np, "qcom,msm8916-apcs-kpss-global")) {
> + apcs->clk = platform_device_register_data(&pdev->dev,
> +   
> "qcom-apcs-msm8916-clk",
> +   -1, NULL, 0);
> + if (IS_ERR(apcs->clk))
> + dev_err(&pdev->dev, "failed to register APCS clk\n");
> + }
> +
>   platform_set_drvdata(pdev, apcs);
>  
>   return 0;
> @@ -104,8 +113,10 @@ static int qcom_apcs_ipc_probe(struct platform_device 
> *pdev)
>  static int qcom_apcs_ipc_remove(struct platform_device *pdev)
>  {
>   struct qcom_apcs_ipc *apcs = platform_get_drvdata(pdev);
> + struct platform_device *clk = apcs->clk;
>  
>   mbox_controller_unregister(&apcs->mbox);
> + platform_device_unregister(clk);
>  
>   return 0;
>  }


Re: [PATCH v10 6/6] clk: qcom: Add APCS clock controller support

2017-12-04 Thread Bjorn Andersson
On Fri 01 Dec 09:02 PST 2017, Georgi Djakov wrote:
[..]
> diff --git a/drivers/clk/qcom/apcs-msm8916.c b/drivers/clk/qcom/apcs-msm8916.c
> new file mode 100644
> index ..f71039ff2347
> --- /dev/null
> +++ b/drivers/clk/qcom/apcs-msm8916.c
> @@ -0,0 +1,149 @@
> +/*
> + * Qualcomm APCS clock controller driver
> + *
> + * Copyright (c) 2017, Linaro Limited
> + * Author: Georgi Djakov 
> + *
> + * SPDX-License-Identifier: GPL-2.0

The SPDX-License-Identifier should be on the first line in the file,
commented by //

> + */
> +
[..]
> +static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev)
> +{
> + struct device *dev = pdev->dev.parent;

Call this "parent" instead.

> + struct device_node *np = dev->of_node;
> + struct clk_regmap_mux_div *a53cc;
> + struct regmap *regmap;
> + struct clk_init_data init = { };
> + int ret;
> +
> + regmap = dev_get_regmap(dev, NULL);
> + if (IS_ERR(regmap)) {
> + ret = PTR_ERR(regmap);
> + dev_err(dev, "failed to get regmap: %d\n", ret);

dev_* prints should be on &pdev->dev and not on parent device.

> + return ret;
> + }
> +
> + a53cc = devm_kzalloc(dev, sizeof(*a53cc), GFP_KERNEL);

Perform this allocation on behalf of this device (i.e. &pdev->dev and
not parent)

> + if (!a53cc)
> + return -ENOMEM;
> +
> + init.name = "a53mux";
> + init.parent_names = gpll0_a53cc;
> + init.num_parents = ARRAY_SIZE(gpll0_a53cc);
> + init.ops = &clk_regmap_mux_div_ops;
> + init.flags = CLK_SET_RATE_PARENT;
> +
> + a53cc->clkr.hw.init = &init;
> + a53cc->clkr.regmap = regmap;
> + a53cc->reg_offset = 0x50;
> + a53cc->hid_width = 5;
> + a53cc->hid_shift = 0;
> + a53cc->src_width = 3;
> + a53cc->src_shift = 8;
> + a53cc->parent_map = gpll0_a53cc_map;
> +
> + a53cc->pclk = devm_clk_get(dev, NULL);
> + if (IS_ERR(a53cc->pclk)) {
> + ret = PTR_ERR(a53cc->pclk);
> + dev_err(dev, "failed to get clk: %d\n", ret);
> + return ret;
> + }
> +
> + a53cc->clk_nb.notifier_call = a53cc_notifier_cb;
> + ret = clk_notifier_register(a53cc->pclk, &a53cc->clk_nb);
> + if (ret) {
> + dev_err(dev, "failed to register clock notifier: %d\n", ret);
> + return ret;
> + }
> +
> + ret = devm_clk_register_regmap(dev, &a53cc->clkr);

This you can do on the &pdev->dev, it won't find a regmap on this node
and will try the parent.

> + if (ret) {
> + dev_err(dev, "failed to register regmap clock: %d\n", ret);
> + goto err;
> + }
> +
> + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get,

Be explicit here and do parent->of_node.

> +  &a53cc->clkr.hw);
> + if (ret) {
> + dev_err(dev, "failed to add clock provider: %d\n", ret);
> + goto err;
> + }
> +
> + platform_set_drvdata(pdev, a53cc);
> +
> + return 0;
> +
> +err:
> + clk_notifier_unregister(a53cc->pclk, &a53cc->clk_nb);
> + return ret;
> +}
> +
> +static int qcom_apcs_msm8916_clk_remove(struct platform_device *pdev)
> +{
> + struct clk_regmap_mux_div *a53cc = platform_get_drvdata(pdev);
> +
> + clk_notifier_unregister(a53cc->pclk, &a53cc->clk_nb);
> + of_clk_del_provider(pdev->dev.of_node);

You registered the provider on pdev->dev->parent.of_node.

> +
> + return 0;
> +}
> +

Regards,
Bjorn


Re: [LKP] [lkp-robot] [fs/locks] 52306e882f: stress-ng.lockofd.ops_per_sec -11% regression

2017-12-04 Thread Aaron Lu
On Wed, Nov 08, 2017 at 03:22:33PM +0800, Aaron Lu wrote:
> On Thu, Sep 28, 2017 at 04:02:23PM +0800, kernel test robot wrote:
> > 
> > Greeting,
> > 
> > FYI, we noticed a -11% regression of stress-ng.lockofd.ops_per_sec due to 
> > commit:
> > 
> > 
> > commit: 52306e882f77d3fd73f91435c41373d634acc5d2 ("fs/locks: Use allocation 
> > rather than the stack in fcntl_getlk()")
> > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git master
> 
> It's been a while, I wonder what do you think of this regression?
> 
> The test stresses byte-range locks AFAICS and since the commit uses
> dynamic allocation instead of stack for the 'struct file_lock', it sounds
> natural the performance regressed for this test.
> 
> Now the question is, do we care about the performance regression here?

Appreciated it if you can share your opinion on this, thanks.

Regards,
Aaron
 
> Feel free to let me know if you need any other data.
> 
> Thanks for your time.
> 
> > in testcase: stress-ng
> > on test machine: 88 threads Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz with 
> > 128G memory
> > with following parameters:
> > 
> > testtime: 1s
> > class: filesystem
> > cpufreq_governor: performance
> > 
> > 
> > 
> > 
> > Details are as below:
> > -->
> > 
> > 
> > To reproduce:
> > 
> > git clone https://github.com/intel/lkp-tests.git
> > cd lkp-tests
> > bin/lkp install job.yaml  # job file is attached in this email
> > bin/lkp run job.yaml
> > 
> > testcase/path_params/tbox_group/run: 
> > stress-ng/1s-filesystem-performance/lkp-bdw-ep6
> > 
> >v4.13-rc1  52306e882f77d3fd73f91435c4  
> >   --  
> >  %stddev  change %stddev
> >  \  |\  
> >  1.219e+08 -11%   1.09e+08stress-ng.lockofd.ops_per_sec
> >  1.229e+08 -10%  1.103e+08stress-ng.locka.ops_per_sec
> >  1.233e+08 -10%  1.105e+08stress-ng.locka.ops
> >  1.223e+08 -11%  1.093e+08stress-ng.lockofd.ops
> >1061237  10%1168476stress-ng.eventfd.ops
> >1061205  10%1168414stress-ng.eventfd.ops_per_sec
> >2913174   9%3163165
> > stress-ng.time.voluntary_context_switches
> >  89.90  -4%  86.58stress-ng.time.user_time
> >  26510  -6%  24822stress-ng.io.ops
> >  26489  -6%  24798stress-ng.io.ops_per_sec
> > 885499 ± 14%18%1042236perf-stat.cpu-migrations
> >  2.537e+08  10%  2.783e+08perf-stat.node-store-misses
> >1067830 ±  4% 8%1154877 ±  3%  perf-stat.page-faults
> >5384755 ±  4% 7%5747689perf-stat.context-switches
> >  32.28   7%  34.42 ±  3%  
> > perf-stat.node-store-miss-rate%
> >  12245 ±110% -7e+03   5367 ± 29%  
> > latency_stats.avg.call_usermodehelper_exec.__request_module.get_fs_type.do_mount.SyS_mount.entry_SYSCALL_64_fastpath
> > 311261 ±173% -3e+05  11702 ±100%  
> > latency_stats.avg.tty_release_struct.tty_release.__fput.fput.task_work_run.exit_to_usermode_loop.syscall_return_slowpath.entry_SYSCALL_64_fastpath
> >   1472 ± 60%  4e+03   5144 ± 97%  
> > latency_stats.max.sync_inodes_sb.sync_inodes_one_sb.iterate_supers.sys_sync.entry_SYSCALL_64_fastpath
> >225 ± 39%  3e+03   3698 ±132%  
> > latency_stats.max.rpc_wait_bit_killable.__rpc_wait_for_completion_task.nfs4_do_close.[nfsv4].__nfs4_close.[nfsv4].nfs4_close_sync.[nfsv4].nfs4_close_context.[nfsv4].__put_nfs_open_context.nfs_file_clear_open_context.nfs_file_release.__fput.fput.task_work_run
> >228 ± 34%  3e+03   3103 ±159%  
> > latency_stats.max.rpc_wait_bit_killable.__rpc_wait_for_completion_task.nfs4_run_open_task.[nfsv4].nfs4_do_open.[nfsv4].nfs4_atomic_open.[nfsv4].nfs4_file_open.[nfsv4].do_dentry_open.vfs_open.path_openat.do_filp_open.do_sys_open.SyS_open
> >270 ± 24%  3e+03   3110 ±162%  
> > latency_stats.max.io_schedule.wait_on_page_bit_common.__filemap_fdatawait_range.filemap_write_and_wait_range.nfs_file_fsync.vfs_fsync_range.vfs_fsync.nfs4_file_flush.[nfsv4].filp_close.do_dup2.SyS_dup2.entry_SYSCALL_64_fastpath
> >  12245 ±110% -7e+03   5367 ± 29%  
> > latency_stats.max.call_usermodehelper_exec.__request_module.get_fs_type.do_mount.SyS_mount.entry_SYSCALL_64_fastpath
> > 927506 ±173% -9e+05  11702 ±100%  
> > latency_stats.max.tty_release_struct.tty_release.__fput.fput.task_work_run.exit_to_usermode_loop.syscall_return_slowpath.entry_SYSCALL_64_fastpath
> >   7892 ± 54%  3e+04  33793 ±131%  
> > latency_stats.sum.sync_inodes_sb.sync_inodes_one_sb.iterate_supers.sys_sync.entry_SYSCAL

[PATCHv2 2/2] mtd: m25p80: restore the status of SPI flash when stop using it

2017-12-04 Thread Zhiqiang Hou
From: Hou Zhiqiang 

Implement .shutdown function to restore the status in reboot
process, and add the same operation to the .remove function.

Signed-off-by: Hou Zhiqiang 
---
V2:
 - Changed code format slightly.

 drivers/mtd/devices/m25p80.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index dbe6a1de2bb8..a4e18f6aaa33 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -307,10 +307,18 @@ static int m25p_remove(struct spi_device *spi)
 {
struct m25p *flash = spi_get_drvdata(spi);
 
+   spi_nor_restore(&flash->spi_nor);
+
/* Clean up MTD stuff. */
return mtd_device_unregister(&flash->spi_nor.mtd);
 }
 
+static void m25p_shutdown(struct spi_device *spi)
+{
+   struct m25p *flash = spi_get_drvdata(spi);
+
+   spi_nor_restore(&flash->spi_nor);
+}
 /*
  * Do NOT add to this array without reading the following:
  *
@@ -386,6 +394,7 @@ static struct spi_driver m25p80_driver = {
.id_table   = m25p_ids,
.probe  = m25p_probe,
.remove = m25p_remove,
+   .shutdown   = m25p_shutdown,
 
/* REVISIT: many of these chips have deep power-down modes, which
 * should clearly be entered on suspend() to minimize power use.
-- 
2.14.1



[PATCHv2 1/2] mtd: spi-nor: add an API to restore the status of SPI flash chip

2017-12-04 Thread Zhiqiang Hou
From: Hou Zhiqiang 

Add this API to restore the status of SPI flash chip to the default
such as addressing mode, whenever detach the driver from device or
reboot the system.

Signed-off-by: Hou Zhiqiang 
---
V2:
 - Changed the API name and added the comments and kernel document for it.
 - Export this symbol for modules.

 Documentation/mtd/spi-nor.txt |  3 +++
 drivers/mtd/spi-nor/spi-nor.c | 10 ++
 include/linux/mtd/spi-nor.h   |  6 ++
 3 files changed, 19 insertions(+)

diff --git a/Documentation/mtd/spi-nor.txt b/Documentation/mtd/spi-nor.txt
index 548d6306ebca..da1fbff5a24c 100644
--- a/Documentation/mtd/spi-nor.txt
+++ b/Documentation/mtd/spi-nor.txt
@@ -60,3 +60,6 @@ The main API is spi_nor_scan(). Before you call the hook, a 
driver should
 initialize the necessary fields for spi_nor{}. Please see
 drivers/mtd/spi-nor/spi-nor.c for detail. Please also refer to fsl-quadspi.c
 when you want to write a new driver for a SPI NOR controller.
+Another API is spi_nor_restore(), this is used to restore the status of SPI
+flash chip such as addressing mode. Call it whenever detach the driver from
+device or reboot the system.
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index bc266f70a15b..4a925378d434 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -2713,6 +2713,16 @@ static void spi_nor_resume(struct mtd_info *mtd)
dev_err(dev, "resume() failed\n");
 }
 
+void spi_nor_restore(struct spi_nor *nor)
+{
+   /* restore the addressing mode */
+   if ((nor->addr_width == 4) &&
+   (JEDEC_MFR(nor->info) != SNOR_MFR_SPANSION) &&
+   !(nor->info->flags & SPI_NOR_4B_OPCODES))
+   set_4byte(nor, nor->info, 0);
+}
+EXPORT_SYMBOL_GPL(spi_nor_restore);
+
 int spi_nor_scan(struct spi_nor *nor, const char *name,
 const struct spi_nor_hwcaps *hwcaps)
 {
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index d0c66a0975cf..0a182c3d0884 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -399,4 +399,10 @@ struct spi_nor_hwcaps {
 int spi_nor_scan(struct spi_nor *nor, const char *name,
 const struct spi_nor_hwcaps *hwcaps);
 
+/*
+ * spi_nor_restore_addr_mode() - restore the status of SPI NOR
+ * @nor:   the spi_nor structure
+ */
+void spi_nor_restore(struct spi_nor *nor);
+
 #endif
-- 
2.14.1



[PATCHv2 0/2] mtd: m25p80: restore the addressing mode when stop using the flash

2017-12-04 Thread Zhiqiang Hou
From: Hou Zhiqiang 

To be compatible with legacy device, reset the addressing mode
to the default mode. Such as Freescale eSPI boot, it copies the
images from SPI flash without firing a reset signal previously,
so the reboot command will fail without reseting the addressing
mode of SPI flash.

Hou Zhiqiang (2):
  mtd: spi-nor: add an API to restore the status of SPI flash chip
  mtd: m25p80: restore the status of SPI flash when stop using it

 Documentation/mtd/spi-nor.txt |  3 +++
 drivers/mtd/devices/m25p80.c  |  9 +
 drivers/mtd/spi-nor/spi-nor.c | 10 ++
 include/linux/mtd/spi-nor.h   |  6 ++
 4 files changed, 28 insertions(+)

-- 
2.14.1



Re: [PATCH v10 5/6] dt-bindings: mailbox: qcom: Document the APCS clock binding

2017-12-04 Thread Bjorn Andersson
On Fri 01 Dec 09:02 PST 2017, Georgi Djakov wrote:

> Update the binding documentation for APCS to mention that the APCS
> hardware block also expose a clock controller functionality.
> 
> The APCS clock controller is a mux and half-integer divider. It has the
> main CPU PLL as an input and provides the clock for the application CPU.
> 
> Signed-off-by: Georgi Djakov 

Nice!

Acked-by: Bjorn Andersson 

Regards,
Bjorn

> ---
>  .../bindings/mailbox/qcom,apcs-kpss-global.txt | 18 
> ++
>  1 file changed, 18 insertions(+)
> 
> diff --git 
> a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt 
> b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt
> index fb961c310f44..16964f0c1773 100644
> --- a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt
> +++ b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt
> @@ -15,12 +15,21 @@ platforms.
>   Usage: required
>   Value type: 
>   Definition: must specify the base address and size of the global block
> +- clocks:
> + Usage: required if #clocks-cells property is present
> + Value type: 
> + Definition: phandle to the input PLL, which feeds the APCS mux/divider
>  
>  - #mbox-cells:
>   Usage: required
>   Value type: 
>   Definition: as described in mailbox.txt, must be 1
>  
> +- #clock-cells:
> + Usage: optional
> + Value type: 
> + Definition: as described in clock.txt, must be 0
> +
>  
>  = EXAMPLE
>  The following example describes the APCS HMSS found in MSM8996 and part of 
> the
> @@ -44,3 +53,12 @@ GLINK RPM referencing the "rpm_hlos" doorbell therein.
>   mbox-names = "rpm_hlos";
>   };
>  
> +Below is another example of the APCS binding on MSM8916 platforms:
> +
> + apcs: mailbox@b011000 {
> + compatible = "qcom,msm8916-apcs-kpss-global";
> + reg = <0xb011000 0x1000>;
> + #mbox-cells = <1>;
> + clocks = <&a53pll>;
> + #clock-cells = <0>;
> + };


Re: [PATCH v2 0/4] lockdep/crossrelease: Apply crossrelease to page locks

2017-12-04 Thread Byungchul Park

On 12/5/2017 2:30 PM, Matthew Wilcox wrote:

On Mon, Dec 04, 2017 at 02:16:19PM +0900, Byungchul Park wrote:

For now, wait_for_completion() / complete() works with lockdep, add
lock_page() / unlock_page() and its family to lockdep support.

Changes from v1
  - Move lockdep_map_cross outside of page_ext to make it flexible
  - Prevent allocating lockdep_map per page by default
  - Add a boot parameter allowing the allocation for debugging

Byungchul Park (4):
   lockdep: Apply crossrelease to PG_locked locks
   lockdep: Apply lock_acquire(release) on __Set(__Clear)PageLocked
   lockdep: Move data of CONFIG_LOCKDEP_PAGELOCK from page to page_ext
   lockdep: Add a boot parameter enabling to track page locks using
 lockdep and disable it by default


I don't like the way you've structured this patch series; first adding
the lockdep map to struct page, then moving it to page_ext.


Hello,

I will make them into one patch.


I also don't like it that you've made CONFIG_LOCKDEP_PAGELOCK not
individually selectable.  I might well want a kernel with crosslock
support, but only for completions.


OK then, I will make it individually selectable.

I want to know others' opinions as well.

Thank you for the opinions. I will apply yours next spin.

--
Thanks,
Byungchul


Re: [PATCH v3 07/16] iommu/vt-d: assign PFSID in device TLB invalidation

2017-12-04 Thread Lu Baolu
Hi,

On 11/18/2017 02:55 AM, Jacob Pan wrote:
> When SRIOV VF device IOTLB is invalidated, we need to provide
> the PF source SID such that IOMMU hardware can gauge the depth
> of invalidation queue which is shared among VFs. This is needed
> when device invalidation throttle (DIT) capability is supported.
>
> Signed-off-by: Jacob Pan 
> ---
>  drivers/iommu/intel-iommu.c | 13 +
>  include/linux/intel-iommu.h |  3 +++
>  2 files changed, 16 insertions(+)
>
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 000b2b3..e1bd219 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -1459,6 +1459,19 @@ static void iommu_enable_dev_iotlb(struct 
> device_domain_info *info)
>   return;
>  
>   pdev = to_pci_dev(info->dev);
> + /* For IOMMU that supports device IOTLB throttling (DIT), we assign
> +  * PFSID to the invalidation desc of a VF such that IOMMU HW can gauge
> +  * queue depth at PF level. If DIT is not set, PFSID will be treated as
> +  * reserved, which should be set to 0.
> +  */
> + if (!ecap_dit(info->iommu->ecap))
> + info->pfsid = 0;
> + else if (pdev && pdev->is_virtfn) {
> + if (ecap_dit(info->iommu->ecap))

Isn't this condition always true when it comes here?

Best regards,
Lu Baolu

> + dev_warn(&pdev->dev, "SRIOV VF device IOTLB enabled 
> without flow control\n");
> + info->pfsid = PCI_DEVID(pdev->physfn->bus->number, 
> pdev->physfn->devfn);
> + } else
> + info->pfsid = PCI_DEVID(info->bus, info->devfn);
>  
>  #ifdef CONFIG_INTEL_IOMMU_SVM
>   /* The PCIe spec, in its wisdom, declares that the behaviour of
> diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
> index 7f05e36..6956a4e 100644
> --- a/include/linux/intel-iommu.h
> +++ b/include/linux/intel-iommu.h
> @@ -112,6 +112,7 @@
>   * Extended Capability Register
>   */
>  
> +#define ecap_dit(e)  ((e >> 41) & 0x1)
>  #define ecap_pasid(e)((e >> 40) & 0x1)
>  #define ecap_pss(e)  ((e >> 35) & 0x1f)
>  #define ecap_eafs(e) ((e >> 34) & 0x1)
> @@ -285,6 +286,7 @@ enum {
>  #define QI_DEV_IOTLB_SID(sid)((u64)((sid) & 0x) << 32)
>  #define QI_DEV_IOTLB_QDEP(qdep)  (((qdep) & 0x1f) << 16)
>  #define QI_DEV_IOTLB_ADDR(addr)  ((u64)(addr) & VTD_PAGE_MASK)
> +#define QI_DEV_IOTLB_PFSID(pfsid) (((u64)(pfsid & 0xf) << 12) | ((u64)(pfsid 
> & 0xff0) << 48))
>  #define QI_DEV_IOTLB_SIZE1
>  #define QI_DEV_IOTLB_MAX_INVS32
>  
> @@ -475,6 +477,7 @@ struct device_domain_info {
>   struct list_head global; /* link to global list */
>   u8 bus; /* PCI bus number */
>   u8 devfn;   /* PCI devfn number */
> + u16 pfsid;  /* SRIOV physical function source ID */
>   u8 pasid_supported:3;
>   u8 pasid_enabled:1;
>   u8 pri_supported:1;



Re: [PATCH v3 06/16] iommu/vt-d: add svm/sva invalidate function

2017-12-04 Thread Lu Baolu
Hi,

On 11/18/2017 02:55 AM, Jacob Pan wrote:
> This patch adds Intel VT-d specific function to implement
> iommu passdown invalidate API for shared virtual address.
>
> The use case is for supporting caching structure invalidation
> of assigned SVM capable devices. Emulated IOMMU exposes queue
> invalidation capability and passes down all descriptors from the guest
> to the physical IOMMU.
>
> The assumption is that guest to host device ID mapping should be
> resolved prior to calling IOMMU driver. Based on the device handle,
> host IOMMU driver can replace certain fields before submit to the
> invalidation queue.
>
> Signed-off-by: Liu, Yi L 
> Signed-off-by: Jacob Pan 
> Signed-off-by: Ashok Raj 
> ---
>  drivers/iommu/intel-iommu.c | 200 
> +++-
>  include/linux/intel-iommu.h |  17 +++-
>  2 files changed, 211 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 556bdd2..000b2b3 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -4981,6 +4981,183 @@ static void intel_iommu_detach_device(struct 
> iommu_domain *domain,
>   dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
>  }
>  
> +/*
> + * 3D array for converting IOMMU generic type-granularity to VT-d granularity
> + * X indexed by enum iommu_inv_type
> + * Y indicates request without and with PASID
> + * Z indexed by enum enum iommu_inv_granularity
> + *
> + * For an example, if we want to find the VT-d granularity encoding for IOTLB
> + * type, DMA request with PASID, and page selective. The look up indices are:
> + * [1][1][8], where
> + * 1: IOMMU_INV_TYPE_TLB
> + * 1: with PASID
> + * 8: IOMMU_INV_GRANU_PAGE_PASID
> + *
> + */
> +const static int 
> inv_type_granu_map[IOMMU_INV_NR_TYPE][2][IOMMU_INV_NR_GRANU] = {
> + /* extended dev IOTLBs, for dev-IOTLB, only global is valid,
> +for dev-EXIOTLB, two valid granu */
> + {
> + {1},
> + {0, 0, 0, 0, 1, 1, 0, 0, 0}
> + },
> + /* IOTLB and EIOTLB */
> + {
> + {1, 1, 0, 1, 0, 0, 0, 0, 0},
> + {0, 0, 0, 0, 1, 0, 1, 1, 1}
> + },
> + /* PASID cache */
> + {
> + {0},
> + {0, 0, 0, 0, 1, 1, 0, 0, 0}
> + },
> + /* context cache */
> + {
> + {1, 1, 1}
> + }
> +};
> +
> +const static u64 
> inv_type_granu_table[IOMMU_INV_NR_TYPE][2][IOMMU_INV_NR_GRANU] = {
> + /* extended dev IOTLBs, only global is valid */
> + {
> + {QI_DEV_IOTLB_GRAN_ALL},
> + {0, 0, 0, 0, QI_DEV_IOTLB_GRAN_ALL, 
> QI_DEV_IOTLB_GRAN_PASID_SEL, 0, 0, 0}
> + },
> + /* IOTLB and EIOTLB */
> + {
> + {DMA_TLB_GLOBAL_FLUSH, DMA_TLB_DSI_FLUSH, 0, DMA_TLB_PSI_FLUSH},
> + {0, 0, 0, 0, QI_GRAN_ALL_ALL, 0, QI_GRAN_NONG_ALL, 
> QI_GRAN_NONG_PASID, QI_GRAN_PSI_PASID}
> + },
> + /* PASID cache */
> + {
> + {0},
> + {0, 0, 0, 0, QI_PC_ALL_PASIDS, QI_PC_PASID_SEL}
> + },
> + /* context cache */
> + {
> + {DMA_CCMD_GLOBAL_INVL, DMA_CCMD_DOMAIN_INVL, 
> DMA_CCMD_DEVICE_INVL}
> + }
> +};
> +
> +static inline int to_vtd_granularity(int type, int granu, int with_pasid, 
> u64 *vtd_granu)
> +{
> + if (type >= IOMMU_INV_NR_TYPE || granu >= IOMMU_INV_NR_GRANU || 
> with_pasid > 1)
> + return -EINVAL;
> +
> + if (inv_type_granu_map[type][with_pasid][granu] == 0)
> + return -EINVAL;
> +
> + *vtd_granu = inv_type_granu_table[type][with_pasid][granu];
> +
> + return 0;
> +}
> +
> +static int intel_iommu_sva_invalidate(struct iommu_domain *domain,
> + struct device *dev, struct tlb_invalidate_info *inv_info)
> +{
> + struct intel_iommu *iommu;
> + struct dmar_domain *dmar_domain = to_dmar_domain(domain);
> + struct device_domain_info *info;
> + struct pci_dev *pdev;
> + u16 did, sid, pfsid;
> + u8 bus, devfn;
> + int ret = 0;
> + u64 granu;
> + unsigned long flags;
> +
> + if (!inv_info || !dmar_domain)
> + return -EINVAL;
> +
> + iommu = device_to_iommu(dev, &bus, &devfn);
> + if (!iommu)
> + return -ENODEV;
> +
> + if (!dev || !dev_is_pci(dev))
> + return -ENODEV;
> +
> + did = dmar_domain->iommu_did[iommu->seq_id];
> + sid = PCI_DEVID(bus, devfn);
> + ret = to_vtd_granularity(inv_info->hdr.type, inv_info->granularity,
> + !!(inv_info->flags & 
> IOMMU_INVALIDATE_PASID_TAGGED), &granu);
> + if (ret) {
> + pr_err("Invalid range type %d, granu %d\n", inv_info->hdr.type,
> + inv_info->granularity);
> + return ret;
> + }
> +
> + spin_lock(&iommu->lock);
> + spin_lock_irqsave(&device_domain_lock, flags);
> +
> + switch (inv_info->hdr.type) {
> + case IOMMU_INV_TYPE_CONTEXT:
> + iommu->flush.flush_context(iommu,

Re: [PATCH] cpufreq: powernv: Define methods to parse positive & negative pstates

2017-12-04 Thread Viresh Kumar
On 30-11-17, 10:13, Shilpasri G Bhat wrote:
> From: "Gautham R. Shenoy" 
> 
> Pstates are 8bit values but on POWER8 they are negative and on POWER9
> they are positive. This patch adds helper routines to differentiate
> the sign to read the correct pstate value.
> 
> Signed-off-by: Gautham R. Shenoy 
> Tested-by: Shilpasri G Bhat 
> ---
>  drivers/cpufreq/powernv-cpufreq.c | 43 
> ++-
>  1 file changed, 33 insertions(+), 10 deletions(-)

Acked-by: Viresh Kumar 

-- 
viresh


Re: [PATCH 1/1] mm/page_owner: ignore everything below the IRQ entry point

2017-12-04 Thread kbuild test robot
Hi Maninder,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on mmotm/master]
[also build test ERROR on v4.15-rc2 next-20171204]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Maninder-Singh/mm-page_owner-ignore-everything-below-the-IRQ-entry-point/20171205-122901
base:   git://git.cmpxchg.org/linux-mmotm.git master
config: blackfin-allmodconfig (attached as .config)
compiler: bfin-uclinux-gcc (GCC) 6.2.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=blackfin 

All errors (new ones prefixed by >>):

   In file included from include/linux/interrupt.h:22:0,
from include/linux/kernel_stat.h:9,
from arch/blackfin/kernel/asm-offsets.c:11:
>> arch/blackfin/include/asm/sections.h:35:19: error: redefinition of 
>> 'arch_is_kernel_text'
static inline int arch_is_kernel_text(unsigned long addr)
  ^~~
   In file included from include/linux/stacktrace.h:6:0,
from include/linux/lockdep.h:29,
from include/linux/rcupdate.h:42,
from include/linux/rculist.h:11,
from include/linux/pid.h:5,
from include/linux/sched.h:14,
from arch/blackfin/kernel/asm-offsets.c:10:
   include/asm-generic/sections.h:63:19: note: previous definition of 
'arch_is_kernel_text' was here
static inline int arch_is_kernel_text(unsigned long addr)
  ^~~
   In file included from include/linux/interrupt.h:22:0,
from include/linux/kernel_stat.h:9,
from arch/blackfin/kernel/asm-offsets.c:11:
>> arch/blackfin/include/asm/sections.h:48:19: error: redefinition of 
>> 'arch_is_kernel_data'
static inline int arch_is_kernel_data(unsigned long addr)
  ^~~
   In file included from include/linux/stacktrace.h:6:0,
from include/linux/lockdep.h:29,
from include/linux/rcupdate.h:42,
from include/linux/rculist.h:11,
from include/linux/pid.h:5,
from include/linux/sched.h:14,
from arch/blackfin/kernel/asm-offsets.c:10:
   include/asm-generic/sections.h:70:19: note: previous definition of 
'arch_is_kernel_data' was here
static inline int arch_is_kernel_data(unsigned long addr)
  ^~~
   make[2]: *** [arch/blackfin/kernel/asm-offsets.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

vim +/arch_is_kernel_text +35 arch/blackfin/include/asm/sections.h

e56770fb Mike Frysinger 2009-09-22  33  
e56770fb Mike Frysinger 2009-09-22  34  /* Blackfin systems have discontinuous 
memory map and no virtualized memory */
e56770fb Mike Frysinger 2009-09-22 @35  static inline int 
arch_is_kernel_text(unsigned long addr)
e56770fb Mike Frysinger 2009-09-22  36  {
e56770fb Mike Frysinger 2009-09-22  37  return
e56770fb Mike Frysinger 2009-09-22  38  (L1_CODE_LENGTH &&
e56770fb Mike Frysinger 2009-09-22  39   addr >= (unsigned 
long)_stext_l1 &&
e56770fb Mike Frysinger 2009-09-22  40   addr <  (unsigned 
long)_etext_l1)
e56770fb Mike Frysinger 2009-09-22  41  ||
e56770fb Mike Frysinger 2009-09-22  42  (L2_LENGTH &&
e56770fb Mike Frysinger 2009-09-22  43   addr >= (unsigned 
long)_stext_l2 &&
e56770fb Mike Frysinger 2009-09-22  44   addr <  (unsigned 
long)_etext_l2);
e56770fb Mike Frysinger 2009-09-22  45  }
e56770fb Mike Frysinger 2009-09-22  46  #define arch_is_kernel_text(addr) 
arch_is_kernel_text(addr)
e56770fb Mike Frysinger 2009-09-22  47  
e56770fb Mike Frysinger 2009-09-22 @48  static inline int 
arch_is_kernel_data(unsigned long addr)
e56770fb Mike Frysinger 2009-09-22  49  {
e56770fb Mike Frysinger 2009-09-22  50  return
e56770fb Mike Frysinger 2009-09-22  51  (L1_DATA_A_LENGTH &&
e56770fb Mike Frysinger 2009-09-22  52   addr >= (unsigned 
long)_sdata_l1 &&
e56770fb Mike Frysinger 2009-09-22  53   addr <  (unsigned 
long)_ebss_l1)
e56770fb Mike Frysinger 2009-09-22  54  ||
e56770fb Mike Frysinger 2009-09-22  55  (L1_DATA_B_LENGTH &&
e56770fb Mike Frysinger 2009-09-22  56  

Re: [PATCH V1 4/4] qcom: spmi-wled: Add auto-calibration logic support

2017-12-04 Thread Bjorn Andersson
On Thu 16 Nov 04:18 PST 2017, Kiran Gunda wrote:

> The auto-calibration algorithm checks if the current WLED sink
> configuration is valid. It tries enabling every sink and checks
> if the OVP fault is observed. Based on this information it
> detects and enables the valid sink configuration. Auto calibration
> will be triggered when the OVP fault interrupts are seen frequently
> thereby it tries to fix the sink configuration.
> 

So it's not auto "calibration" it's auto "detection" of strings?

When is this feature needed?

> Signed-off-by: Kiran Gunda 
> ---
>  .../bindings/leds/backlight/qcom-spmi-wled.txt |   5 +
>  drivers/video/backlight/qcom-spmi-wled.c   | 304 
> -
>  2 files changed, 306 insertions(+), 3 deletions(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/leds/backlight/qcom-spmi-wled.txt 
> b/Documentation/devicetree/bindings/leds/backlight/qcom-spmi-wled.txt
> index d39ee93..f06c0cd 100644
> --- a/Documentation/devicetree/bindings/leds/backlight/qcom-spmi-wled.txt
> +++ b/Documentation/devicetree/bindings/leds/backlight/qcom-spmi-wled.txt
> @@ -94,6 +94,11 @@ The PMIC is connected to the host processor via SPMI bus.
>   Definition: Interrupt names associated with the interrupts.
>   Currently supported interrupts are "sc-irq" and "ovp-irq".
>  
> +- qcom,auto-calibration

qcom,auto-string-detect?

> + Usage:  optional
> + Value type: 
> + Definition: Enables auto-calibration of the WLED sink configuration.
> +
>  Example:
>  
>  qcom-wled@d800 {
> diff --git a/drivers/video/backlight/qcom-spmi-wled.c 
> b/drivers/video/backlight/qcom-spmi-wled.c
> index 8b2a77a..aee5c56 100644
> --- a/drivers/video/backlight/qcom-spmi-wled.c
> +++ b/drivers/video/backlight/qcom-spmi-wled.c
> @@ -38,11 +38,14 @@
>  #define  QCOM_WLED_CTRL_SC_FAULT_BIT BIT(2)
>  
>  #define QCOM_WLED_CTRL_INT_RT_STS0x10
> +#define  QCOM_WLED_CTRL_OVP_FLT_RT_STS_BIT   BIT(1)

The use of BIT() makes this a mask and not a bit number, so if you just
drop that you can afford to spell out the "FAULT" like the data sheet
does. Perhaps even making it QCOM_WLED_CTRL_OVP_FAULT_STATUS ?

>  
>  #define QCOM_WLED_CTRL_MOD_ENABLE0x46
>  #define  QCOM_WLED_CTRL_MOD_EN_MASK  BIT(7)
>  #define  QCOM_WLED_CTRL_MODULE_EN_SHIFT  7
>  
> +#define QCOM_WLED_CTRL_FDBK_OP   0x48

This is called WLED_CTRL_FEEDBACK_CONTROL, why the need to make it
unreadable?

> +
>  #define QCOM_WLED_CTRL_SWITCH_FREQ   0x4c
>  #define  QCOM_WLED_CTRL_SWITCH_FREQ_MASK GENMASK(3, 0)
>  
> @@ -99,6 +102,7 @@ struct qcom_wled_config {
>   int ovp_irq;
>   bool en_cabc;
>   bool ext_pfet_sc_pro_en;
> + bool auto_calib_enabled;
>  };
>  
>  struct qcom_wled {
> @@ -108,18 +112,25 @@ struct qcom_wled {
>   struct mutex lock;
>   struct qcom_wled_config cfg;
>   ktime_t last_sc_event_time;
> + ktime_t start_ovp_fault_time;
>   u16 sink_addr;
>   u16 ctrl_addr;
> + u16 auto_calibration_ovp_count;
>   u32 brightness;
>   u32 sc_count;
>   bool prev_state;
>   bool ovp_irq_disabled;
> + bool auto_calib_done;
> + bool force_mod_disable;
>  };
>  
>  static int qcom_wled_module_enable(struct qcom_wled *wled, int val)
>  {
>   int rc;
>  
> + if (wled->force_mod_disable)
> + return 0;
> +
>   rc = regmap_update_bits(wled->regmap, wled->ctrl_addr +
>   QCOM_WLED_CTRL_MOD_ENABLE, QCOM_WLED_CTRL_MOD_EN_MASK,
>   val << QCOM_WLED_CTRL_MODULE_EN_SHIFT);
> @@ -187,12 +198,10 @@ static int qcom_wled_set_brightness(struct qcom_wled 
> *wled, u16 brightness)
>   v[1] = (brightness >> 8) & 0xf;
>  
>   for (i = 0; (string_cfg >> i) != 0; i++) {
> - if (string_cfg & BIT(i)) {

Why was this check here in the first place, if it's now fine to
configure the brightness of all strings?

Also, a single-string config of 0b0001 will only set brightness on the
first string, while 0b1000 will set brightness on all strings.

>   rc = regmap_bulk_write(wled->regmap, wled->sink_addr +
>   QCOM_WLED_SINK_BRIGHT_LSB_REG(i), v, 2);
>   if (rc < 0)
>   return rc;
> - }
>   }
>  
>   return 0;
> @@ -294,6 +303,262 @@ static irqreturn_t qcom_wled_sc_irq_handler(int irq, 
> void *_wled)
>   return IRQ_HANDLED;
>  }
>  
> +#define AUTO_CALIB_BRIGHTNESS200
> +static int qcom_wled_auto_calibrate(struct qcom_wled *wled)
> +{
> + int rc = 0, i;
> + u32 sink_config = 0, int_sts;
> + u8 reg = 0, sink_test = 0, sink_valid = 0;
> + u8 string_cfg = wled->cfg.string_cfg;
> +
> + /* read configured sink configuration */
> + rc = regmap_read(wled->regmap, wled->sink_addr +
> + QCOM_WLED_SINK_CURR_SINK_EN, &sink_config);
> + if

[PATCH V2 3/4] cpu_cooling: Keep only one of_cpufreq*cooling_register() helper

2017-12-04 Thread Viresh Kumar
of_cpufreq_cooling_register() isn't used by anyone and so can be
removed, but then we would be left with two routines:
cpufreq_cooling_register() and of_cpufreq_power_cooling_register() that
would look odd.

Remove current implementation of of_cpufreq_cooling_register() and
rename of_cpufreq_power_cooling_register() as
of_cpufreq_cooling_register(). This simplifies lots of stuff.

Acked-by: Eduardo Valentin 
Signed-off-by: Viresh Kumar 
---
 Documentation/thermal/cpu-cooling-api.txt | 14 ++--
 drivers/cpufreq/arm_big_little.c  |  2 +-
 drivers/cpufreq/cpufreq-dt.c  |  2 +-
 drivers/cpufreq/mediatek-cpufreq.c|  2 +-
 drivers/cpufreq/qoriq-cpufreq.c   |  2 +-
 drivers/thermal/cpu_cooling.c | 28 ++--
 include/linux/cpu_cooling.h   | 53 ---
 7 files changed, 23 insertions(+), 80 deletions(-)

diff --git a/Documentation/thermal/cpu-cooling-api.txt 
b/Documentation/thermal/cpu-cooling-api.txt
index ea61e8bf7e2b..7a1c89db0419 100644
--- a/Documentation/thermal/cpu-cooling-api.txt
+++ b/Documentation/thermal/cpu-cooling-api.txt
@@ -26,24 +26,16 @@ the user. The registration APIs returns the cooling device 
pointer.
clip_cpus: cpumask of cpus where the frequency constraints will happen.
 
 1.1.2 struct thermal_cooling_device *of_cpufreq_cooling_register(
-   struct device_node *np, const struct cpumask *clip_cpus)
+   struct cpufreq_policy *policy)
 
 This interface function registers the cpufreq cooling device with
 the name "thermal-cpufreq-%x" linking it with a device tree node, in
 order to bind it via the thermal DT code. This api can support multiple
 instances of cpufreq cooling devices.
 
-np: pointer to the cooling device device tree node
-clip_cpus: cpumask of cpus where the frequency constraints will happen.
-
-1.1.3 struct thermal_cooling_device *of_cpufreq_power_cooling_register(
-   struct cpufreq_policy *policy)
-
-Similar to cpufreq_cooling_register, this function register a
-cpufreq cooling device with power extensions using the device tree
-information supplied by the np parameter.
+policy: CPUFreq policy.
 
-1.1.4 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
+1.1.3 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 
 This interface function unregisters the "thermal-cpufreq-%x" cooling 
device.
 
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index 3d5ed4ef3927..c56b57dcfda5 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -532,7 +532,7 @@ static void bL_cpufreq_ready(struct cpufreq_policy *policy)
if (cur_cluster >= MAX_CLUSTERS)
return;
 
-   cdev[cur_cluster] = of_cpufreq_power_cooling_register(policy);
+   cdev[cur_cluster] = of_cpufreq_cooling_register(policy);
 }
 
 static struct cpufreq_driver bL_cpufreq_driver = {
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index 1e7bec7694ab..de3d104c25d7 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -320,7 +320,7 @@ static void cpufreq_ready(struct cpufreq_policy *policy)
 {
struct private_data *priv = policy->driver_data;
 
-   priv->cdev = of_cpufreq_power_cooling_register(policy);
+   priv->cdev = of_cpufreq_cooling_register(policy);
 }
 
 static struct cpufreq_driver dt_cpufreq_driver = {
diff --git a/drivers/cpufreq/mediatek-cpufreq.c 
b/drivers/cpufreq/mediatek-cpufreq.c
index 6ff783e1b18a..f95975b76d98 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -311,7 +311,7 @@ static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
 {
struct mtk_cpu_dvfs_info *info = policy->driver_data;
 
-   info->cdev = of_cpufreq_power_cooling_register(policy);
+   info->cdev = of_cpufreq_cooling_register(policy);
 }
 
 static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c
index 3a665c18e14e..0562761a3dec 100644
--- a/drivers/cpufreq/qoriq-cpufreq.c
+++ b/drivers/cpufreq/qoriq-cpufreq.c
@@ -276,7 +276,7 @@ static void qoriq_cpufreq_ready(struct cpufreq_policy 
*policy)
 {
struct cpu_data *cpud = policy->driver_data;
 
-   cpud->cdev = of_cpufreq_power_cooling_register(policy);
+   cpud->cdev = of_cpufreq_cooling_register(policy);
 }
 
 static struct cpufreq_driver qoriq_cpufreq_driver = {
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 10199f7e1196..3371caf3095c 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -819,7 +819,6 @@ EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
 
 /**
  * of_cpufreq_cooling_register - function to create cpufreq cooling device.
- * @np: a valid struct device_node to th

[PATCH V2 1/4] cpu_cooling: Make of_cpufreq_power_cooling_register() parse DT

2017-12-04 Thread Viresh Kumar
All the callers of of_cpufreq_power_cooling_register() have almost
identical code and it makes more sense to move that code into the helper
as its all about reading DT properties.

This got rid of lot of redundant code.

Acked-by: Eduardo Valentin 
Signed-off-by: Viresh Kumar 
---
 Documentation/thermal/cpu-cooling-api.txt |  7 ++---
 drivers/cpufreq/arm_big_little.c  | 23 +--
 drivers/cpufreq/cpufreq-dt.c  | 27 +
 drivers/cpufreq/mediatek-cpufreq.c| 22 +-
 drivers/cpufreq/qoriq-cpufreq.c   | 14 +
 drivers/thermal/cpu_cooling.c | 49 +++
 include/linux/cpu_cooling.h   | 15 ++
 7 files changed, 41 insertions(+), 116 deletions(-)

diff --git a/Documentation/thermal/cpu-cooling-api.txt 
b/Documentation/thermal/cpu-cooling-api.txt
index 71653584cd03..4f6f5e9bb4d6 100644
--- a/Documentation/thermal/cpu-cooling-api.txt
+++ b/Documentation/thermal/cpu-cooling-api.txt
@@ -51,8 +51,7 @@ Dynamic power).  "plat_static_func" is a function to 
calculate the
 static power consumed by these cpus (See 2.2 Static power).
 
 1.1.4 struct thermal_cooling_device *of_cpufreq_power_cooling_register(
-struct device_node *np, const struct cpumask *clip_cpus, u32 capacitance,
-get_static_t plat_static_func)
+   struct cpufreq_policy *policy)
 
 Similar to cpufreq_power_cooling_register, this function register a
 cpufreq cooling device with power extensions using the device tree
@@ -76,8 +75,8 @@ cpu.  If you are using CONFIG_CPUFREQ_DT then the
 device.
 
 The `plat_static_func` parameter of `cpufreq_power_cooling_register()`
-and `of_cpufreq_power_cooling_register()` is optional.  If you don't
-provide it, only dynamic power will be considered.
+is optional.  If you don't provide it, only dynamic power will be
+considered.
 
 2.1 Dynamic power
 
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index 65ec5f01aa8d..3d5ed4ef3927 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -526,34 +526,13 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy)
 
 static void bL_cpufreq_ready(struct cpufreq_policy *policy)
 {
-   struct device *cpu_dev = get_cpu_device(policy->cpu);
int cur_cluster = cpu_to_cluster(policy->cpu);
-   struct device_node *np;
 
/* Do not register a cpu_cooling device if we are in IKS mode */
if (cur_cluster >= MAX_CLUSTERS)
return;
 
-   np = of_node_get(cpu_dev->of_node);
-   if (WARN_ON(!np))
-   return;
-
-   if (of_find_property(np, "#cooling-cells", NULL)) {
-   u32 power_coefficient = 0;
-
-   of_property_read_u32(np, "dynamic-power-coefficient",
-&power_coefficient);
-
-   cdev[cur_cluster] = of_cpufreq_power_cooling_register(np,
-   policy, power_coefficient, NULL);
-   if (IS_ERR(cdev[cur_cluster])) {
-   dev_err(cpu_dev,
-   "running cpufreq without cooling device: %ld\n",
-   PTR_ERR(cdev[cur_cluster]));
-   cdev[cur_cluster] = NULL;
-   }
-   }
-   of_node_put(np);
+   cdev[cur_cluster] = of_cpufreq_power_cooling_register(policy);
 }
 
 static struct cpufreq_driver bL_cpufreq_driver = {
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index 545946ad0752..1e7bec7694ab 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -319,33 +319,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
 static void cpufreq_ready(struct cpufreq_policy *policy)
 {
struct private_data *priv = policy->driver_data;
-   struct device_node *np = of_node_get(priv->cpu_dev->of_node);
 
-   if (WARN_ON(!np))
-   return;
-
-   /*
-* For now, just loading the cooling device;
-* thermal DT code takes care of matching them.
-*/
-   if (of_find_property(np, "#cooling-cells", NULL)) {
-   u32 power_coefficient = 0;
-
-   of_property_read_u32(np, "dynamic-power-coefficient",
-&power_coefficient);
-
-   priv->cdev = of_cpufreq_power_cooling_register(np,
-   policy, power_coefficient, NULL);
-   if (IS_ERR(priv->cdev)) {
-   dev_err(priv->cpu_dev,
-   "running cpufreq without cooling device: %ld\n",
-   PTR_ERR(priv->cdev));
-
-   priv->cdev = NULL;
-   }
-   }
-
-   of_node_put(np);
+   priv->cdev = of_cpufreq_power_cooling_register(policy);
 }
 
 static struct cpufreq_driver dt_cpufreq_driver = {
diff --git a/drivers/cpufreq/mediatek-cpufre

[PATCH V2 4/4] cpu_cooling: Drop static-power related stuff

2017-12-04 Thread Viresh Kumar
No one has used it for the last two and half years (since it was
introduced by commit c36cf0717631 ("thermal: cpu_cooling: implement the
power cooling device API")), get rid of it.

Cc: Javi Merino 
Cc: Punit Agrawal 
Acked-by: Eduardo Valentin 
Signed-off-by: Viresh Kumar 
---
 drivers/thermal/cpu_cooling.c  | 106 +
 include/linux/cpu_cooling.h|   3 --
 include/trace/events/thermal.h |  10 ++--
 3 files changed, 16 insertions(+), 103 deletions(-)

diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 3371caf3095c..dfd23245f778 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -88,7 +88,6 @@ struct time_in_idle {
  * @policy: cpufreq policy.
  * @node: list_head to link all cpufreq_cooling_device together.
  * @idle_time: idle time stats
- * @plat_get_static_power: callback to calculate the static power
  *
  * This structure is required for keeping information of each registered
  * cpufreq_cooling_device.
@@ -104,7 +103,6 @@ struct cpufreq_cooling_device {
struct cpufreq_policy *policy;
struct list_head node;
struct time_in_idle *idle_time;
-   get_static_t plat_get_static_power;
 };
 
 static DEFINE_IDA(cpufreq_ida);
@@ -319,60 +317,6 @@ static u32 get_load(struct cpufreq_cooling_device 
*cpufreq_cdev, int cpu,
 }
 
 /**
- * get_static_power() - calculate the static power consumed by the cpus
- * @cpufreq_cdev:  struct &cpufreq_cooling_device for this cpu cdev
- * @tz:thermal zone device in which we're operating
- * @freq:  frequency in KHz
- * @power: pointer in which to store the calculated static power
- *
- * Calculate the static power consumed by the cpus described by
- * @cpu_actor running at frequency @freq.  This function relies on a
- * platform specific function that should have been provided when the
- * actor was registered.  If it wasn't, the static power is assumed to
- * be negligible.  The calculated static power is stored in @power.
- *
- * Return: 0 on success, -E* on failure.
- */
-static int get_static_power(struct cpufreq_cooling_device *cpufreq_cdev,
-   struct thermal_zone_device *tz, unsigned long freq,
-   u32 *power)
-{
-   struct dev_pm_opp *opp;
-   unsigned long voltage;
-   struct cpufreq_policy *policy = cpufreq_cdev->policy;
-   struct cpumask *cpumask = policy->related_cpus;
-   unsigned long freq_hz = freq * 1000;
-   struct device *dev;
-
-   if (!cpufreq_cdev->plat_get_static_power) {
-   *power = 0;
-   return 0;
-   }
-
-   dev = get_cpu_device(policy->cpu);
-   WARN_ON(!dev);
-
-   opp = dev_pm_opp_find_freq_exact(dev, freq_hz, true);
-   if (IS_ERR(opp)) {
-   dev_warn_ratelimited(dev, "Failed to find OPP for frequency 
%lu: %ld\n",
-freq_hz, PTR_ERR(opp));
-   return -EINVAL;
-   }
-
-   voltage = dev_pm_opp_get_voltage(opp);
-   dev_pm_opp_put(opp);
-
-   if (voltage == 0) {
-   dev_err_ratelimited(dev, "Failed to get voltage for frequency 
%lu\n",
-   freq_hz);
-   return -EINVAL;
-   }
-
-   return cpufreq_cdev->plat_get_static_power(cpumask, tz->passive_delay,
- voltage, power);
-}
-
-/**
  * get_dynamic_power() - calculate the dynamic power
  * @cpufreq_cdev:  &cpufreq_cooling_device for this cdev
  * @freq:  current frequency
@@ -491,8 +435,8 @@ static int cpufreq_get_requested_power(struct 
thermal_cooling_device *cdev,
   u32 *power)
 {
unsigned long freq;
-   int i = 0, cpu, ret;
-   u32 static_power, dynamic_power, total_load = 0;
+   int i = 0, cpu;
+   u32 total_load = 0;
struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
struct cpufreq_policy *policy = cpufreq_cdev->policy;
u32 *load_cpu = NULL;
@@ -522,22 +466,15 @@ static int cpufreq_get_requested_power(struct 
thermal_cooling_device *cdev,
 
cpufreq_cdev->last_load = total_load;
 
-   dynamic_power = get_dynamic_power(cpufreq_cdev, freq);
-   ret = get_static_power(cpufreq_cdev, tz, freq, &static_power);
-   if (ret) {
-   kfree(load_cpu);
-   return ret;
-   }
+   *power = get_dynamic_power(cpufreq_cdev, freq);
 
if (load_cpu) {
trace_thermal_power_cpu_get_power(policy->related_cpus, freq,
- load_cpu, i, dynamic_power,
- static_power);
+ load_cpu, i, *power);
 
kfree(load_cpu);
}
 
-   *power = static_power + dynamic_power;
return 0;
 }
 
@@ -561,8 +498,6 @@ static int cpufreq_state2powe

[PATCH V2 0/4] cpu_cooling: cooling dev registration cleanups

2017-12-04 Thread Viresh Kumar
Hi,

This cleans up the helpers exposed by cpu_cooling driver and its users
and removes a lot of code (around 280 lines effectively). Lots of unused
code is removed.

Tested on Hikey6220 and based over pm/linux-next.

V1->V2:
- Fixed a compilation warning when CONFIG_CPU_THERMAL isn't selected.

--
viresh

Viresh Kumar (4):
  cpu_cooling: Make of_cpufreq_power_cooling_register() parse DT
  cpu_cooling: Remove unused cpufreq_power_cooling_register()
  cpu_cooling: Keep only one of_cpufreq*cooling_register() helper
  cpu_cooling: Drop static-power related stuff

 Documentation/thermal/cpu-cooling-api.txt |  33 +
 drivers/cpufreq/arm_big_little.c  |  23 +---
 drivers/cpufreq/cpufreq-dt.c  |  27 +---
 drivers/cpufreq/mediatek-cpufreq.c|  22 +---
 drivers/cpufreq/qoriq-cpufreq.c   |  14 +--
 drivers/thermal/cpu_cooling.c | 201 ++
 include/linux/cpu_cooling.h   |  75 +++
 include/trace/events/thermal.h|  10 +-
 8 files changed, 64 insertions(+), 341 deletions(-)

-- 
2.11.0



  1   2   3   4   5   6   7   8   9   10   >