[PATCH 0/2] Fatal signal handing within uaccess faults

2017-07-11 Thread Mark Rutland
Hi,

Arch maintainer tl;dr: most arch fault code doesn't handle fatal signals
correctly, allowing unprivileged users to create an unkillable task which can
lock up the system. Please check whether your arch is affected.

AFAICT, most arches don't correctly handle a fatal signal interrupting a
uaccess fault. They attempt to bail out, returning to the faulting context
without bothering to handle the fault, but forget to apply the uaccess fixup.
Consequently, the uaccess gets replayed, and the same thing happens forver.

When this occurs, the relevant task never returns to userspace, never handles
the fatal signal, and is stuck in an unkillable (though interruptible and
preemptible) state. The task can inhibit forward progress of the rest of the
system, leading to RCU stalls and lockups.

It's possible for an unprivileged user to trigger this deliberately using the
userfaultfd syscall, as demonstrated by the test case at the end of this email
(note: requires CONFIG_USERFAULTFD to be selected). I am not sure if this is
the only way of triggering the issue.

I stumbled upon this while fuzzing arm64 with Syzkaller. I've verified that
both arm and arm64 have the issue, and by inspection is seems that the majority
of other architectures are affected.

It looks like this was fixed up for x86 in 2014 with commit:

  26178ec11ef3c6c8 ("x86: mm: consolidate VM_FAULT_RETRY handling")

... but most other architectures never received a similar fixup.

The duplication (and divergence) of this logic is unfortunate. It's largely
copy-paste code that could be consolidated under mm/.

Until we end up refactoring this, and so as to be sutiable for backporting,
this series fixes arm and arm64 in-place. I've not touched other architectures
as I don't have the relevant hardwre or arch knowledge.

Thanks,
Mark.


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

int main(int argc, char *argv[])
{
void *mem;
long pagesz;
int uffd, ret;
struct uffdio_api api = {
.api = UFFD_API
};
struct uffdio_register reg;
   
pagesz = sysconf(_SC_PAGESIZE);
if (pagesz < 0) {
return errno;
}

mem = mmap(NULL, pagesz, PROT_READ | PROT_WRITE,
   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem == MAP_FAILED)
return errno;

uffd = syscall(__NR_userfaultfd, 0);
if (uffd < 0)
return errno;

ret = ioctl(uffd, UFFDIO_API, );
if (ret < 0)
return errno;

reg = (struct uffdio_register) {
.range = {
.start = (unsigned long)mem,
.len = pagesz
},
.mode = UFFDIO_REGISTER_MODE_MISSING
};

ret = ioctl(uffd, UFFDIO_REGISTER, );
if (ret < 0)
return errno;

/*
 * Force an arbitrary uaccess to memory monitored by the userfaultfd.
 * This will block, but when a SIGKILL is sent, will consume all
 * available CPU time without being killed, and may inhibit forward
 * progress of the system.
 */
ret = fstatfs(0, (struct statfs *)mem);

return 0;
}


Mark Rutland (2):
  arm64: mm: abort uaccess retries upon fatal signal
  arm: mm: abort uaccess retries upon fatal signal

 arch/arm/mm/fault.c   | 5 -
 arch/arm64/mm/fault.c | 5 -
 2 files changed, 8 insertions(+), 2 deletions(-)

-- 
1.9.1



[PATCH 0/2] Fatal signal handing within uaccess faults

2017-07-11 Thread Mark Rutland
Hi,

Arch maintainer tl;dr: most arch fault code doesn't handle fatal signals
correctly, allowing unprivileged users to create an unkillable task which can
lock up the system. Please check whether your arch is affected.

AFAICT, most arches don't correctly handle a fatal signal interrupting a
uaccess fault. They attempt to bail out, returning to the faulting context
without bothering to handle the fault, but forget to apply the uaccess fixup.
Consequently, the uaccess gets replayed, and the same thing happens forver.

When this occurs, the relevant task never returns to userspace, never handles
the fatal signal, and is stuck in an unkillable (though interruptible and
preemptible) state. The task can inhibit forward progress of the rest of the
system, leading to RCU stalls and lockups.

It's possible for an unprivileged user to trigger this deliberately using the
userfaultfd syscall, as demonstrated by the test case at the end of this email
(note: requires CONFIG_USERFAULTFD to be selected). I am not sure if this is
the only way of triggering the issue.

I stumbled upon this while fuzzing arm64 with Syzkaller. I've verified that
both arm and arm64 have the issue, and by inspection is seems that the majority
of other architectures are affected.

It looks like this was fixed up for x86 in 2014 with commit:

  26178ec11ef3c6c8 ("x86: mm: consolidate VM_FAULT_RETRY handling")

... but most other architectures never received a similar fixup.

The duplication (and divergence) of this logic is unfortunate. It's largely
copy-paste code that could be consolidated under mm/.

Until we end up refactoring this, and so as to be sutiable for backporting,
this series fixes arm and arm64 in-place. I've not touched other architectures
as I don't have the relevant hardwre or arch knowledge.

Thanks,
Mark.


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

int main(int argc, char *argv[])
{
void *mem;
long pagesz;
int uffd, ret;
struct uffdio_api api = {
.api = UFFD_API
};
struct uffdio_register reg;
   
pagesz = sysconf(_SC_PAGESIZE);
if (pagesz < 0) {
return errno;
}

mem = mmap(NULL, pagesz, PROT_READ | PROT_WRITE,
   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem == MAP_FAILED)
return errno;

uffd = syscall(__NR_userfaultfd, 0);
if (uffd < 0)
return errno;

ret = ioctl(uffd, UFFDIO_API, );
if (ret < 0)
return errno;

reg = (struct uffdio_register) {
.range = {
.start = (unsigned long)mem,
.len = pagesz
},
.mode = UFFDIO_REGISTER_MODE_MISSING
};

ret = ioctl(uffd, UFFDIO_REGISTER, );
if (ret < 0)
return errno;

/*
 * Force an arbitrary uaccess to memory monitored by the userfaultfd.
 * This will block, but when a SIGKILL is sent, will consume all
 * available CPU time without being killed, and may inhibit forward
 * progress of the system.
 */
ret = fstatfs(0, (struct statfs *)mem);

return 0;
}


Mark Rutland (2):
  arm64: mm: abort uaccess retries upon fatal signal
  arm: mm: abort uaccess retries upon fatal signal

 arch/arm/mm/fault.c   | 5 -
 arch/arm64/mm/fault.c | 5 -
 2 files changed, 8 insertions(+), 2 deletions(-)

-- 
1.9.1



Re: [PATCHSET for-4.13] cgroup: implement cgroup2 thread mode, v2

2017-07-11 Thread Waiman Long
On 07/11/2017 08:15 AM, Peter Zijlstra wrote:
> On Mon, Jul 10, 2017 at 05:01:19PM -0400, Waiman Long wrote:
>> On 07/10/2017 04:32 AM, Peter Zijlstra wrote:
>>> On Fri, Jun 30, 2017 at 09:23:24AM -0400, Tejun Heo wrote:
 On Tue, Jun 27, 2017 at 09:01:43AM +0200, Peter Zijlstra wrote:
> On Mon, Jun 12, 2017 at 05:27:53PM -0400, Tejun Heo wrote:
> IIRC the problem with the 'threaded' marker is that it doesn't clearly
> capture what a resource domain is.
>
> That is, assuming that a thread root is always a resource domain, we get
> the following problem:
>
> If we set 'threaded' on the root group in order to create a thread
> (sub)group. If we then want to create another domain group, we'd have to
> clear 'threaded' on that.
>
>   R (t=1)
>/ \
> (t=1) T   D (t=0)
>
> So far so good. However, now we want to create another thread group
> under our domain group D, so we have to set its 'threaded' marker again:
>
>   R (t=1)
>/ \
> (t=1) T   D (t=1)
>  /
>   T (t=1)
>> This configuration is actually not possible with Tejun's latest v3 patch
>> which took out the "join" operation. Maybe we should keep the "join"
>> operation if this configuration is likely to happen.
> Wait what? Why not? That's a fairly fundamental setup that needs to be
> possible. I understood the 'join' thing was for something else entirely.
> TJ said the 'join' was to allow thread-roots that were not domain
> controllers -- which I didn't get the point of.

The "join" was a special op for the children of cgroup root to join the
root as part of a threaded subtree. The children can instead use the
"enable" option to become a thread root which was the configuration
shown above.  This behavior applied only to children of root. Down the
hierarchy, you can't have configuration like:

 R (t=0)
/ \
   D (t=1)
  / \
 T   D (t=1)
   
Instead, you can have

 R (t=0)
/ \
   D (t=0)
  / \
(t=1)D   D(t=1)

With Tejun's v3 patch, the "join" operation was removed and "enable"
behaved like "join" in joining the threaded subtree of the root. I was
wrong in saying that the configuration listed in your example was not
possible. It was, but it depends on the order of activating the thread
mode. If we enables thread mode on a child of root first followed by the
root itself, we can have your configuration, but not in the reverse
order. It was possible in the reverse order in the previous patch.

> And we can no longer identify D as a resource domain. If OTOH we mark
> 'domain' we get:
>
>   R (d=1)
>/ \
> (d=0) T   D (d=1)
>  /
>   T (d=0)
>
> Which clearly identifies the domains and the thread only groups.
 So, the difference between the two interfaces is that the one I
 proposed is marking the thread root which makes all its descendants
 threaded while the above is marking each individual cgroup as being
 whether a resource domain or threaded.
>>> You start by marking the thread root, but then continue to mark all
>>> 'threaded' (including root). This then leads to the problem described
>>> above where you cannot (easily) (re)discover what the actual root is.
>> I don't think that is true. Internally, we can always find out if a
>> cgroup is a thread root. Externally, the presence of resource domain
>> control knobs in a threaded cgroup will indicate that it is a thread root.
> You're confusing thread root with resource domain. While a resource
> domain must be a thread root the reverse is not necessarily so (this is
> what I understood the 'join' thing to be for).

I know the difference between thread root and resource domain. In the
current scheme, all the cgroups which are not threaded under a thread
root are resource domain.

> And this is detection by inference, which breaks the moment you disable
> all resource domain controllers, because at that point those files will
> not be present.

It is true that there is no external marker to find out if a threaded
cgroup is a root or not when the parent of a thread root is also a
thread root of a separate threaded subtree if the domain controller
files are not present. However, we can always add a status file to
indicate the state of threaded-ness of a cgroup if we want to.

>>> My proposal differs in that we retain a clear difference between
>>> resource domain / root and threaded (sub)trees.
>> For me, I have no preference of using either the threaded or the domain
>> marker as long as some kind of join operation that allows the
>> configuration above is present in the thread mode. They both looks good
>> to me. It is just a matter of which aspect of the cgroup we want to
>> emphasize. I would suggest we reach a consensus ASAP and move forward to
>> other more substantial issues in cgroup v2.
> I think you're confused on join. Join should not be needed.

Tejun's patch makes resource 

Re: [PATCHSET for-4.13] cgroup: implement cgroup2 thread mode, v2

2017-07-11 Thread Waiman Long
On 07/11/2017 08:15 AM, Peter Zijlstra wrote:
> On Mon, Jul 10, 2017 at 05:01:19PM -0400, Waiman Long wrote:
>> On 07/10/2017 04:32 AM, Peter Zijlstra wrote:
>>> On Fri, Jun 30, 2017 at 09:23:24AM -0400, Tejun Heo wrote:
 On Tue, Jun 27, 2017 at 09:01:43AM +0200, Peter Zijlstra wrote:
> On Mon, Jun 12, 2017 at 05:27:53PM -0400, Tejun Heo wrote:
> IIRC the problem with the 'threaded' marker is that it doesn't clearly
> capture what a resource domain is.
>
> That is, assuming that a thread root is always a resource domain, we get
> the following problem:
>
> If we set 'threaded' on the root group in order to create a thread
> (sub)group. If we then want to create another domain group, we'd have to
> clear 'threaded' on that.
>
>   R (t=1)
>/ \
> (t=1) T   D (t=0)
>
> So far so good. However, now we want to create another thread group
> under our domain group D, so we have to set its 'threaded' marker again:
>
>   R (t=1)
>/ \
> (t=1) T   D (t=1)
>  /
>   T (t=1)
>> This configuration is actually not possible with Tejun's latest v3 patch
>> which took out the "join" operation. Maybe we should keep the "join"
>> operation if this configuration is likely to happen.
> Wait what? Why not? That's a fairly fundamental setup that needs to be
> possible. I understood the 'join' thing was for something else entirely.
> TJ said the 'join' was to allow thread-roots that were not domain
> controllers -- which I didn't get the point of.

The "join" was a special op for the children of cgroup root to join the
root as part of a threaded subtree. The children can instead use the
"enable" option to become a thread root which was the configuration
shown above.  This behavior applied only to children of root. Down the
hierarchy, you can't have configuration like:

 R (t=0)
/ \
   D (t=1)
  / \
 T   D (t=1)
   
Instead, you can have

 R (t=0)
/ \
   D (t=0)
  / \
(t=1)D   D(t=1)

With Tejun's v3 patch, the "join" operation was removed and "enable"
behaved like "join" in joining the threaded subtree of the root. I was
wrong in saying that the configuration listed in your example was not
possible. It was, but it depends on the order of activating the thread
mode. If we enables thread mode on a child of root first followed by the
root itself, we can have your configuration, but not in the reverse
order. It was possible in the reverse order in the previous patch.

> And we can no longer identify D as a resource domain. If OTOH we mark
> 'domain' we get:
>
>   R (d=1)
>/ \
> (d=0) T   D (d=1)
>  /
>   T (d=0)
>
> Which clearly identifies the domains and the thread only groups.
 So, the difference between the two interfaces is that the one I
 proposed is marking the thread root which makes all its descendants
 threaded while the above is marking each individual cgroup as being
 whether a resource domain or threaded.
>>> You start by marking the thread root, but then continue to mark all
>>> 'threaded' (including root). This then leads to the problem described
>>> above where you cannot (easily) (re)discover what the actual root is.
>> I don't think that is true. Internally, we can always find out if a
>> cgroup is a thread root. Externally, the presence of resource domain
>> control knobs in a threaded cgroup will indicate that it is a thread root.
> You're confusing thread root with resource domain. While a resource
> domain must be a thread root the reverse is not necessarily so (this is
> what I understood the 'join' thing to be for).

I know the difference between thread root and resource domain. In the
current scheme, all the cgroups which are not threaded under a thread
root are resource domain.

> And this is detection by inference, which breaks the moment you disable
> all resource domain controllers, because at that point those files will
> not be present.

It is true that there is no external marker to find out if a threaded
cgroup is a root or not when the parent of a thread root is also a
thread root of a separate threaded subtree if the domain controller
files are not present. However, we can always add a status file to
indicate the state of threaded-ness of a cgroup if we want to.

>>> My proposal differs in that we retain a clear difference between
>>> resource domain / root and threaded (sub)trees.
>> For me, I have no preference of using either the threaded or the domain
>> marker as long as some kind of join operation that allows the
>> configuration above is present in the thread mode. They both looks good
>> to me. It is just a matter of which aspect of the cgroup we want to
>> emphasize. I would suggest we reach a consensus ASAP and move forward to
>> other more substantial issues in cgroup v2.
> I think you're confused on join. Join should not be needed.

Tejun's patch makes resource 

Re: [PATCH RFC v4] cpufreq: schedutil: Make iowait boost more energy efficient

2017-07-11 Thread Joel Fernandes
Hi Viresh,

On Tue, Jul 11, 2017 at 3:14 AM, Viresh Kumar  wrote:
> On 09-07-17, 10:08, Joel Fernandes wrote:
>> diff --git a/kernel/sched/cpufreq_schedutil.c 
>> b/kernel/sched/cpufreq_schedutil.c
>> index 622eed1b7658..4d9e8b96bed1 100644
>> --- a/kernel/sched/cpufreq_schedutil.c
>> +++ b/kernel/sched/cpufreq_schedutil.c
>> @@ -53,7 +53,9 @@ struct sugov_cpu {
>>   struct update_util_data update_util;
>>   struct sugov_policy *sg_policy;
>>
>> + bool prev_iowait_boost;
>>   unsigned long iowait_boost;
>> + unsigned long iowait_boost_min;
>>   unsigned long iowait_boost_max;
>>   u64 last_update;
>>
>> @@ -168,22 +170,47 @@ static void sugov_get_util(unsigned long *util, 
>> unsigned long *max)
>>   *max = cfs_max;
>>  }
>>
>> +static void sugov_decay_iowait_boost(struct sugov_cpu *sg_cpu)
>> +{
>> + sg_cpu->iowait_boost >>= 1;
>> +
>> + if (sg_cpu->iowait_boost < sg_cpu->iowait_boost_min)
>> + sg_cpu->iowait_boost = 0;
>> +}
>> +
>>  static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time,
>>  unsigned int flags)
>>  {
>>   if (flags & SCHED_CPUFREQ_IOWAIT) {
>> - sg_cpu->iowait_boost = sg_cpu->iowait_boost_max;
>> + /* Remember for next time that we did an iowait boost */
>> + sg_cpu->prev_iowait_boost = true;
>> + if (sg_cpu->iowait_boost) {
>> + sg_cpu->iowait_boost <<= 1;
>> + sg_cpu->iowait_boost = min(sg_cpu->iowait_boost,
>> +sg_cpu->iowait_boost_max);
>> + } else {
>> + sg_cpu->iowait_boost = sg_cpu->iowait_boost_min;
>
> I am not sure if boost should start from the min frequency, as the current
> frequency will at least be equal to that. Which means that with no boost
> initially, we will never increase the frequency for the first IOWAIT flag 
> event.

I think the whole point of IOWAIT boost was to solve the issue with a
long sequence of repeated I/O requests as described in the commit
message. So IIUC there isn't a usecase for that (increase freq. on
first request). Also its just for the first couple of requests in my
testing and doesn't hurt the performance at all for the intended
usecase while still not causing transient spikes.

Another approach than setting min in sugov_set_iowait_boost, is, since
we have already retrieved the current util, we can check if flags ==
SCHED_CPUFREQ_IOWAIT, then set initial the iowait_boost such that
(iowait_boost / iowait_boost_max) is aleast equal to (util / max) or
iowait_boost_min, which ever is lower. This still will not increase
frequency on the first request, but will ensure the next one will
benefit. Then again I fear running into slightly longer-term
transients where 2 iowait requests are enough to boost the frequency
to high values. I can try to measure how often this can hurt power for
common usecases if you agree its worth exploring.

>
>> + }
>>   } else if (sg_cpu->iowait_boost) {
>>   s64 delta_ns = time - sg_cpu->last_update;
>>
>>   /* Clear iowait_boost if the CPU apprears to have been idle. */
>>   if (delta_ns > TICK_NSEC)
>>   sg_cpu->iowait_boost = 0;
>> +
>> + /*
>> +  * Since we don't decay iowait_boost when its consumed during
>> +  * the previous SCHED_CPUFREQ_IOWAIT update, decay it now.
>> +  */
>> + if (sg_cpu->prev_iowait_boost) {
>
> SCHED_CPUFREQ_IOWAIT flag is set only by CFS from the enqueue_task() and in 
> many
> cases we call the util hook twice from the same enqueue_task() instance before
> returning (2nd one after updating util). And in such cases we will set
> iowait_boost as 0 on the second call.
>
> Have you ever seen two consecutive calls to sugov_set_iowait_boost() with 
> IOWAIT
> flag set ? Can we get the ratio of that against the other case where we have
> IOWAIT flag set in first call, followed by one or more non-IOWAIT calls and 
> then
> IOWAIT again ?
>
> I am asking because if the calls with IOWAIT flag aren't consecutive then we
> will make iowait_boost as 0 in the next non-IOWAIT call.

Yes, I've seen that happen in my testing (consecutive iowait). I
haven't seen the other case where you have IOWAIT followed by
non-IOWAIT for a repeated set of IOWAIT requests. Would you more
comfortable if we moved sugov_set_iowait_boost() after the
sugov_should_update_freq() ? That way if there are consecutive
requests in the same path, then it most likely rate-limiting will
prevent such updates. I will also try to collect some stats as you
suggested to see if how often if at all this can happen.

thanks,

-Joel


Re: [PATCH RFC v4] cpufreq: schedutil: Make iowait boost more energy efficient

2017-07-11 Thread Joel Fernandes
Hi Viresh,

On Tue, Jul 11, 2017 at 3:14 AM, Viresh Kumar  wrote:
> On 09-07-17, 10:08, Joel Fernandes wrote:
>> diff --git a/kernel/sched/cpufreq_schedutil.c 
>> b/kernel/sched/cpufreq_schedutil.c
>> index 622eed1b7658..4d9e8b96bed1 100644
>> --- a/kernel/sched/cpufreq_schedutil.c
>> +++ b/kernel/sched/cpufreq_schedutil.c
>> @@ -53,7 +53,9 @@ struct sugov_cpu {
>>   struct update_util_data update_util;
>>   struct sugov_policy *sg_policy;
>>
>> + bool prev_iowait_boost;
>>   unsigned long iowait_boost;
>> + unsigned long iowait_boost_min;
>>   unsigned long iowait_boost_max;
>>   u64 last_update;
>>
>> @@ -168,22 +170,47 @@ static void sugov_get_util(unsigned long *util, 
>> unsigned long *max)
>>   *max = cfs_max;
>>  }
>>
>> +static void sugov_decay_iowait_boost(struct sugov_cpu *sg_cpu)
>> +{
>> + sg_cpu->iowait_boost >>= 1;
>> +
>> + if (sg_cpu->iowait_boost < sg_cpu->iowait_boost_min)
>> + sg_cpu->iowait_boost = 0;
>> +}
>> +
>>  static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time,
>>  unsigned int flags)
>>  {
>>   if (flags & SCHED_CPUFREQ_IOWAIT) {
>> - sg_cpu->iowait_boost = sg_cpu->iowait_boost_max;
>> + /* Remember for next time that we did an iowait boost */
>> + sg_cpu->prev_iowait_boost = true;
>> + if (sg_cpu->iowait_boost) {
>> + sg_cpu->iowait_boost <<= 1;
>> + sg_cpu->iowait_boost = min(sg_cpu->iowait_boost,
>> +sg_cpu->iowait_boost_max);
>> + } else {
>> + sg_cpu->iowait_boost = sg_cpu->iowait_boost_min;
>
> I am not sure if boost should start from the min frequency, as the current
> frequency will at least be equal to that. Which means that with no boost
> initially, we will never increase the frequency for the first IOWAIT flag 
> event.

I think the whole point of IOWAIT boost was to solve the issue with a
long sequence of repeated I/O requests as described in the commit
message. So IIUC there isn't a usecase for that (increase freq. on
first request). Also its just for the first couple of requests in my
testing and doesn't hurt the performance at all for the intended
usecase while still not causing transient spikes.

Another approach than setting min in sugov_set_iowait_boost, is, since
we have already retrieved the current util, we can check if flags ==
SCHED_CPUFREQ_IOWAIT, then set initial the iowait_boost such that
(iowait_boost / iowait_boost_max) is aleast equal to (util / max) or
iowait_boost_min, which ever is lower. This still will not increase
frequency on the first request, but will ensure the next one will
benefit. Then again I fear running into slightly longer-term
transients where 2 iowait requests are enough to boost the frequency
to high values. I can try to measure how often this can hurt power for
common usecases if you agree its worth exploring.

>
>> + }
>>   } else if (sg_cpu->iowait_boost) {
>>   s64 delta_ns = time - sg_cpu->last_update;
>>
>>   /* Clear iowait_boost if the CPU apprears to have been idle. */
>>   if (delta_ns > TICK_NSEC)
>>   sg_cpu->iowait_boost = 0;
>> +
>> + /*
>> +  * Since we don't decay iowait_boost when its consumed during
>> +  * the previous SCHED_CPUFREQ_IOWAIT update, decay it now.
>> +  */
>> + if (sg_cpu->prev_iowait_boost) {
>
> SCHED_CPUFREQ_IOWAIT flag is set only by CFS from the enqueue_task() and in 
> many
> cases we call the util hook twice from the same enqueue_task() instance before
> returning (2nd one after updating util). And in such cases we will set
> iowait_boost as 0 on the second call.
>
> Have you ever seen two consecutive calls to sugov_set_iowait_boost() with 
> IOWAIT
> flag set ? Can we get the ratio of that against the other case where we have
> IOWAIT flag set in first call, followed by one or more non-IOWAIT calls and 
> then
> IOWAIT again ?
>
> I am asking because if the calls with IOWAIT flag aren't consecutive then we
> will make iowait_boost as 0 in the next non-IOWAIT call.

Yes, I've seen that happen in my testing (consecutive iowait). I
haven't seen the other case where you have IOWAIT followed by
non-IOWAIT for a repeated set of IOWAIT requests. Would you more
comfortable if we moved sugov_set_iowait_boost() after the
sugov_should_update_freq() ? That way if there are consecutive
requests in the same path, then it most likely rate-limiting will
prevent such updates. I will also try to collect some stats as you
suggested to see if how often if at all this can happen.

thanks,

-Joel


[PATCH] scsi: scsi_dh_alua: fix boolreturn.cocci warnings

2017-07-11 Thread kbuild test robot
drivers/scsi/device_handler/scsi_dh_alua.c:594:9-10: WARNING: return of 0/1 in 
function 'alua_rtpg_print_check' with return type bool

 Return statements in functions returning bool should use
 true/false instead of 1/0.
Generated by: scripts/coccinelle/misc/boolreturn.cocci

Fixes: cb809ba2fcbf ("scsi: scsi_dh_alua: do not print RTPG state if it remains 
unavailable/standby")
CC: Mauricio Faria de Oliveira 
Signed-off-by: Fengguang Wu 
---

 scsi_dh_alua.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -591,7 +591,7 @@ static bool alua_rtpg_print_check(int ol
case SCSI_ACCESS_STATE_STANDBY:
return old_state != new_state;
default:
-   return 1;
+   return true;
}
 }
 


Re: [PATCH v2 3/4] scsi: scsi_dh_alua: do not print RTPG state if it remains unavailable/standby

2017-07-11 Thread kbuild test robot
Hi Mauricio,

[auto build test WARNING on bvanassche/for-next]
[also build test WARNING on v4.12 next-20170711]
[cannot apply to mkp-scsi/for-next scsi/for-next]
[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/Mauricio-Faria-de-Oliveira/scsi_dh_alua-fix-stuck-I-O-after-unavailable-standby-states/20170711-141350
base:   https://github.com/bvanassche/linux for-next


coccinelle warnings: (new ones prefixed by >>)

>> drivers/scsi/device_handler/scsi_dh_alua.c:594:9-10: WARNING: return of 0/1 
>> in function 'alua_rtpg_print_check' with return type bool

Please review and possibly fold the followup patch.

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


[PATCH] scsi: scsi_dh_alua: fix boolreturn.cocci warnings

2017-07-11 Thread kbuild test robot
drivers/scsi/device_handler/scsi_dh_alua.c:594:9-10: WARNING: return of 0/1 in 
function 'alua_rtpg_print_check' with return type bool

 Return statements in functions returning bool should use
 true/false instead of 1/0.
Generated by: scripts/coccinelle/misc/boolreturn.cocci

Fixes: cb809ba2fcbf ("scsi: scsi_dh_alua: do not print RTPG state if it remains 
unavailable/standby")
CC: Mauricio Faria de Oliveira 
Signed-off-by: Fengguang Wu 
---

 scsi_dh_alua.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -591,7 +591,7 @@ static bool alua_rtpg_print_check(int ol
case SCSI_ACCESS_STATE_STANDBY:
return old_state != new_state;
default:
-   return 1;
+   return true;
}
 }
 


Re: [PATCH v2 3/4] scsi: scsi_dh_alua: do not print RTPG state if it remains unavailable/standby

2017-07-11 Thread kbuild test robot
Hi Mauricio,

[auto build test WARNING on bvanassche/for-next]
[also build test WARNING on v4.12 next-20170711]
[cannot apply to mkp-scsi/for-next scsi/for-next]
[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/Mauricio-Faria-de-Oliveira/scsi_dh_alua-fix-stuck-I-O-after-unavailable-standby-states/20170711-141350
base:   https://github.com/bvanassche/linux for-next


coccinelle warnings: (new ones prefixed by >>)

>> drivers/scsi/device_handler/scsi_dh_alua.c:594:9-10: WARNING: return of 0/1 
>> in function 'alua_rtpg_print_check' with return type bool

Please review and possibly fold the followup patch.

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


[PATCH] ARM: dts: uniphier: use SPDX-License-Identifier (2nd)

2017-07-11 Thread Masahiro Yamada
Commit fa53757bca33 ("ARM: dts: uniphier: use SPDX-License-Identifier")
missed to touch these two.  Now updating.

Signed-off-by: Masahiro Yamada 
---

 arch/arm/boot/dts/uniphier-pinctrl.dtsi | 38 +
 arch/arm/boot/dts/uniphier-pro5.dtsi| 38 +
 2 files changed, 2 insertions(+), 74 deletions(-)

diff --git a/arch/arm/boot/dts/uniphier-pinctrl.dtsi 
b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
index 246f35ffb638..f6c5cf2281d5 100644
--- a/arch/arm/boot/dts/uniphier-pinctrl.dtsi
+++ b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
@@ -4,43 +4,7 @@
  * Copyright (C) 2015-2017 Socionext Inc.
  *   Author: Masahiro Yamada 
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
  {
diff --git a/arch/arm/boot/dts/uniphier-pro5.dtsi 
b/arch/arm/boot/dts/uniphier-pro5.dtsi
index 9577769a0add..140327ddde1c 100644
--- a/arch/arm/boot/dts/uniphier-pro5.dtsi
+++ b/arch/arm/boot/dts/uniphier-pro5.dtsi
@@ -4,43 +4,7 @@
  * Copyright (C) 2015-2016 Socionext Inc.
  *   Author: Masahiro Yamada 
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN 

[PATCH] ARM: dts: uniphier: use SPDX-License-Identifier (2nd)

2017-07-11 Thread Masahiro Yamada
Commit fa53757bca33 ("ARM: dts: uniphier: use SPDX-License-Identifier")
missed to touch these two.  Now updating.

Signed-off-by: Masahiro Yamada 
---

 arch/arm/boot/dts/uniphier-pinctrl.dtsi | 38 +
 arch/arm/boot/dts/uniphier-pro5.dtsi| 38 +
 2 files changed, 2 insertions(+), 74 deletions(-)

diff --git a/arch/arm/boot/dts/uniphier-pinctrl.dtsi 
b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
index 246f35ffb638..f6c5cf2281d5 100644
--- a/arch/arm/boot/dts/uniphier-pinctrl.dtsi
+++ b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
@@ -4,43 +4,7 @@
  * Copyright (C) 2015-2017 Socionext Inc.
  *   Author: Masahiro Yamada 
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  */
 
  {
diff --git a/arch/arm/boot/dts/uniphier-pro5.dtsi 
b/arch/arm/boot/dts/uniphier-pro5.dtsi
index 9577769a0add..140327ddde1c 100644
--- a/arch/arm/boot/dts/uniphier-pro5.dtsi
+++ b/arch/arm/boot/dts/uniphier-pro5.dtsi
@@ -4,43 +4,7 @@
  * Copyright (C) 2015-2016 Socionext Inc.
  *   Author: Masahiro Yamada 
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
+ * 

[PATCH] ASoC: hdmi-codec: make const array hdmi_codec_eld_spk_alloc_bits static

2017-07-11 Thread Colin King
From: Colin Ian King 

Don't populate array hdmi_codec_eld_spk_alloc_bits on the stack but
make it static. Makes the object code smaller by over 260 bytes:

Before:
   textdata bss dec hex filename
  108823384  64   1433037fa sound/soc/codecs/hdmi-codec.o

After:
   textdata bss dec hex filename
  105573440  64   1406136ed sound/soc/codecs/hdmi-codec.o

Signed-off-by: Colin Ian King 
---
 sound/soc/codecs/hdmi-codec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 7686a80861f1..509ab513b4b2 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -326,7 +326,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
 static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
 {
int i;
-   const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
+   static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
[0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
[4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
};
-- 
2.11.0



[PATCH] ASoC: hdmi-codec: make const array hdmi_codec_eld_spk_alloc_bits static

2017-07-11 Thread Colin King
From: Colin Ian King 

Don't populate array hdmi_codec_eld_spk_alloc_bits on the stack but
make it static. Makes the object code smaller by over 260 bytes:

Before:
   textdata bss dec hex filename
  108823384  64   1433037fa sound/soc/codecs/hdmi-codec.o

After:
   textdata bss dec hex filename
  105573440  64   1406136ed sound/soc/codecs/hdmi-codec.o

Signed-off-by: Colin Ian King 
---
 sound/soc/codecs/hdmi-codec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 7686a80861f1..509ab513b4b2 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -326,7 +326,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
 static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
 {
int i;
-   const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
+   static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
[0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
[4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
};
-- 
2.11.0



[PATCH] power: supply: ltc2941-battery-gauge: Add LTC2944 support

2017-07-11 Thread Dragos Bogdan
The only difference between the already supported LTC2943 and LTC2944 is the
operating range (3.6V - 20V compared to 3.6V - 60V).

Signed-off-by: Dragos Bogdan 
---
 Documentation/devicetree/bindings/power/supply/ltc2941.txt | 10 +-
 drivers/power/supply/ltc2941-battery-gauge.c   | 11 ---
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/supply/ltc2941.txt 
b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
index a9d7aa60558b..ed0f02846d10 100644
--- a/Documentation/devicetree/bindings/power/supply/ltc2941.txt
+++ b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
@@ -1,9 +1,9 @@
-binding for LTC2941 and LTC2943 battery gauges
+binding for LTC2941, LTC2943 and LTC2944 battery gauges
 
-Both the LTC2941 and LTC2943 measure battery capacity.
-The LTC2943 is compatible with the LTC2941, it adds voltage and
-temperature monitoring, and uses a slightly different conversion
-formula for the charge counter.
+All the LTC2941, LTC2943 and LTC2944 measure battery capacity.
+The LTC2943 and LTC2944 are compatible with the LTC2941, they add voltage and
+temperature monitoring, and use a slightly different conversion formula for the
+charge counter.
 
 Required properties:
 - compatible: Should contain "lltc,ltc2941" or "lltc,ltc2943" which also
diff --git a/drivers/power/supply/ltc2941-battery-gauge.c 
b/drivers/power/supply/ltc2941-battery-gauge.c
index 7efb908f4451..48af7b6fb704 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -1,5 +1,5 @@
 /*
- * I2C client/driver for the Linear Technology LTC2941 and LTC2943
+ * I2C client/driver for the Linear Technology LTC2941, LTC2943 and LTC2944
  * Battery Gas Gauge IC
  *
  * Copyright (C) 2014 Topic Embedded Systems
@@ -145,7 +145,7 @@ static int ltc294x_reset(const struct ltc294x_info *info, 
int prescaler_exp)
 
control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
-   /* Put the 2943 into "monitor" mode, so it measures every 10 sec */
+   /* Put the 2943/4 into "monitor" mode, so it measures every 10 sec */
if (info->num_regs == LTC2943_NUM_REGS)
control |= LTC2943_REG_CONTROL_MODE_SCAN;
 
@@ -494,6 +494,7 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, 
ltc294x_resume);
 static const struct i2c_device_id ltc294x_i2c_id[] = {
{"ltc2941", LTC2941_NUM_REGS},
{"ltc2943", LTC2943_NUM_REGS},
+   {"ltc2944", LTC2943_NUM_REGS},
{ },
 };
 MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
@@ -507,6 +508,10 @@ static const struct of_device_id ltc294x_i2c_of_match[] = {
.compatible = "lltc,ltc2943",
.data = (void *)LTC2943_NUM_REGS
},
+   {
+   .compatible = "lltc,ltc2944",
+   .data = (void *)LTC2943_NUM_REGS
+   },
{ },
 };
 MODULE_DEVICE_TABLE(of, ltc294x_i2c_of_match);
@@ -525,5 +530,5 @@ module_i2c_driver(ltc294x_driver);
 
 MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
 MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
-MODULE_DESCRIPTION("LTC2941/LTC2943 Battery Gas Gauge IC driver");
+MODULE_DESCRIPTION("LTC2941/LTC2943/LTC2944 Battery Gas Gauge IC driver");
 MODULE_LICENSE("GPL");
-- 
2.11.0



[PATCH] power: supply: ltc2941-battery-gauge: Add LTC2944 support

2017-07-11 Thread Dragos Bogdan
The only difference between the already supported LTC2943 and LTC2944 is the
operating range (3.6V - 20V compared to 3.6V - 60V).

Signed-off-by: Dragos Bogdan 
---
 Documentation/devicetree/bindings/power/supply/ltc2941.txt | 10 +-
 drivers/power/supply/ltc2941-battery-gauge.c   | 11 ---
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/supply/ltc2941.txt 
b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
index a9d7aa60558b..ed0f02846d10 100644
--- a/Documentation/devicetree/bindings/power/supply/ltc2941.txt
+++ b/Documentation/devicetree/bindings/power/supply/ltc2941.txt
@@ -1,9 +1,9 @@
-binding for LTC2941 and LTC2943 battery gauges
+binding for LTC2941, LTC2943 and LTC2944 battery gauges
 
-Both the LTC2941 and LTC2943 measure battery capacity.
-The LTC2943 is compatible with the LTC2941, it adds voltage and
-temperature monitoring, and uses a slightly different conversion
-formula for the charge counter.
+All the LTC2941, LTC2943 and LTC2944 measure battery capacity.
+The LTC2943 and LTC2944 are compatible with the LTC2941, they add voltage and
+temperature monitoring, and use a slightly different conversion formula for the
+charge counter.
 
 Required properties:
 - compatible: Should contain "lltc,ltc2941" or "lltc,ltc2943" which also
diff --git a/drivers/power/supply/ltc2941-battery-gauge.c 
b/drivers/power/supply/ltc2941-battery-gauge.c
index 7efb908f4451..48af7b6fb704 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -1,5 +1,5 @@
 /*
- * I2C client/driver for the Linear Technology LTC2941 and LTC2943
+ * I2C client/driver for the Linear Technology LTC2941, LTC2943 and LTC2944
  * Battery Gas Gauge IC
  *
  * Copyright (C) 2014 Topic Embedded Systems
@@ -145,7 +145,7 @@ static int ltc294x_reset(const struct ltc294x_info *info, 
int prescaler_exp)
 
control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
-   /* Put the 2943 into "monitor" mode, so it measures every 10 sec */
+   /* Put the 2943/4 into "monitor" mode, so it measures every 10 sec */
if (info->num_regs == LTC2943_NUM_REGS)
control |= LTC2943_REG_CONTROL_MODE_SCAN;
 
@@ -494,6 +494,7 @@ static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, 
ltc294x_resume);
 static const struct i2c_device_id ltc294x_i2c_id[] = {
{"ltc2941", LTC2941_NUM_REGS},
{"ltc2943", LTC2943_NUM_REGS},
+   {"ltc2944", LTC2943_NUM_REGS},
{ },
 };
 MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
@@ -507,6 +508,10 @@ static const struct of_device_id ltc294x_i2c_of_match[] = {
.compatible = "lltc,ltc2943",
.data = (void *)LTC2943_NUM_REGS
},
+   {
+   .compatible = "lltc,ltc2944",
+   .data = (void *)LTC2943_NUM_REGS
+   },
{ },
 };
 MODULE_DEVICE_TABLE(of, ltc294x_i2c_of_match);
@@ -525,5 +530,5 @@ module_i2c_driver(ltc294x_driver);
 
 MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
 MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
-MODULE_DESCRIPTION("LTC2941/LTC2943 Battery Gas Gauge IC driver");
+MODULE_DESCRIPTION("LTC2941/LTC2943/LTC2944 Battery Gas Gauge IC driver");
 MODULE_LICENSE("GPL");
-- 
2.11.0



Re: [PATCH/RFC] dma-mapping: Provide dummy set_dma_ops() for NO_DMA=y

2017-07-11 Thread Christoph Hellwig
On Mon, Jul 10, 2017 at 04:31:54PM +0100, Robin Murphy wrote:
> On 10/07/17 15:56, Christoph Hellwig wrote:
> > This looks reasonable to me, I'd be happy to pick it up.  Can you send
> > it as a series with the reverts?
> 
> The fact remains that the FSL driver is still doing the wrong thing
> though - set_dma_ops(dev1, get_dma_ops(dev2)) is just a hack which
> happens to work on platforms which don't keep other arch-internal DMA
> info as well. I did start writing a patch somewhere to fix this thing to
> actually do proper DMA configuration (originally in the context of not
> abusing arch_setup_dma_ops()), but Arnd's fix is probably simpler.
> 
> I don't think it makes an awful lot of sense for code without a DMA API
> dependency to be calling set_dma_ops() - AFAIU the only reason it's
> available to drivers at all is for particular RDMA cases which know that
> their "DMA" is actually done by CPU threads, and want to optimise for that.

Even that code should require the DMA API.  So yes, maybe we should
fix the code to propagate the settings by another means.


Re: [PATCH/RFC] dma-mapping: Provide dummy set_dma_ops() for NO_DMA=y

2017-07-11 Thread Christoph Hellwig
On Mon, Jul 10, 2017 at 04:31:54PM +0100, Robin Murphy wrote:
> On 10/07/17 15:56, Christoph Hellwig wrote:
> > This looks reasonable to me, I'd be happy to pick it up.  Can you send
> > it as a series with the reverts?
> 
> The fact remains that the FSL driver is still doing the wrong thing
> though - set_dma_ops(dev1, get_dma_ops(dev2)) is just a hack which
> happens to work on platforms which don't keep other arch-internal DMA
> info as well. I did start writing a patch somewhere to fix this thing to
> actually do proper DMA configuration (originally in the context of not
> abusing arch_setup_dma_ops()), but Arnd's fix is probably simpler.
> 
> I don't think it makes an awful lot of sense for code without a DMA API
> dependency to be calling set_dma_ops() - AFAIU the only reason it's
> available to drivers at all is for particular RDMA cases which know that
> their "DMA" is actually done by CPU threads, and want to optimise for that.

Even that code should require the DMA API.  So yes, maybe we should
fix the code to propagate the settings by another means.


Re: [PATCH 16/17] RISC-V: User-facing API

2017-07-11 Thread James Hogan
Hi Christoph,

On Tue, Jul 11, 2017 at 06:39:48AM -0700, Christoph Hellwig wrote:
> > +#ifdef CONFIG_64BIT
> > +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
> > +   unsigned long, prot, unsigned long, flags,
> > +   unsigned long, fd, off_t, offset)
> > +{
> > +   if (unlikely(offset & (~PAGE_MASK)))
> > +   return -EINVAL;
> > +   return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
> > +}
> > +#else
> > +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> > +   unsigned long, prot, unsigned long, flags,
> > +   unsigned long, fd, off_t, offset)
> > +{
> > +   /*
> > +* Note that the shift for mmap2 is constant (12),
> > +* regardless of PAGE_SIZE
> > +*/
> > +   if (unlikely(offset & (~PAGE_MASK >> 12)))
> > +   return -EINVAL;
> > +   return sys_mmap_pgoff(addr, len, prot, flags, fd,
> > +   offset >> (PAGE_SHIFT - 12));
> > +}
> > +#endif /* !CONFIG_64BIT */
> 
> Most modern ports seem to expose sys_mmap_pgoff as the
> syscall directly.  Any reason you're doing this differently?

I think Palmer's patch is probably correct here. Exposing sys_mmap_pgoff
is only really correct on 32-bit arches where the only page size is 4k.
If other page sizes are supported then this is the correct way to handle
it as the page offset from 32-bit userland is supposed to be in 4k
units.

64-bit doesn't need to worry about squeezing big file offsets into the
off_t offset so don't need to do the shift at all.

See the mmap2 man page. It says "the final argument specifies the offset
into the file in 4096-byte units", and it points out ia64 as an
exception where it depends on the page size of the system.

> 
> But even the code for the older ones should probably be consolidated..

Quite probably, yes.

Cheers
James


signature.asc
Description: Digital signature


Re: [PATCH 16/17] RISC-V: User-facing API

2017-07-11 Thread James Hogan
Hi Christoph,

On Tue, Jul 11, 2017 at 06:39:48AM -0700, Christoph Hellwig wrote:
> > +#ifdef CONFIG_64BIT
> > +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
> > +   unsigned long, prot, unsigned long, flags,
> > +   unsigned long, fd, off_t, offset)
> > +{
> > +   if (unlikely(offset & (~PAGE_MASK)))
> > +   return -EINVAL;
> > +   return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
> > +}
> > +#else
> > +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> > +   unsigned long, prot, unsigned long, flags,
> > +   unsigned long, fd, off_t, offset)
> > +{
> > +   /*
> > +* Note that the shift for mmap2 is constant (12),
> > +* regardless of PAGE_SIZE
> > +*/
> > +   if (unlikely(offset & (~PAGE_MASK >> 12)))
> > +   return -EINVAL;
> > +   return sys_mmap_pgoff(addr, len, prot, flags, fd,
> > +   offset >> (PAGE_SHIFT - 12));
> > +}
> > +#endif /* !CONFIG_64BIT */
> 
> Most modern ports seem to expose sys_mmap_pgoff as the
> syscall directly.  Any reason you're doing this differently?

I think Palmer's patch is probably correct here. Exposing sys_mmap_pgoff
is only really correct on 32-bit arches where the only page size is 4k.
If other page sizes are supported then this is the correct way to handle
it as the page offset from 32-bit userland is supposed to be in 4k
units.

64-bit doesn't need to worry about squeezing big file offsets into the
off_t offset so don't need to do the shift at all.

See the mmap2 man page. It says "the final argument specifies the offset
into the file in 4096-byte units", and it points out ia64 as an
exception where it depends on the page size of the system.

> 
> But even the code for the older ones should probably be consolidated..

Quite probably, yes.

Cheers
James


signature.asc
Description: Digital signature


Re: [PATCH v8 05/10] mm: thp: enable thp migration in generic path

2017-07-11 Thread Zi Yan
On 11 Jul 2017, at 2:47, Naoya Horiguchi wrote:

> On Sat, Jul 01, 2017 at 09:40:03AM -0400, Zi Yan wrote:
>> From: Zi Yan 
>>
>> This patch adds thp migration's core code, including conversions
>> between a PMD entry and a swap entry, setting PMD migration entry,
>> removing PMD migration entry, and waiting on PMD migration entries.
>>
>> This patch makes it possible to support thp migration.
>> If you fail to allocate a destination page as a thp, you just split
>> the source thp as we do now, and then enter the normal page migration.
>> If you succeed to allocate destination thp, you enter thp migration.
>> Subsequent patches actually enable thp migration for each caller of
>> page migration by allowing its get_new_page() callback to
>> allocate thps.
>>
>> ChangeLog v1 -> v2:
>> - support pte-mapped thp, doubly-mapped thp
>>
>> Signed-off-by: Naoya Horiguchi 
>>
>> ChangeLog v2 -> v3:
>> - use page_vma_mapped_walk()
>> - use pmdp_huge_clear_flush() instead of pmdp_huge_get_and_clear() in
>>   set_pmd_migration_entry()
>>
>> ChangeLog v3 -> v4:
>> - factor out the code of removing pte pgtable page in zap_huge_pmd()
>>
>> ChangeLog v4 -> v5:
>> - remove unnecessary PTE-mapped THP code in remove_migration_pmd()
>>   and set_pmd_migration_entry()
>> - restructure the code in zap_huge_pmd() to avoid factoring out
>>   the pte pgtable page code
>> - in zap_huge_pmd(), check that PMD swap entries are migration entries
>> - change author information
>>
>> ChangeLog v5 -> v7
>> - use macro to disable the code when thp migration is not enabled
>>
>> ChangeLog v7 -> v8
>> - use IS_ENABLED instead of macro to make code look clean in
>>   zap_huge_pmd() and page_vma_mapped_walk()
>> - remove BUILD_BUG() in pmd_to_swp_entry() and swp_entry_to_pmd() to
>>   avoid compilation error
>> - rename variable 'migration' to 'flush_needed' and invert the logic in
>>   zap_huge_pmd() to make code more descriptive
>> - use pmdp_invalidate() in set_pmd_migration_entry() to avoid race
>>   with MADV_DONTNEED
>> - remove unnecessary tlb flush in remove_migration_pmd()
>> - add the missing migration flag check in page_vma_mapped_walk()
>>
>> Signed-off-by: Zi Yan 
>> Cc: Kirill A. Shutemov 
>> ---
>>  arch/x86/include/asm/pgtable_64.h |  2 +
>>  include/linux/swapops.h   | 67 ++-
>>  mm/huge_memory.c  | 84 
>> ---
>>  mm/migrate.c  | 32 ++-
>>  mm/page_vma_mapped.c  | 18 +++--
>>  mm/pgtable-generic.c  |  3 +-
>>  mm/rmap.c | 13 ++
>>  7 files changed, 207 insertions(+), 12 deletions(-)
>>
> ...
>
>> diff --git a/mm/rmap.c b/mm/rmap.c
>> index 91948fbbb0bb..b28f633cd569 100644
>> --- a/mm/rmap.c
>> +++ b/mm/rmap.c
>> @@ -1302,6 +1302,7 @@ static bool try_to_unmap_one(struct page *page, struct 
>> vm_area_struct *vma,
>>  bool ret = true;
>>  enum ttu_flags flags = (enum ttu_flags)arg;
>>
>> +
>>  /* munlock has nothing to gain from examining un-locked vmas */
>>  if ((flags & TTU_MUNLOCK) && !(vma->vm_flags & VM_LOCKED))
>>  return true;
>> @@ -1312,6 +1313,18 @@ static bool try_to_unmap_one(struct page *page, 
>> struct vm_area_struct *vma,
>>  }
>>
>>  while (page_vma_mapped_walk()) {
>> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
>> +/* PMD-mapped THP migration entry */
>> +if (flags & TTU_MIGRATION) {
>
> My testing based on mmotm-2017-07-06-16-18 showed that migrating shmem thp
> caused kernel crash. I don't think this is critical because that case is
> just not-prepared yet. So in order to avoid the crash, please add
> PageAnon(page) check here. This makes shmem thp migration just fail.
>
> + if (!PageAnon(page))
> + continue;
>

Thanks for your testing. I will add this check in my next version.


>> +if (!pvmw.pte && page) {
>
> Just from curiosity, do we really need this page check?
> try_to_unmap() always passes down the parameter 'page' to try_to_unmap_one()
> via rmap_walk_* family, so I think we can assume page is always non-NULL.

You are right. Checking page is not necessary here. I will remove it in my
next version.



--
Best Regards
Yan Zi


signature.asc
Description: OpenPGP digital signature


Re: [PATCH v8 05/10] mm: thp: enable thp migration in generic path

2017-07-11 Thread Zi Yan
On 11 Jul 2017, at 2:47, Naoya Horiguchi wrote:

> On Sat, Jul 01, 2017 at 09:40:03AM -0400, Zi Yan wrote:
>> From: Zi Yan 
>>
>> This patch adds thp migration's core code, including conversions
>> between a PMD entry and a swap entry, setting PMD migration entry,
>> removing PMD migration entry, and waiting on PMD migration entries.
>>
>> This patch makes it possible to support thp migration.
>> If you fail to allocate a destination page as a thp, you just split
>> the source thp as we do now, and then enter the normal page migration.
>> If you succeed to allocate destination thp, you enter thp migration.
>> Subsequent patches actually enable thp migration for each caller of
>> page migration by allowing its get_new_page() callback to
>> allocate thps.
>>
>> ChangeLog v1 -> v2:
>> - support pte-mapped thp, doubly-mapped thp
>>
>> Signed-off-by: Naoya Horiguchi 
>>
>> ChangeLog v2 -> v3:
>> - use page_vma_mapped_walk()
>> - use pmdp_huge_clear_flush() instead of pmdp_huge_get_and_clear() in
>>   set_pmd_migration_entry()
>>
>> ChangeLog v3 -> v4:
>> - factor out the code of removing pte pgtable page in zap_huge_pmd()
>>
>> ChangeLog v4 -> v5:
>> - remove unnecessary PTE-mapped THP code in remove_migration_pmd()
>>   and set_pmd_migration_entry()
>> - restructure the code in zap_huge_pmd() to avoid factoring out
>>   the pte pgtable page code
>> - in zap_huge_pmd(), check that PMD swap entries are migration entries
>> - change author information
>>
>> ChangeLog v5 -> v7
>> - use macro to disable the code when thp migration is not enabled
>>
>> ChangeLog v7 -> v8
>> - use IS_ENABLED instead of macro to make code look clean in
>>   zap_huge_pmd() and page_vma_mapped_walk()
>> - remove BUILD_BUG() in pmd_to_swp_entry() and swp_entry_to_pmd() to
>>   avoid compilation error
>> - rename variable 'migration' to 'flush_needed' and invert the logic in
>>   zap_huge_pmd() to make code more descriptive
>> - use pmdp_invalidate() in set_pmd_migration_entry() to avoid race
>>   with MADV_DONTNEED
>> - remove unnecessary tlb flush in remove_migration_pmd()
>> - add the missing migration flag check in page_vma_mapped_walk()
>>
>> Signed-off-by: Zi Yan 
>> Cc: Kirill A. Shutemov 
>> ---
>>  arch/x86/include/asm/pgtable_64.h |  2 +
>>  include/linux/swapops.h   | 67 ++-
>>  mm/huge_memory.c  | 84 
>> ---
>>  mm/migrate.c  | 32 ++-
>>  mm/page_vma_mapped.c  | 18 +++--
>>  mm/pgtable-generic.c  |  3 +-
>>  mm/rmap.c | 13 ++
>>  7 files changed, 207 insertions(+), 12 deletions(-)
>>
> ...
>
>> diff --git a/mm/rmap.c b/mm/rmap.c
>> index 91948fbbb0bb..b28f633cd569 100644
>> --- a/mm/rmap.c
>> +++ b/mm/rmap.c
>> @@ -1302,6 +1302,7 @@ static bool try_to_unmap_one(struct page *page, struct 
>> vm_area_struct *vma,
>>  bool ret = true;
>>  enum ttu_flags flags = (enum ttu_flags)arg;
>>
>> +
>>  /* munlock has nothing to gain from examining un-locked vmas */
>>  if ((flags & TTU_MUNLOCK) && !(vma->vm_flags & VM_LOCKED))
>>  return true;
>> @@ -1312,6 +1313,18 @@ static bool try_to_unmap_one(struct page *page, 
>> struct vm_area_struct *vma,
>>  }
>>
>>  while (page_vma_mapped_walk()) {
>> +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
>> +/* PMD-mapped THP migration entry */
>> +if (flags & TTU_MIGRATION) {
>
> My testing based on mmotm-2017-07-06-16-18 showed that migrating shmem thp
> caused kernel crash. I don't think this is critical because that case is
> just not-prepared yet. So in order to avoid the crash, please add
> PageAnon(page) check here. This makes shmem thp migration just fail.
>
> + if (!PageAnon(page))
> + continue;
>

Thanks for your testing. I will add this check in my next version.


>> +if (!pvmw.pte && page) {
>
> Just from curiosity, do we really need this page check?
> try_to_unmap() always passes down the parameter 'page' to try_to_unmap_one()
> via rmap_walk_* family, so I think we can assume page is always non-NULL.

You are right. Checking page is not necessary here. I will remove it in my
next version.



--
Best Regards
Yan Zi


signature.asc
Description: OpenPGP digital signature


Re: [PATCH 00/16] omap_hsmmc: Add ADMA support and UHS/HS200/DDR support

2017-07-11 Thread Kishon Vijay Abraham I
Hi Ulf,

On Tuesday 11 July 2017 06:40 PM, Ulf Hansson wrote:
> On 16 June 2017 at 14:45, Kishon Vijay Abraham I  wrote:
>> This is the final part of the series originally sent as
>> part of [2].
>>
>> This series adds UHS, HS200, DDR mode and ADMA support to
>> omap_hsmmc driver used to improve the throughput of MMC/SD in dra7
>> SoCs.
>>
>> Changes from [2]:
>> *) No more updating omap2plus_defconfig or multi_v7_defconfig is
>>required, so those patches are removed.
>> *) Addressed Rob Herring's comment on implementing a function
>>instead of having a macro while getting pinctrl state.
>>
>> This series is created on top of [3], [4], [5] AND [6]
>> (i.e after
>>   ARM: dts: omap3-overo: Remove "vqmmc-supply" property from MMC dt node
>>   omap_hsmmc: use mmc_regulator_get_supply() to get regulators
>>   omap*: Fixes/Cleanups for MMC devicetree node
>>   ARM: dts: Add iodelay data for MMC)
>>
>> The functionality implemented in this series was sent before ([1]) but
>> was never followed up since supporting high speed modes in dra7 required
>> IODelay values to be configured. With IODelay driver being merged into
>> kernel, sending it as a fresh series with support for configuring IODelay
>> values.
> 
> Is it safe to queue this via mmc tree for 4.14 or is there a
> dependency I must consider? The above didn't quite tell me that, could
> you please elaborate.

There is a dependency with 
https://www.spinics.net/lists/arm-kernel/msg586215.html.

I'll resend the series after all the platform data specific stuff is merged.
> 
>>
>> Suggestions of migrating to sdhci driver (from omap_hsmmc driver) is not
>> addressed since
>> *) tuning ratio of MMC in dra7 is different from sdhci
>> *) IOdelay is required for dra7
>> *) GPIO based card detect is not supported in sdhci
> 
> Lots of sdhci drivers calls mmc_of_parse(), and uses the mmc slot gpio
> APIs, so I don't this this is correct statement.
> 
>> *) Some of the registers don't always have correct values as in sdhci
>>(like PSTATE).
>> Supporting all of these in sdhci will result in adding lot of quirks in
>> sdhci driver.
> 
> Is it really that much different? It would be nice if some really took
> on the challenge of converting omap_hsmmc into an sdhci variant.

Okay. I'll give that a shot and see how far I can get.

Thanks
Kishon


Re: [PATCH 00/16] omap_hsmmc: Add ADMA support and UHS/HS200/DDR support

2017-07-11 Thread Kishon Vijay Abraham I
Hi Ulf,

On Tuesday 11 July 2017 06:40 PM, Ulf Hansson wrote:
> On 16 June 2017 at 14:45, Kishon Vijay Abraham I  wrote:
>> This is the final part of the series originally sent as
>> part of [2].
>>
>> This series adds UHS, HS200, DDR mode and ADMA support to
>> omap_hsmmc driver used to improve the throughput of MMC/SD in dra7
>> SoCs.
>>
>> Changes from [2]:
>> *) No more updating omap2plus_defconfig or multi_v7_defconfig is
>>required, so those patches are removed.
>> *) Addressed Rob Herring's comment on implementing a function
>>instead of having a macro while getting pinctrl state.
>>
>> This series is created on top of [3], [4], [5] AND [6]
>> (i.e after
>>   ARM: dts: omap3-overo: Remove "vqmmc-supply" property from MMC dt node
>>   omap_hsmmc: use mmc_regulator_get_supply() to get regulators
>>   omap*: Fixes/Cleanups for MMC devicetree node
>>   ARM: dts: Add iodelay data for MMC)
>>
>> The functionality implemented in this series was sent before ([1]) but
>> was never followed up since supporting high speed modes in dra7 required
>> IODelay values to be configured. With IODelay driver being merged into
>> kernel, sending it as a fresh series with support for configuring IODelay
>> values.
> 
> Is it safe to queue this via mmc tree for 4.14 or is there a
> dependency I must consider? The above didn't quite tell me that, could
> you please elaborate.

There is a dependency with 
https://www.spinics.net/lists/arm-kernel/msg586215.html.

I'll resend the series after all the platform data specific stuff is merged.
> 
>>
>> Suggestions of migrating to sdhci driver (from omap_hsmmc driver) is not
>> addressed since
>> *) tuning ratio of MMC in dra7 is different from sdhci
>> *) IOdelay is required for dra7
>> *) GPIO based card detect is not supported in sdhci
> 
> Lots of sdhci drivers calls mmc_of_parse(), and uses the mmc slot gpio
> APIs, so I don't this this is correct statement.
> 
>> *) Some of the registers don't always have correct values as in sdhci
>>(like PSTATE).
>> Supporting all of these in sdhci will result in adding lot of quirks in
>> sdhci driver.
> 
> Is it really that much different? It would be nice if some really took
> on the challenge of converting omap_hsmmc into an sdhci variant.

Okay. I'll give that a shot and see how far I can get.

Thanks
Kishon


Re: [PATCH 8/9] RISC-V: User-facing API

2017-07-11 Thread Christoph Hellwig
On Tue, Jul 11, 2017 at 02:22:15PM +0100, Will Deacon wrote:
> The problem is that by supporting these hypothetical designs that can't do
> atomics, you hurt sensible designs that *can* do the atomics because you
> force them to take an additional indirection that could otherwise be
> avoided.

Agreed.  But the new patchset seems to remove it already, so I guess
we're fine on the kernel side.  Now we just need to make sure the
glibc API doesn't use any indirections.

Note that it might make sense to emit these for very low end nommu
designs.  Maybe even running Linux, but in that case they'll just need
a special non-standard ABI for very limited use cases.


Re: [PATCH 8/9] RISC-V: User-facing API

2017-07-11 Thread Christoph Hellwig
On Tue, Jul 11, 2017 at 02:22:15PM +0100, Will Deacon wrote:
> The problem is that by supporting these hypothetical designs that can't do
> atomics, you hurt sensible designs that *can* do the atomics because you
> force them to take an additional indirection that could otherwise be
> avoided.

Agreed.  But the new patchset seems to remove it already, so I guess
we're fine on the kernel side.  Now we just need to make sure the
glibc API doesn't use any indirections.

Note that it might make sense to emit these for very low end nommu
designs.  Maybe even running Linux, but in that case they'll just need
a special non-standard ABI for very limited use cases.


Re: [PATCH 2/2] mmc: sdhci-of-at91: set clocks and presets after resume from deepest PM

2017-07-11 Thread Ulf Hansson
On 11 July 2017 at 15:33, Ludovic Desroches
 wrote:
> On Tue, Jul 11, 2017 at 02:42:44PM +0200, Ulf Hansson wrote:
>> On 16 June 2017 at 09:29, Quentin Schulz
>>  wrote:
>> > This adds deepest (Backup+Self-Refresh) PM support to the ATMEL SAMA5D2
>> > SoC's SDHCI controller.
>> >
>> > When resuming from deepest state, it is required to restore preset
>> > registers as the registers are lost since VDD core has been shut down
>> > when entering deepest state on the SAMA5D2. The clocks need to be
>> > reconfigured as well.
>>
>> Right, so compared to runtime resume there is some additional
>> operations that is needed during system resume. Fair enough.
>>
>> However by looking at the changes below, you also change the system
>> suspend operations, as it now calls sdhci_suspend_host(). Is that
>> change needed? Then why?
>>
>> >
>> > The other registers and init process are taken care of by the SDHCI
>> > core.
>> >
>> > Signed-off-by: Quentin Schulz 
>> > ---
>> >  drivers/mmc/host/sdhci-of-at91.c | 34 --
>> >  1 file changed, 32 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/mmc/host/sdhci-of-at91.c 
>> > b/drivers/mmc/host/sdhci-of-at91.c
>> > index fb8c6011f13d..300513fc1068 100644
>> > --- a/drivers/mmc/host/sdhci-of-at91.c
>> > +++ b/drivers/mmc/host/sdhci-of-at91.c
>> > @@ -207,6 +207,37 @@ static int sdhci_at91_set_clks_presets(struct device 
>> > *dev)
>> >  }
>> >
>> >  #ifdef CONFIG_PM
>> > +static int sdhci_at91_suspend(struct device *dev)
>> > +{
>> > +   struct sdhci_host *host = dev_get_drvdata(dev);
>> > +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> > +   struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host);
>> > +   int ret;
>> > +
>> > +   ret = sdhci_suspend_host(host);
>> > +
>>
>> This is wrong, you can't call sdhci_suspend_host() unless the device
>> is runtime resumed...
>>
>> > +   if (host->runtime_suspended)
>> > +   return ret;
>>
>> ... and this is weird...
>>
>> > +
>> > +   clk_disable_unprepare(priv->gck);
>> > +   clk_disable_unprepare(priv->hclock);
>> > +   clk_disable_unprepare(priv->mainck);
>> > +
>> > +   return ret;
>> > +}
>> > +
>> > +static int sdhci_at91_resume(struct device *dev)
>> > +{
>> > +   struct sdhci_host *host = dev_get_drvdata(dev);
>> > +   int ret;
>> > +
>> > +   ret = sdhci_at91_set_clks_presets(dev);
>> > +   if (ret)
>> > +   return ret;
>>
>> Instead of doing it like this, I suggest you set a new flag to true
>> here, let's call it "restore_needed".
>>
>> In the ->runtime_resume() callback, you check the restore_needed flag
>> and performs the extra operations in that case. When that's done, the
>> ->runtime_resume() callback clears the flag, as to avoid the next
>> runtime resume from unnecessary doing the extra operations.
>>
>> > +
>> > +   return sdhci_resume_host(host);
>>
>> Remove this and call pm_runtime_force_resume().
>>
>> > +}
>> > +
>> >  static int sdhci_at91_runtime_suspend(struct device *dev)
>> >  {
>> > struct sdhci_host *host = dev_get_drvdata(dev);
>> > @@ -256,8 +287,7 @@ static int sdhci_at91_runtime_resume(struct device 
>> > *dev)
>> >  #endif /* CONFIG_PM */
>> >
>> >  static const struct dev_pm_ops sdhci_at91_dev_pm_ops = {
>> > -   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
>>
>> Leave the pm_runtime_force_suspend() here, unless you have other
>> reasons not being described in the change log, to change the system
>> suspend operations.
>
> I think we need to keep it to be able to set the restore_needed flag, isn't 
> it?

Yeah, perhaps it's better to set the flag from sdhci_at91_suspend()
and instead leave the resume callback being assigned to
pm_runtime_force_resume().

I guess that is what you meant?

[...]

Kind regards
Uffe


Re: [PATCH 2/2] mmc: sdhci-of-at91: set clocks and presets after resume from deepest PM

2017-07-11 Thread Ulf Hansson
On 11 July 2017 at 15:33, Ludovic Desroches
 wrote:
> On Tue, Jul 11, 2017 at 02:42:44PM +0200, Ulf Hansson wrote:
>> On 16 June 2017 at 09:29, Quentin Schulz
>>  wrote:
>> > This adds deepest (Backup+Self-Refresh) PM support to the ATMEL SAMA5D2
>> > SoC's SDHCI controller.
>> >
>> > When resuming from deepest state, it is required to restore preset
>> > registers as the registers are lost since VDD core has been shut down
>> > when entering deepest state on the SAMA5D2. The clocks need to be
>> > reconfigured as well.
>>
>> Right, so compared to runtime resume there is some additional
>> operations that is needed during system resume. Fair enough.
>>
>> However by looking at the changes below, you also change the system
>> suspend operations, as it now calls sdhci_suspend_host(). Is that
>> change needed? Then why?
>>
>> >
>> > The other registers and init process are taken care of by the SDHCI
>> > core.
>> >
>> > Signed-off-by: Quentin Schulz 
>> > ---
>> >  drivers/mmc/host/sdhci-of-at91.c | 34 --
>> >  1 file changed, 32 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/mmc/host/sdhci-of-at91.c 
>> > b/drivers/mmc/host/sdhci-of-at91.c
>> > index fb8c6011f13d..300513fc1068 100644
>> > --- a/drivers/mmc/host/sdhci-of-at91.c
>> > +++ b/drivers/mmc/host/sdhci-of-at91.c
>> > @@ -207,6 +207,37 @@ static int sdhci_at91_set_clks_presets(struct device 
>> > *dev)
>> >  }
>> >
>> >  #ifdef CONFIG_PM
>> > +static int sdhci_at91_suspend(struct device *dev)
>> > +{
>> > +   struct sdhci_host *host = dev_get_drvdata(dev);
>> > +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> > +   struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host);
>> > +   int ret;
>> > +
>> > +   ret = sdhci_suspend_host(host);
>> > +
>>
>> This is wrong, you can't call sdhci_suspend_host() unless the device
>> is runtime resumed...
>>
>> > +   if (host->runtime_suspended)
>> > +   return ret;
>>
>> ... and this is weird...
>>
>> > +
>> > +   clk_disable_unprepare(priv->gck);
>> > +   clk_disable_unprepare(priv->hclock);
>> > +   clk_disable_unprepare(priv->mainck);
>> > +
>> > +   return ret;
>> > +}
>> > +
>> > +static int sdhci_at91_resume(struct device *dev)
>> > +{
>> > +   struct sdhci_host *host = dev_get_drvdata(dev);
>> > +   int ret;
>> > +
>> > +   ret = sdhci_at91_set_clks_presets(dev);
>> > +   if (ret)
>> > +   return ret;
>>
>> Instead of doing it like this, I suggest you set a new flag to true
>> here, let's call it "restore_needed".
>>
>> In the ->runtime_resume() callback, you check the restore_needed flag
>> and performs the extra operations in that case. When that's done, the
>> ->runtime_resume() callback clears the flag, as to avoid the next
>> runtime resume from unnecessary doing the extra operations.
>>
>> > +
>> > +   return sdhci_resume_host(host);
>>
>> Remove this and call pm_runtime_force_resume().
>>
>> > +}
>> > +
>> >  static int sdhci_at91_runtime_suspend(struct device *dev)
>> >  {
>> > struct sdhci_host *host = dev_get_drvdata(dev);
>> > @@ -256,8 +287,7 @@ static int sdhci_at91_runtime_resume(struct device 
>> > *dev)
>> >  #endif /* CONFIG_PM */
>> >
>> >  static const struct dev_pm_ops sdhci_at91_dev_pm_ops = {
>> > -   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
>>
>> Leave the pm_runtime_force_suspend() here, unless you have other
>> reasons not being described in the change log, to change the system
>> suspend operations.
>
> I think we need to keep it to be able to set the restore_needed flag, isn't 
> it?

Yeah, perhaps it's better to set the flag from sdhci_at91_suspend()
and instead leave the resume callback being assigned to
pm_runtime_force_resume().

I guess that is what you meant?

[...]

Kind regards
Uffe


Re: [PATCH v4 3/3] KVM: nVMX: Emulate EPTP switching for the L1 hypervisor

2017-07-11 Thread Radim Krčmář
[David did a great review, so I'll just point out things I noticed.]

2017-07-11 09:51+0200, David Hildenbrand:
> On 10.07.2017 22:49, Bandan Das wrote:
> > When L2 uses vmfunc, L0 utilizes the associated vmexit to
> > emulate a switching of the ept pointer by reloading the
> > guest MMU.
> > 
> > Signed-off-by: Paolo Bonzini 
> > Signed-off-by: Bandan Das 
> > ---
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > @@ -7784,11 +7801,46 @@ static int handle_vmfunc(struct kvm_vcpu *vcpu)
> > }
> >  
> > vmcs12 = get_vmcs12(vcpu);
> > -   if ((vmcs12->vm_function_control & (1 << function)) == 0)
> > +   if (((vmcs12->vm_function_control & (1 << function)) == 0) ||
> > +   WARN_ON_ONCE(function))
> 
> "... instruction causes a VM exit if the bit at position EAX is 0 in the
> VM-function controls (the selected VM function is
> not enabled)."
> 
> So g2 can trigger this WARN_ON_ONCE, no? I think we should drop it then
> completely.

It assumes that vm_function_control is not > 1, which is (should be)
guaranteed by VM entry check, because the nested_vmx_vmfunc_controls MSR
is 1.

> > +   goto fail;

The rest of the code assumes that the function is
VMX_VMFUNC_EPTP_SWITCHING, so some WARN_ON_ONCE is reasonable.

Writing it as

  WARN_ON_ONCE(function != VMX_VMFUNC_EPTP_SWITCHING)

would be cleared and I'd prefer to move the part that handles
VMX_VMFUNC_EPTP_SWITCHING into a new function. (Imagine that Intel is
going to add more than one VM FUNC. :])

> > +   if (!nested_cpu_has_ept(vmcs12) ||
> > +   !nested_cpu_has_eptp_switching(vmcs12))
> > +   goto fail;

This brings me to a missing vm-entry check:

 If “EPTP switching” VM-function control is 1, the “enable EPT”
 VM-execution control must also be 1. In addition, the EPTP-list address
 must satisfy the following checks:
 • Bits 11:0 of the address must be 0.
 • The address must not set any bits beyond the processor’s
   physical-address width.

so this one could be

  if (!nested_cpu_has_eptp_switching(vmcs12) ||
  WARN_ON_ONCE(!nested_cpu_has_ept(vmcs12)))

after adding the check.


Re: [PATCH v4 3/3] KVM: nVMX: Emulate EPTP switching for the L1 hypervisor

2017-07-11 Thread Radim Krčmář
[David did a great review, so I'll just point out things I noticed.]

2017-07-11 09:51+0200, David Hildenbrand:
> On 10.07.2017 22:49, Bandan Das wrote:
> > When L2 uses vmfunc, L0 utilizes the associated vmexit to
> > emulate a switching of the ept pointer by reloading the
> > guest MMU.
> > 
> > Signed-off-by: Paolo Bonzini 
> > Signed-off-by: Bandan Das 
> > ---
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > @@ -7784,11 +7801,46 @@ static int handle_vmfunc(struct kvm_vcpu *vcpu)
> > }
> >  
> > vmcs12 = get_vmcs12(vcpu);
> > -   if ((vmcs12->vm_function_control & (1 << function)) == 0)
> > +   if (((vmcs12->vm_function_control & (1 << function)) == 0) ||
> > +   WARN_ON_ONCE(function))
> 
> "... instruction causes a VM exit if the bit at position EAX is 0 in the
> VM-function controls (the selected VM function is
> not enabled)."
> 
> So g2 can trigger this WARN_ON_ONCE, no? I think we should drop it then
> completely.

It assumes that vm_function_control is not > 1, which is (should be)
guaranteed by VM entry check, because the nested_vmx_vmfunc_controls MSR
is 1.

> > +   goto fail;

The rest of the code assumes that the function is
VMX_VMFUNC_EPTP_SWITCHING, so some WARN_ON_ONCE is reasonable.

Writing it as

  WARN_ON_ONCE(function != VMX_VMFUNC_EPTP_SWITCHING)

would be cleared and I'd prefer to move the part that handles
VMX_VMFUNC_EPTP_SWITCHING into a new function. (Imagine that Intel is
going to add more than one VM FUNC. :])

> > +   if (!nested_cpu_has_ept(vmcs12) ||
> > +   !nested_cpu_has_eptp_switching(vmcs12))
> > +   goto fail;

This brings me to a missing vm-entry check:

 If “EPTP switching” VM-function control is 1, the “enable EPT”
 VM-execution control must also be 1. In addition, the EPTP-list address
 must satisfy the following checks:
 • Bits 11:0 of the address must be 0.
 • The address must not set any bits beyond the processor’s
   physical-address width.

so this one could be

  if (!nested_cpu_has_eptp_switching(vmcs12) ||
  WARN_ON_ONCE(!nested_cpu_has_ept(vmcs12)))

after adding the check.


Re: [GIT pull] irq updates for 4.13

2017-07-11 Thread Tony Lindgren
* Thomas Gleixner  [170711 02:48]:
> On Tue, 11 Jul 2017, Thomas Gleixner wrote:
> 
> So Tony actually provided the part of dmesg which shows the initial
> failure, which subsequently leads to the splat Sebastian reported.
> 
> Unhandled fault: external abort on non-linefetch (0x1028) at 0xfb050034
> pgd = c0004000 [fb050034] *pgd=49011452(bad)
> Internal error: : 1028 [#1] SMP ARM
> Workqueue: events deferred_probe_work_func
> task: ce1d41c0 task.stack: ce1fc000
> PC is at omap_gpio_get_direction+0x2c/0x44
> LR is at _raw_spin_lock_irqsave+0x40/0x4c
> pc : []lr : []psr: 6093
> sp : ce1fdb78  ip : c0dce42c  fp : ce22d810
> r10: ce22d800  r9 :   r8 : ce22d900
> r7 : 0016  r6 : ce223864  r5 : fb050034  r4 : 0020
> r3 : ce1d41c0  r2 :   r1 : a013  r0 : a013
> Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
> Control: 10c5387d  Table: 80004019  DAC: 0051
> Process kworker/0:1 (pid: 14, stack limit = 0xce1fc218)
> 
> The callstack is:
> 
> omap_gpio_get_direction
> gpiochip_lock_as_irq
> gpiochip_irq_reqres
> __setup_irq
> request_threaded_irq
> smc_probe
> smc_drv_probe
> platform_drv_probe
> 
> 
> So the SMC91X network driver request an IRQ, which ends up calling into the
> GPIO interrupt setup and that fails. I have no idea why that would not fail
> with the patch reverted. Dusting off a Beaglebone board

And "external abort on non-linefetch" means something is not clocked
in this case. The following alone makes things boot for me again, but I don't
quite follow what has now changed with the ordering.. Thomas, any ideas?

Anyways, adding Linus W and Grygorii to Cc since things now point to
gpio-omap.

Regards,

Tony

8< -
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -919,13 +919,24 @@ static int omap_gpio_get_direction(struct gpio_chip 
*chip, unsigned offset)
struct gpio_bank *bank;
unsigned long flags;
void __iomem *reg;
-   int dir;
+   int error, dir;
 
bank = gpiochip_get_data(chip);
reg = bank->base + bank->regs->direction;
+   error = pm_runtime_get_sync(bank->chip.parent);
+   if (error < 0) {
+   dev_err(bank->chip.parent,
+   "Could not enable gpio bank %p: %d\n",
+   bank, error);
+   pm_runtime_put_noidle(bank->chip.parent);
+
+   return error;
+   }
raw_spin_lock_irqsave(>lock, flags);
dir = !!(readl_relaxed(reg) & BIT(offset));
raw_spin_unlock_irqrestore(>lock, flags);
+   pm_runtime_put_sync(bank->chip.parent);
+
return dir;
 }
 
-- 
2.13.2


Re: [GIT pull] irq updates for 4.13

2017-07-11 Thread Tony Lindgren
* Thomas Gleixner  [170711 02:48]:
> On Tue, 11 Jul 2017, Thomas Gleixner wrote:
> 
> So Tony actually provided the part of dmesg which shows the initial
> failure, which subsequently leads to the splat Sebastian reported.
> 
> Unhandled fault: external abort on non-linefetch (0x1028) at 0xfb050034
> pgd = c0004000 [fb050034] *pgd=49011452(bad)
> Internal error: : 1028 [#1] SMP ARM
> Workqueue: events deferred_probe_work_func
> task: ce1d41c0 task.stack: ce1fc000
> PC is at omap_gpio_get_direction+0x2c/0x44
> LR is at _raw_spin_lock_irqsave+0x40/0x4c
> pc : []lr : []psr: 6093
> sp : ce1fdb78  ip : c0dce42c  fp : ce22d810
> r10: ce22d800  r9 :   r8 : ce22d900
> r7 : 0016  r6 : ce223864  r5 : fb050034  r4 : 0020
> r3 : ce1d41c0  r2 :   r1 : a013  r0 : a013
> Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
> Control: 10c5387d  Table: 80004019  DAC: 0051
> Process kworker/0:1 (pid: 14, stack limit = 0xce1fc218)
> 
> The callstack is:
> 
> omap_gpio_get_direction
> gpiochip_lock_as_irq
> gpiochip_irq_reqres
> __setup_irq
> request_threaded_irq
> smc_probe
> smc_drv_probe
> platform_drv_probe
> 
> 
> So the SMC91X network driver request an IRQ, which ends up calling into the
> GPIO interrupt setup and that fails. I have no idea why that would not fail
> with the patch reverted. Dusting off a Beaglebone board

And "external abort on non-linefetch" means something is not clocked
in this case. The following alone makes things boot for me again, but I don't
quite follow what has now changed with the ordering.. Thomas, any ideas?

Anyways, adding Linus W and Grygorii to Cc since things now point to
gpio-omap.

Regards,

Tony

8< -
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -919,13 +919,24 @@ static int omap_gpio_get_direction(struct gpio_chip 
*chip, unsigned offset)
struct gpio_bank *bank;
unsigned long flags;
void __iomem *reg;
-   int dir;
+   int error, dir;
 
bank = gpiochip_get_data(chip);
reg = bank->base + bank->regs->direction;
+   error = pm_runtime_get_sync(bank->chip.parent);
+   if (error < 0) {
+   dev_err(bank->chip.parent,
+   "Could not enable gpio bank %p: %d\n",
+   bank, error);
+   pm_runtime_put_noidle(bank->chip.parent);
+
+   return error;
+   }
raw_spin_lock_irqsave(>lock, flags);
dir = !!(readl_relaxed(reg) & BIT(offset));
raw_spin_unlock_irqrestore(>lock, flags);
+   pm_runtime_put_sync(bank->chip.parent);
+
return dir;
 }
 
-- 
2.13.2


Re: [GIT pull] irq updates for 4.13

2017-07-11 Thread Marc Zyngier
On 11/07/17 12:21, Sebastian Reichel wrote:
> Hi,
> 
> On Tue, Jul 11, 2017 at 12:52:17PM +0200, Thomas Gleixner wrote:
>> On Tue, 11 Jul 2017, Thomas Gleixner wrote:
>>> On Tue, 11 Jul 2017, Sebastian Reichel wrote:
>>> So this crashes in do_raw_spin_unlock_irqrestore() !?! I just have to
>>> wonder how the raw_spin_lock() succeeded. That does not make any sense.
>>
>> can you please apply the patch below on top of 4.12? It's a backport
>> isolating the resource request changes.
> 
> Full bootlog for v4.12 + your patch is below. I used the same
> .config with oldconfig.

[...]

> [1.329315] cpcap-core spi1.0: CPCAP vendor: ST rev: 2.10 (1a)
> [1.336914] Unhandled fault: imprecise external abort (0x1406) at 
> 0x
> [1.343994] pgd = c0004000
> [1.346710] [] *pgd=
> [1.350341] Internal error: : 1406 [#1] SMP ARM
> [1.354888] Modules linked in:
> [1.357971] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
> 4.12.0-1-g2a481f732c4b #1539
> [1.365936] Hardware name: Generic OMAP4 (Flattened Device Tree)
> [1.371978] task: ee8aadc0 task.stack: ee8ac000
> [1.376556] PC is at lock_release+0x25c/0x360
> [1.380950] LR is at lock_release+0x25c/0x360
> [1.385314] pc : []lr : []psr: 2093
> [1.385314] sp : ee8adb60  ip : c10fc43c  fp : eea05010
> [1.396881] r10: 0001  r9 : c10f1e70  r8 : 6093
> [1.402130] r7 : c1007b6c  r6 : c0520658  r5 : ee9fd274  r4 : a013
> [1.408691] r3 : ee8aadc0  r2 : 0003  r1 : 0003  r0 : 
> [1.415252] Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment 
> none
> [1.422515] Control: 10c5387d  Table: 8000404a  DAC: 0051
> [1.428314] Process swapper/0 (pid: 1, stack limit = 0xee8ac218)
> [1.434356] Stack: (0xee8adb60 to 0xee8ae000)
> [1.438751] db60: a013 c0520648 0007 a013 ee9fd264 ee9fd264 
> 0007 eea05100
> [1.446960] db80: c061fe0c eea05000 eea05010 c0add86c  fc310134 
> ee9fd264 c0520658
> [1.455200] dba0: 0020 ee9fd2a4 ee9fd070  eea05100 c05196f0 
> ee9fd2a4 eea05010
> [1.463439] dbc0: eef1d580 c0519c20 eea05000 0021 eef1d580 c01a9508 
> 000f c01aa584
> [1.471649] dbe0: ee8000c0 6013  eef1d580  c01a77b8 
> eef9c400 0021
> [1.479888] dc00: c061fe0c eea05000 eea05010 c01a9890 2084 0204 
> eef9c400 c10a7bc8
> [1.488128] dc20: 0001 eef18600    c0620d7c 
> c0d93c60 eef9c400
> [1.496368] dc40:  efd93038 ef6a85d0 014e 0021 0084 
> 0084 eef18600
> [1.504577] dc60: eef1de90 0021 0084 eef19000 0010 eef1e93c 
> c0b613dc c0620f54
> [1.512817] dc80: c10a7bc8 ee8adc8c 0004 eef19000 eef19000 eef18600 
> 0021 eef17f90
> [1.521057] dca0: eef1e810 c062bd68  c10a7bc8 eef17f98 ee8aadc0 
> 0001 
> [1.529266] dcc0: c10a7bc8 0010   eef19000 eef19000 
> eef17f90 
> [1.537506] dce0: 0010 001a 0013   c062bef0 
> 000a 001a
> [1.545745] dd00:  0013  eef19000 c10a7b78  
> c10a7b88 
> [1.553985] dd20:  c06a06b8 eef19000 c18bfe4c  c05fcd9c 
>  ee8add70
> [1.562194] dd40: c05fcee8 0001  c18bfe08  c05fb2d4 
> ee9eccd4 eef13c54
> [1.570434] dd60: eef19000 eef19034 c10affe0 c05fca58 eef19000 0001 
> c18bfe08 eef19008
> [1.578674] dd80: eef19000 c10affe0  c05fc0d4 eef19008 eecdc000 
> eef19000 c05fa478
> [1.586914] dda0:  eef19000 eef19260  eef19000 eecdc000 
>  eea61c10
> [1.595123] ddc0: 0001  c0d7f208 c06a184c eecdc000 ef6e9a2c 
> ef6e9a7c eef19000
> [1.603363] dde0: 0001 c06a20ac  0002 c0add880 eea61c10 
> c06a1bd8 002dc6c0
> [1.611602] de00: eea61c10 eef17210 eecdc000 eecdc000 eea61c10 eea61c10 
> c0da4ba0 c0da4b98
> [1.619812] de20: 01f0 c06a243c  eecdc4e0 eecdc000 eecdc000 
> eea61c10 c06a5e60
> [1.628051] de40:  6013 c1897138 0004 8132535b eea61c10 
> ffed c10b0c74
> [1.636291] de60: fdfb   c0f66858 c0f005a8 c05fecf8 
> eea61c10 c18bfe4c
> [1.644531] de80:  c10b0c74  c05fcd9c eea61c10 c10b0c74 
> eea61c44 
> [1.652740] dea0: c10f8000 0007 c0f66858 c05fcee4  c10b0c74 
> c05fce24 c05fb228
> [1.660980] dec0: ee8a58a4 eea5ac50 c10b0c74 eef13580 c10a5720 c05fc2e4 
> c0d332c0 c0f4365c
> [1.669219] dee0:  c10b0c74 c0f4365c  c0e4f6ec c05fdd28 
> e000 c0f4365c
> [1.677429] df00:  c0101874 0134  efffec00 efffecdd 
> c0e50efc 0134
> [1.685668] df20: 0134 c015f5dc c0e4f6ec  0006 0006 
> efffecdd 
> [1.693908] df40: c0f7f7cc 0006 c10f8000 c0f6684c c0f7fe74 c10f8000 
> c0f66850 c10f8000
> [1.702148] df60: 0007 

Re: [GIT pull] irq updates for 4.13

2017-07-11 Thread Marc Zyngier
On 11/07/17 12:21, Sebastian Reichel wrote:
> Hi,
> 
> On Tue, Jul 11, 2017 at 12:52:17PM +0200, Thomas Gleixner wrote:
>> On Tue, 11 Jul 2017, Thomas Gleixner wrote:
>>> On Tue, 11 Jul 2017, Sebastian Reichel wrote:
>>> So this crashes in do_raw_spin_unlock_irqrestore() !?! I just have to
>>> wonder how the raw_spin_lock() succeeded. That does not make any sense.
>>
>> can you please apply the patch below on top of 4.12? It's a backport
>> isolating the resource request changes.
> 
> Full bootlog for v4.12 + your patch is below. I used the same
> .config with oldconfig.

[...]

> [1.329315] cpcap-core spi1.0: CPCAP vendor: ST rev: 2.10 (1a)
> [1.336914] Unhandled fault: imprecise external abort (0x1406) at 
> 0x
> [1.343994] pgd = c0004000
> [1.346710] [] *pgd=
> [1.350341] Internal error: : 1406 [#1] SMP ARM
> [1.354888] Modules linked in:
> [1.357971] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
> 4.12.0-1-g2a481f732c4b #1539
> [1.365936] Hardware name: Generic OMAP4 (Flattened Device Tree)
> [1.371978] task: ee8aadc0 task.stack: ee8ac000
> [1.376556] PC is at lock_release+0x25c/0x360
> [1.380950] LR is at lock_release+0x25c/0x360
> [1.385314] pc : []lr : []psr: 2093
> [1.385314] sp : ee8adb60  ip : c10fc43c  fp : eea05010
> [1.396881] r10: 0001  r9 : c10f1e70  r8 : 6093
> [1.402130] r7 : c1007b6c  r6 : c0520658  r5 : ee9fd274  r4 : a013
> [1.408691] r3 : ee8aadc0  r2 : 0003  r1 : 0003  r0 : 
> [1.415252] Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment 
> none
> [1.422515] Control: 10c5387d  Table: 8000404a  DAC: 0051
> [1.428314] Process swapper/0 (pid: 1, stack limit = 0xee8ac218)
> [1.434356] Stack: (0xee8adb60 to 0xee8ae000)
> [1.438751] db60: a013 c0520648 0007 a013 ee9fd264 ee9fd264 
> 0007 eea05100
> [1.446960] db80: c061fe0c eea05000 eea05010 c0add86c  fc310134 
> ee9fd264 c0520658
> [1.455200] dba0: 0020 ee9fd2a4 ee9fd070  eea05100 c05196f0 
> ee9fd2a4 eea05010
> [1.463439] dbc0: eef1d580 c0519c20 eea05000 0021 eef1d580 c01a9508 
> 000f c01aa584
> [1.471649] dbe0: ee8000c0 6013  eef1d580  c01a77b8 
> eef9c400 0021
> [1.479888] dc00: c061fe0c eea05000 eea05010 c01a9890 2084 0204 
> eef9c400 c10a7bc8
> [1.488128] dc20: 0001 eef18600    c0620d7c 
> c0d93c60 eef9c400
> [1.496368] dc40:  efd93038 ef6a85d0 014e 0021 0084 
> 0084 eef18600
> [1.504577] dc60: eef1de90 0021 0084 eef19000 0010 eef1e93c 
> c0b613dc c0620f54
> [1.512817] dc80: c10a7bc8 ee8adc8c 0004 eef19000 eef19000 eef18600 
> 0021 eef17f90
> [1.521057] dca0: eef1e810 c062bd68  c10a7bc8 eef17f98 ee8aadc0 
> 0001 
> [1.529266] dcc0: c10a7bc8 0010   eef19000 eef19000 
> eef17f90 
> [1.537506] dce0: 0010 001a 0013   c062bef0 
> 000a 001a
> [1.545745] dd00:  0013  eef19000 c10a7b78  
> c10a7b88 
> [1.553985] dd20:  c06a06b8 eef19000 c18bfe4c  c05fcd9c 
>  ee8add70
> [1.562194] dd40: c05fcee8 0001  c18bfe08  c05fb2d4 
> ee9eccd4 eef13c54
> [1.570434] dd60: eef19000 eef19034 c10affe0 c05fca58 eef19000 0001 
> c18bfe08 eef19008
> [1.578674] dd80: eef19000 c10affe0  c05fc0d4 eef19008 eecdc000 
> eef19000 c05fa478
> [1.586914] dda0:  eef19000 eef19260  eef19000 eecdc000 
>  eea61c10
> [1.595123] ddc0: 0001  c0d7f208 c06a184c eecdc000 ef6e9a2c 
> ef6e9a7c eef19000
> [1.603363] dde0: 0001 c06a20ac  0002 c0add880 eea61c10 
> c06a1bd8 002dc6c0
> [1.611602] de00: eea61c10 eef17210 eecdc000 eecdc000 eea61c10 eea61c10 
> c0da4ba0 c0da4b98
> [1.619812] de20: 01f0 c06a243c  eecdc4e0 eecdc000 eecdc000 
> eea61c10 c06a5e60
> [1.628051] de40:  6013 c1897138 0004 8132535b eea61c10 
> ffed c10b0c74
> [1.636291] de60: fdfb   c0f66858 c0f005a8 c05fecf8 
> eea61c10 c18bfe4c
> [1.644531] de80:  c10b0c74  c05fcd9c eea61c10 c10b0c74 
> eea61c44 
> [1.652740] dea0: c10f8000 0007 c0f66858 c05fcee4  c10b0c74 
> c05fce24 c05fb228
> [1.660980] dec0: ee8a58a4 eea5ac50 c10b0c74 eef13580 c10a5720 c05fc2e4 
> c0d332c0 c0f4365c
> [1.669219] dee0:  c10b0c74 c0f4365c  c0e4f6ec c05fdd28 
> e000 c0f4365c
> [1.677429] df00:  c0101874 0134  efffec00 efffecdd 
> c0e50efc 0134
> [1.685668] df20: 0134 c015f5dc c0e4f6ec  0006 0006 
> efffecdd 
> [1.693908] df40: c0f7f7cc 0006 c10f8000 c0f6684c c0f7fe74 c10f8000 
> c0f66850 c10f8000
> [1.702148] df60: 0007 

Re: [RFC PATCH 1/2] mmc: sdhci: add quirk SDHCI_QUIRK2_BROKEN_SDMA_BOUNDARY_BUFFER

2017-07-11 Thread Ulf Hansson
On 28 June 2017 at 15:35,   wrote:
> From: Srinivas Kandagatla 
>
> This patch adds quirk to sdhci controllers which are broken when
> HOST SDMA Buffer Boundary is programmed in Block Size Register (0x04)
> when using ADMA. Qualcomm sdhci controller is one of such type, writing
> to this bits is un-supported.
>
> Signed-off-by: Srinivas Kandagatla 
> ---
>  drivers/mmc/host/sdhci.c | 24 ++--
>  drivers/mmc/host/sdhci.h |  2 ++
>  2 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index ecd0d4350e8a..d68ff1955761 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -765,6 +765,20 @@ static void sdhci_set_timeout(struct sdhci_host *host, 
> struct mmc_command *cmd)
> }
>  }
>
> +static void sdhci_set_blk_size_reg(struct sdhci_host *host,
> +  unsigned int sdma_boundary,
> +  unsigned int blksz)
> +{
> +   if ((host->quirks2 & SDHCI_QUIRK2_BROKEN_SDMA_BOUNDARY_BUFFER) &&
> +   (host->flags & SDHCI_USE_ADMA)) {
> +   sdhci_writew(host, SDHCI_MAKE_BLKSZ(0, blksz),
> +SDHCI_BLOCK_SIZE);
> +   } else {
> +   sdhci_writew(host, SDHCI_MAKE_BLKSZ(sdma_boundary, blksz),
> +SDHCI_BLOCK_SIZE);
> +   }
> +}
> +
>  static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command 
> *cmd)
>  {
> u8 ctrl;
> @@ -897,8 +911,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, 
> struct mmc_command *cmd)
> sdhci_set_transfer_irqs(host);
>
> /* Set the DMA boundary value and block size */
> -   sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
> -   data->blksz), SDHCI_BLOCK_SIZE);
> +   sdhci_set_blk_size_reg(host, SDHCI_DEFAULT_BOUNDARY_ARG, data->blksz);
> sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
>  }
>
> @@ -2052,9 +2065,9 @@ static void sdhci_send_tuning(struct sdhci_host *host, 
> u32 opcode)
>  */
> if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200 &&
> mmc->ios.bus_width == MMC_BUS_WIDTH_8)
> -   sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128), 
> SDHCI_BLOCK_SIZE);
> +   sdhci_set_blk_size_reg(host, SDHCI_DEFAULT_BOUNDARY_ARG, 128);
> else
> -   sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE);
> +   sdhci_set_blk_size_reg(host, SDHCI_DEFAULT_BOUNDARY_ARG, 64);
>
> /*
>  * The tuning block is sent by the card to the host controller.
> @@ -2998,8 +3011,7 @@ void sdhci_cqe_enable(struct mmc_host *mmc)
> ctrl |= SDHCI_CTRL_ADMA32;
> sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
>
> -   sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, 512),
> -SDHCI_BLOCK_SIZE);
> +   sdhci_set_blk_size_reg(host, SDHCI_DEFAULT_BOUNDARY_ARG, 512);
>
> /* Set maximum timeout */
> sdhci_writeb(host, 0xE, SDHCI_TIMEOUT_CONTROL);
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 0469fa191493..9a1343509bb5 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -435,6 +435,8 @@ struct sdhci_host {
>  #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14)
>  /* Broken Clock divider zero in controller */
>  #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15)
> +/* Controller doesn't support sdma boundray buffer setup when using ADMA */
> +#define SDHCI_QUIRK2_BROKEN_SDMA_BOUNDARY_BUFFER   (1<<16)
>
> int irq;/* Device IRQ */
> void __iomem *ioaddr;   /* Mapped address */
> --
> 2.11.0
>

This change seems like a reasonable justification for adding a new
SDHCI quirk, even if we in general wants to avoid that.

Adrian?

Kind regards
Uffe


Re: [RFC PATCH 1/2] mmc: sdhci: add quirk SDHCI_QUIRK2_BROKEN_SDMA_BOUNDARY_BUFFER

2017-07-11 Thread Ulf Hansson
On 28 June 2017 at 15:35,   wrote:
> From: Srinivas Kandagatla 
>
> This patch adds quirk to sdhci controllers which are broken when
> HOST SDMA Buffer Boundary is programmed in Block Size Register (0x04)
> when using ADMA. Qualcomm sdhci controller is one of such type, writing
> to this bits is un-supported.
>
> Signed-off-by: Srinivas Kandagatla 
> ---
>  drivers/mmc/host/sdhci.c | 24 ++--
>  drivers/mmc/host/sdhci.h |  2 ++
>  2 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index ecd0d4350e8a..d68ff1955761 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -765,6 +765,20 @@ static void sdhci_set_timeout(struct sdhci_host *host, 
> struct mmc_command *cmd)
> }
>  }
>
> +static void sdhci_set_blk_size_reg(struct sdhci_host *host,
> +  unsigned int sdma_boundary,
> +  unsigned int blksz)
> +{
> +   if ((host->quirks2 & SDHCI_QUIRK2_BROKEN_SDMA_BOUNDARY_BUFFER) &&
> +   (host->flags & SDHCI_USE_ADMA)) {
> +   sdhci_writew(host, SDHCI_MAKE_BLKSZ(0, blksz),
> +SDHCI_BLOCK_SIZE);
> +   } else {
> +   sdhci_writew(host, SDHCI_MAKE_BLKSZ(sdma_boundary, blksz),
> +SDHCI_BLOCK_SIZE);
> +   }
> +}
> +
>  static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command 
> *cmd)
>  {
> u8 ctrl;
> @@ -897,8 +911,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, 
> struct mmc_command *cmd)
> sdhci_set_transfer_irqs(host);
>
> /* Set the DMA boundary value and block size */
> -   sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
> -   data->blksz), SDHCI_BLOCK_SIZE);
> +   sdhci_set_blk_size_reg(host, SDHCI_DEFAULT_BOUNDARY_ARG, data->blksz);
> sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
>  }
>
> @@ -2052,9 +2065,9 @@ static void sdhci_send_tuning(struct sdhci_host *host, 
> u32 opcode)
>  */
> if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200 &&
> mmc->ios.bus_width == MMC_BUS_WIDTH_8)
> -   sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128), 
> SDHCI_BLOCK_SIZE);
> +   sdhci_set_blk_size_reg(host, SDHCI_DEFAULT_BOUNDARY_ARG, 128);
> else
> -   sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE);
> +   sdhci_set_blk_size_reg(host, SDHCI_DEFAULT_BOUNDARY_ARG, 64);
>
> /*
>  * The tuning block is sent by the card to the host controller.
> @@ -2998,8 +3011,7 @@ void sdhci_cqe_enable(struct mmc_host *mmc)
> ctrl |= SDHCI_CTRL_ADMA32;
> sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
>
> -   sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, 512),
> -SDHCI_BLOCK_SIZE);
> +   sdhci_set_blk_size_reg(host, SDHCI_DEFAULT_BOUNDARY_ARG, 512);
>
> /* Set maximum timeout */
> sdhci_writeb(host, 0xE, SDHCI_TIMEOUT_CONTROL);
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 0469fa191493..9a1343509bb5 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -435,6 +435,8 @@ struct sdhci_host {
>  #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14)
>  /* Broken Clock divider zero in controller */
>  #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15)
> +/* Controller doesn't support sdma boundray buffer setup when using ADMA */
> +#define SDHCI_QUIRK2_BROKEN_SDMA_BOUNDARY_BUFFER   (1<<16)
>
> int irq;/* Device IRQ */
> void __iomem *ioaddr;   /* Mapped address */
> --
> 2.11.0
>

This change seems like a reasonable justification for adding a new
SDHCI quirk, even if we in general wants to avoid that.

Adrian?

Kind regards
Uffe


Re: [PATCH 1/2] staging: ccree: remove unnecessary cast on kmalloc

2017-07-11 Thread Gilad Ben-Yossef
On Sun, Jul 9, 2017 at 8:43 AM, Gustavo A. R. Silva
 wrote:
> The assignment operator implicitly converts a void pointer to the type of the
> pointer it is assigned to.
>
> This issue was detected using Coccinelle and the following semantic patch:
>
> @@
> expression * e;
> expression arg1, arg2;
> type T;
> @@
>
> - e=(T*)
> + e=
> kmalloc(arg1, arg2);
>
> Signed-off-by: Gustavo A. R. Silva 

For both patches:

Acked-by: Gilad Ben-Yossef 

> ---
>  drivers/staging/ccree/ssi_buffer_mgr.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/staging/ccree/ssi_buffer_mgr.c 
> b/drivers/staging/ccree/ssi_buffer_mgr.c
> index b35871e..18a8694 100644
> --- a/drivers/staging/ccree/ssi_buffer_mgr.c
> +++ b/drivers/staging/ccree/ssi_buffer_mgr.c
> @@ -1725,8 +1725,7 @@ int ssi_buffer_mgr_init(struct ssi_drvdata *drvdata)
> struct buff_mgr_handle *buff_mgr_handle;
> struct device *dev = >plat_dev->dev;
>
> -   buff_mgr_handle = (struct buff_mgr_handle *)
> -   kmalloc(sizeof(struct buff_mgr_handle), GFP_KERNEL);
> +   buff_mgr_handle = kmalloc(sizeof(struct buff_mgr_handle), GFP_KERNEL);
> if (!buff_mgr_handle)
> return -ENOMEM;
>
> --
> 2.5.0
>

Thanks,
Gilad



-- 
Gilad Ben-Yossef
Chief Coffee Drinker

"If you take a class in large-scale robotics, can you end up in a
situation where the homework eats your dog?"
 -- Jean-Baptiste Queru


Re: [PATCH 1/2] staging: ccree: remove unnecessary cast on kmalloc

2017-07-11 Thread Gilad Ben-Yossef
On Sun, Jul 9, 2017 at 8:43 AM, Gustavo A. R. Silva
 wrote:
> The assignment operator implicitly converts a void pointer to the type of the
> pointer it is assigned to.
>
> This issue was detected using Coccinelle and the following semantic patch:
>
> @@
> expression * e;
> expression arg1, arg2;
> type T;
> @@
>
> - e=(T*)
> + e=
> kmalloc(arg1, arg2);
>
> Signed-off-by: Gustavo A. R. Silva 

For both patches:

Acked-by: Gilad Ben-Yossef 

> ---
>  drivers/staging/ccree/ssi_buffer_mgr.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/staging/ccree/ssi_buffer_mgr.c 
> b/drivers/staging/ccree/ssi_buffer_mgr.c
> index b35871e..18a8694 100644
> --- a/drivers/staging/ccree/ssi_buffer_mgr.c
> +++ b/drivers/staging/ccree/ssi_buffer_mgr.c
> @@ -1725,8 +1725,7 @@ int ssi_buffer_mgr_init(struct ssi_drvdata *drvdata)
> struct buff_mgr_handle *buff_mgr_handle;
> struct device *dev = >plat_dev->dev;
>
> -   buff_mgr_handle = (struct buff_mgr_handle *)
> -   kmalloc(sizeof(struct buff_mgr_handle), GFP_KERNEL);
> +   buff_mgr_handle = kmalloc(sizeof(struct buff_mgr_handle), GFP_KERNEL);
> if (!buff_mgr_handle)
> return -ENOMEM;
>
> --
> 2.5.0
>

Thanks,
Gilad



-- 
Gilad Ben-Yossef
Chief Coffee Drinker

"If you take a class in large-scale robotics, can you end up in a
situation where the homework eats your dog?"
 -- Jean-Baptiste Queru


[PATCH v4 1/1] ARM: dts: imx53: Add GE Healthcare PPD

2017-07-11 Thread Martyn Welch
From: Fabien Lahoudere 

PPD is a product from GE Healthcare to monitor vital biometric signals.

Signed-off-by: Fabien Lahoudere 
Signed-off-by: Sebastian Reichel 
Signed-off-by: Martyn Welch 
---

Changes since PATCHv3: https://patchwork.kernel.org/patch/9819017/
 - licensing modified
 - manufacturer changed to GE
 - regulator nodes corrected
 - backlight node corrected
 - flags rather than magic numbers used
 - registers for usbphys added
 - set up IOMUX configuration correctly
 - various whitespace corrections
 - removed unused fsl,mode node
 - missing unit addresses added
 - reordered nodes and properties as requested
Changes since PATCHv2: https://patchwork.kernel.org/patch/9809681/
 - drop dma-info property from serial nodes. That property is not
   available in mainline.
Changes since PATCHv1: https://patchwork.kernel.org/patch/9265391/
 - fixed issues raised by Mark
 - added some missing vendor prefixes
 - dropped anx9804 nodes (no upstream support/binding)
 - use proper chip-select for ecspi1.cs0

 arch/arm/boot/dts/Makefile  |1 +
 arch/arm/boot/dts/imx53-ppd.dts | 1059 +++
 2 files changed, 1060 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx53-ppd.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 9c5e1d9..135ae56 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -340,6 +340,7 @@ dtb-$(CONFIG_SOC_IMX53) += \
imx53-ard.dtb \
imx53-m53evk.dtb \
imx53-mba53.dtb \
+   imx53-ppd.dtb \
imx53-qsb.dtb \
imx53-qsrb.dtb \
imx53-smd.dtb \
diff --git a/arch/arm/boot/dts/imx53-ppd.dts b/arch/arm/boot/dts/imx53-ppd.dts
new file mode 100644
index 000..0480fa9
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-ppd.dts
@@ -0,0 +1,1059 @@
+/*
+ * Copyright 2014 General Electric Company
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "imx53.dtsi"
+
+/ {
+   model = "Freescale i.MX53 CPUV0 PPD rev6";
+   compatible = "ge,imx53-cpuvo", "fsl,imx53";
+
+   aliases {
+   spi0 = 
+   spi1 = 
+   spi2 = 
+   };
+
+   chosen {
+   stdout-path = ":115200n8";
+   };
+
+   memory@7000 {
+   device_type = "memory";
+   reg = <0x7000 0x2000>,
+ <0xb000 0x2000>;
+   };
+
+   cko2_11M: sgtl_clock_cko2 {
+   compatible = "fixed-clock";
+   #clock-cells = <0>;
+   clock-frequency = <11289600>;
+   };
+
+   sgtlsound: sound {
+   compatible = "fsl,imx53-cpuvo-sgtl5000",
+"fsl,imx-audio-sgtl5000";
+   model = "imx53-cpuvo-sgtl5000";
+   ssi-controller = <>;
+   audio-codec = <>;
+   audio-routing =
+   "MIC_IN", "Mic Jack",
+   "Mic Jack", "Mic Bias",
+   "Headphone 

[PATCH v4 1/1] ARM: dts: imx53: Add GE Healthcare PPD

2017-07-11 Thread Martyn Welch
From: Fabien Lahoudere 

PPD is a product from GE Healthcare to monitor vital biometric signals.

Signed-off-by: Fabien Lahoudere 
Signed-off-by: Sebastian Reichel 
Signed-off-by: Martyn Welch 
---

Changes since PATCHv3: https://patchwork.kernel.org/patch/9819017/
 - licensing modified
 - manufacturer changed to GE
 - regulator nodes corrected
 - backlight node corrected
 - flags rather than magic numbers used
 - registers for usbphys added
 - set up IOMUX configuration correctly
 - various whitespace corrections
 - removed unused fsl,mode node
 - missing unit addresses added
 - reordered nodes and properties as requested
Changes since PATCHv2: https://patchwork.kernel.org/patch/9809681/
 - drop dma-info property from serial nodes. That property is not
   available in mainline.
Changes since PATCHv1: https://patchwork.kernel.org/patch/9265391/
 - fixed issues raised by Mark
 - added some missing vendor prefixes
 - dropped anx9804 nodes (no upstream support/binding)
 - use proper chip-select for ecspi1.cs0

 arch/arm/boot/dts/Makefile  |1 +
 arch/arm/boot/dts/imx53-ppd.dts | 1059 +++
 2 files changed, 1060 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx53-ppd.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 9c5e1d9..135ae56 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -340,6 +340,7 @@ dtb-$(CONFIG_SOC_IMX53) += \
imx53-ard.dtb \
imx53-m53evk.dtb \
imx53-mba53.dtb \
+   imx53-ppd.dtb \
imx53-qsb.dtb \
imx53-qsrb.dtb \
imx53-smd.dtb \
diff --git a/arch/arm/boot/dts/imx53-ppd.dts b/arch/arm/boot/dts/imx53-ppd.dts
new file mode 100644
index 000..0480fa9
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-ppd.dts
@@ -0,0 +1,1059 @@
+/*
+ * Copyright 2014 General Electric Company
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "imx53.dtsi"
+
+/ {
+   model = "Freescale i.MX53 CPUV0 PPD rev6";
+   compatible = "ge,imx53-cpuvo", "fsl,imx53";
+
+   aliases {
+   spi0 = 
+   spi1 = 
+   spi2 = 
+   };
+
+   chosen {
+   stdout-path = ":115200n8";
+   };
+
+   memory@7000 {
+   device_type = "memory";
+   reg = <0x7000 0x2000>,
+ <0xb000 0x2000>;
+   };
+
+   cko2_11M: sgtl_clock_cko2 {
+   compatible = "fixed-clock";
+   #clock-cells = <0>;
+   clock-frequency = <11289600>;
+   };
+
+   sgtlsound: sound {
+   compatible = "fsl,imx53-cpuvo-sgtl5000",
+"fsl,imx-audio-sgtl5000";
+   model = "imx53-cpuvo-sgtl5000";
+   ssi-controller = <>;
+   audio-codec = <>;
+   audio-routing =
+   "MIC_IN", "Mic Jack",
+   "Mic Jack", "Mic Bias",
+   "Headphone Jack", "HP_OUT";
+   mux-int-port = <2>;
+   mux-ext-port = <6>;
+   status = "okay";
+   };
+
+   

[PATCH] vmemmap, memory_hotplug: fallback to base pages for vmmap

2017-07-11 Thread Michal Hocko
From: Michal Hocko 

vmemmap_populate uses huge pages if the CPU supports them which is good
and usually what we want. vmemmap_alloc_block will use the bootmem
allocator in the early initialization so the allocation will most likely
succeed. This is not the case for the memory hotplug though. Such an
allocation can easily fail under memory pressure. Especially so when the
kernel memory is restricted with movable_node parameter.

There is no real reason to fail the vmemmap_populate when
vmemmap_populate_hugepages fails though. We can still fallback to
vmemmap_populate_basepages and use base pages. The performance will not
be optimal but this is much better than failing the memory hot add.

Signed-off-by: Michal Hocko 
---
 arch/x86/mm/init_64.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 136422d7d539..e6e3c755b9cb 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1401,15 +1401,16 @@ static int __meminit 
vmemmap_populate_hugepages(unsigned long start,
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int 
node)
 {
struct vmem_altmap *altmap = to_vmem_altmap(start);
-   int err;
+   int err = -ENOMEM;
 
if (boot_cpu_has(X86_FEATURE_PSE))
err = vmemmap_populate_hugepages(start, end, node, altmap);
else if (altmap) {
pr_err_once("%s: no cpu support for altmap allocations\n",
__func__);
-   err = -ENOMEM;
-   } else
+   return err;
+   }
+   if (err)
err = vmemmap_populate_basepages(start, end, node);
if (!err)
sync_global_pgds(start, end - 1);
-- 
2.11.0



[PATCH] vmemmap, memory_hotplug: fallback to base pages for vmmap

2017-07-11 Thread Michal Hocko
From: Michal Hocko 

vmemmap_populate uses huge pages if the CPU supports them which is good
and usually what we want. vmemmap_alloc_block will use the bootmem
allocator in the early initialization so the allocation will most likely
succeed. This is not the case for the memory hotplug though. Such an
allocation can easily fail under memory pressure. Especially so when the
kernel memory is restricted with movable_node parameter.

There is no real reason to fail the vmemmap_populate when
vmemmap_populate_hugepages fails though. We can still fallback to
vmemmap_populate_basepages and use base pages. The performance will not
be optimal but this is much better than failing the memory hot add.

Signed-off-by: Michal Hocko 
---
 arch/x86/mm/init_64.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 136422d7d539..e6e3c755b9cb 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1401,15 +1401,16 @@ static int __meminit 
vmemmap_populate_hugepages(unsigned long start,
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int 
node)
 {
struct vmem_altmap *altmap = to_vmem_altmap(start);
-   int err;
+   int err = -ENOMEM;
 
if (boot_cpu_has(X86_FEATURE_PSE))
err = vmemmap_populate_hugepages(start, end, node, altmap);
else if (altmap) {
pr_err_once("%s: no cpu support for altmap allocations\n",
__func__);
-   err = -ENOMEM;
-   } else
+   return err;
+   }
+   if (err)
err = vmemmap_populate_basepages(start, end, node);
if (!err)
sync_global_pgds(start, end - 1);
-- 
2.11.0



Re: [PATCH 16/17] RISC-V: User-facing API

2017-07-11 Thread Christoph Hellwig
> +++ b/arch/riscv/kernel/sys_riscv.c
> @@ -0,0 +1,43 @@
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2014 Darius Rad 
> + * Copyright (C) 2017 SiFive
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful,
> + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *   GNU General Public License for more details.
> + */
> +
> +#include 
> +#include 

Should not be needed.

> +#ifdef CONFIG_64BIT
> +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
> + unsigned long, prot, unsigned long, flags,
> + unsigned long, fd, off_t, offset)
> +{
> + if (unlikely(offset & (~PAGE_MASK)))
> + return -EINVAL;
> + return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
> +}
> +#else
> +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> + unsigned long, prot, unsigned long, flags,
> + unsigned long, fd, off_t, offset)
> +{
> + /*
> +  * Note that the shift for mmap2 is constant (12),
> +  * regardless of PAGE_SIZE
> +  */
> + if (unlikely(offset & (~PAGE_MASK >> 12)))
> + return -EINVAL;
> + return sys_mmap_pgoff(addr, len, prot, flags, fd,
> + offset >> (PAGE_SHIFT - 12));
> +}
> +#endif /* !CONFIG_64BIT */

Most modern ports seem to expose sys_mmap_pgoff as the
syscall directly.  Any reason you're doing this differently?

But even the code for the older ones should probably be consolidated..


Re: [PATCH 16/17] RISC-V: User-facing API

2017-07-11 Thread Christoph Hellwig
> +++ b/arch/riscv/kernel/sys_riscv.c
> @@ -0,0 +1,43 @@
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2014 Darius Rad 
> + * Copyright (C) 2017 SiFive
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful,
> + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *   GNU General Public License for more details.
> + */
> +
> +#include 
> +#include 

Should not be needed.

> +#ifdef CONFIG_64BIT
> +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
> + unsigned long, prot, unsigned long, flags,
> + unsigned long, fd, off_t, offset)
> +{
> + if (unlikely(offset & (~PAGE_MASK)))
> + return -EINVAL;
> + return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
> +}
> +#else
> +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> + unsigned long, prot, unsigned long, flags,
> + unsigned long, fd, off_t, offset)
> +{
> + /*
> +  * Note that the shift for mmap2 is constant (12),
> +  * regardless of PAGE_SIZE
> +  */
> + if (unlikely(offset & (~PAGE_MASK >> 12)))
> + return -EINVAL;
> + return sys_mmap_pgoff(addr, len, prot, flags, fd,
> + offset >> (PAGE_SHIFT - 12));
> +}
> +#endif /* !CONFIG_64BIT */

Most modern ports seem to expose sys_mmap_pgoff as the
syscall directly.  Any reason you're doing this differently?

But even the code for the older ones should probably be consolidated..


Re: [RFC PATCH 2/4] pmbus: Add fan configuration support

2017-07-11 Thread Guenter Roeck

On 07/10/2017 06:56 AM, Andrew Jeffery wrote:

Augment PMBus support to include control of fans via the
FAN_COMMAND_[1-4] registers, both in RPM and PWM modes. The behaviour
of FAN_CONFIG_{1_2,3_4} and FAN_COMMAND_[1-4] are tightly coupled, and
their interactions do not fit the existing use of struct pmbus_sensor.
The patch introduces struct pmbus_fan_ctrl to distinguish from the
simple sensor case, along with associated sysfs show/set implementations.

Further, the interpreting the value of FAN_COMMAND_[1-4] depends on both
the current fan mode (RPM or PWM, as configured in
FAN_CONFIG_{1_2,3_4}), and the device-specific behaviour for the
register. For example, the MAX31785 chip defines the following:

PWM (m = 1, b = 0, R = 2):
  0x - 0x2710: 0 - 100% fan PWM duty cycle
  0x2711 - 0x7fff: 100% fan PWM duty cycle
  0x8000 - 0x: Ignore FAN_COMMAND_[1-4], use automatic fan control

RPM (m = 1, b = 0, R = 0):
  0x - 0x7FFF: 0 - 32,767 RPM
  0x8000 - 0x: Ignore FAN_COMMAND_[1-4], use automatic fan control

To handle the device-specific interpretation of the FAN_COMMAND_[1-4],
add an optional callbacks to the info struct to get/set the 'mode'
value required for the pwm[1-n]_enable sysfs attribute. A fallback
calculation exists if the callbacks are not populated; the fallback
ignores device-specific ranges and tries to determine a reasonable value
from FAN_CONFIG_{1_2,3_4} and FAN_COMMAND_[1-4].



This seems overly complex, but unfortunately I don't have time for a detailed
analysis right now. Couple of comments below.

Guenter


Signed-off-by: Andrew Jeffery 
---
  drivers/hwmon/pmbus/pmbus.h  |   7 +
  drivers/hwmon/pmbus/pmbus_core.c | 335 +++
  2 files changed, 342 insertions(+)

diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index bfcb13bae34b..927eabc1b273 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -223,6 +223,8 @@ enum pmbus_regs {
  #define PB_FAN_1_RPM  BIT(6)
  #define PB_FAN_1_INSTALLEDBIT(7)
  
+enum pmbus_fan_mode { percent = 0, rpm };

+
  /*
   * STATUS_BYTE, STATUS_WORD (lower)
   */
@@ -380,6 +382,11 @@ struct pmbus_driver_info {
int (*identify)(struct i2c_client *client,
struct pmbus_driver_info *info);
  
+	/* Allow the driver to interpret the fan command value */

+   int (*get_pwm_mode)(int id, u8 fan_config, u16 fan_command);
+   int (*set_pwm_mode)(int id, long mode, u8 *fan_config,
+   u16 *fan_command);
+


It is not entirely obvious to me why this would require new callback functions.
Can you overload PMBUS_FAN_CONFIG_12 / PMBUS_FAN_CONFIG_34 or, if that does not
work for some reason, introduce a virtual register, such as PMBUS_VIRT_PWM_MODE 
?


/* Regulator functionality, if supported by this chip driver. */
int num_regulators;
const struct regulator_desc *reg_desc;
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index ba59eaef2e07..3b0a55bbbd2c 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -69,6 +69,38 @@ struct pmbus_sensor {
  #define to_pmbus_sensor(_attr) \
container_of(_attr, struct pmbus_sensor, attribute)
  
+#define PB_FAN_CONFIG_RPM		PB_FAN_2_RPM

+#define PB_FAN_CONFIG_INSTALLEDPB_FAN_2_INSTALLEDBUS_VIRT_


Something seems odd here. PB_FAN_2_INSTALLEDBUS_VIRT_ ?


+#define PB_FAN_CONFIG_MASK(i)  (0xff << (4 * !((i) & 1)))
+#define PB_FAN_CONFIG_GET(i, n)(((n) >> (4 * !((i) & 1))) & 
0xff)
+#define PB_FAN_CONFIG_PUT(i, n)(((n) & 0xff) << (4 * !((i) & 
1)))
+


Aren't there standard bit manipulation macros for that ? Either case, this is 
just to avoid
having to use the existing defines. Ok, but then I think it would make more 
sense to
make it generic, ie change the core to not use PB_FAN_2_RPM / PB_FAN_1_RPM etc.
but PB_FAN_RPM(index) everywhere.


+struct pmbus_fan_ctrl_attr {
+   struct device_attribute attribute;
+   char name[PMBUS_NAME_SIZE];
+};
+
+struct pmbus_fan_ctrl {
+   struct pmbus_fan_ctrl_attr fan_target;
+   struct pmbus_fan_ctrl_attr pwm;
+   struct pmbus_fan_ctrl_attr pwm_enable;
+   int index;
+   u8 page;
+   u8 id;
+   u8 config;
+   u16 command;
+};
+#define to_pmbus_fan_ctrl_attr(_attr) \
+   container_of(_attr, struct pmbus_fan_ctrl_attr, attribute)
+#define fan_target_to_pmbus_fan_ctrl(_attr) \
+   container_of(to_pmbus_fan_ctrl_attr(_attr), struct pmbus_fan_ctrl, \
+   fan_target)
+#define pwm_to_pmbus_fan_ctrl(_attr) \
+   container_of(to_pmbus_fan_ctrl_attr(_attr), struct pmbus_fan_ctrl, pwm)
+#define pwm_enable_to_pmbus_fan_ctrl(_attr) \
+   container_of(to_pmbus_fan_ctrl_attr(_attr), struct pmbus_fan_ctrl, \
+   pwm_enable)
+
  

Re: [RFC PATCH 2/4] pmbus: Add fan configuration support

2017-07-11 Thread Guenter Roeck

On 07/10/2017 06:56 AM, Andrew Jeffery wrote:

Augment PMBus support to include control of fans via the
FAN_COMMAND_[1-4] registers, both in RPM and PWM modes. The behaviour
of FAN_CONFIG_{1_2,3_4} and FAN_COMMAND_[1-4] are tightly coupled, and
their interactions do not fit the existing use of struct pmbus_sensor.
The patch introduces struct pmbus_fan_ctrl to distinguish from the
simple sensor case, along with associated sysfs show/set implementations.

Further, the interpreting the value of FAN_COMMAND_[1-4] depends on both
the current fan mode (RPM or PWM, as configured in
FAN_CONFIG_{1_2,3_4}), and the device-specific behaviour for the
register. For example, the MAX31785 chip defines the following:

PWM (m = 1, b = 0, R = 2):
  0x - 0x2710: 0 - 100% fan PWM duty cycle
  0x2711 - 0x7fff: 100% fan PWM duty cycle
  0x8000 - 0x: Ignore FAN_COMMAND_[1-4], use automatic fan control

RPM (m = 1, b = 0, R = 0):
  0x - 0x7FFF: 0 - 32,767 RPM
  0x8000 - 0x: Ignore FAN_COMMAND_[1-4], use automatic fan control

To handle the device-specific interpretation of the FAN_COMMAND_[1-4],
add an optional callbacks to the info struct to get/set the 'mode'
value required for the pwm[1-n]_enable sysfs attribute. A fallback
calculation exists if the callbacks are not populated; the fallback
ignores device-specific ranges and tries to determine a reasonable value
from FAN_CONFIG_{1_2,3_4} and FAN_COMMAND_[1-4].



This seems overly complex, but unfortunately I don't have time for a detailed
analysis right now. Couple of comments below.

Guenter


Signed-off-by: Andrew Jeffery 
---
  drivers/hwmon/pmbus/pmbus.h  |   7 +
  drivers/hwmon/pmbus/pmbus_core.c | 335 +++
  2 files changed, 342 insertions(+)

diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index bfcb13bae34b..927eabc1b273 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -223,6 +223,8 @@ enum pmbus_regs {
  #define PB_FAN_1_RPM  BIT(6)
  #define PB_FAN_1_INSTALLEDBIT(7)
  
+enum pmbus_fan_mode { percent = 0, rpm };

+
  /*
   * STATUS_BYTE, STATUS_WORD (lower)
   */
@@ -380,6 +382,11 @@ struct pmbus_driver_info {
int (*identify)(struct i2c_client *client,
struct pmbus_driver_info *info);
  
+	/* Allow the driver to interpret the fan command value */

+   int (*get_pwm_mode)(int id, u8 fan_config, u16 fan_command);
+   int (*set_pwm_mode)(int id, long mode, u8 *fan_config,
+   u16 *fan_command);
+


It is not entirely obvious to me why this would require new callback functions.
Can you overload PMBUS_FAN_CONFIG_12 / PMBUS_FAN_CONFIG_34 or, if that does not
work for some reason, introduce a virtual register, such as PMBUS_VIRT_PWM_MODE 
?


/* Regulator functionality, if supported by this chip driver. */
int num_regulators;
const struct regulator_desc *reg_desc;
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index ba59eaef2e07..3b0a55bbbd2c 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -69,6 +69,38 @@ struct pmbus_sensor {
  #define to_pmbus_sensor(_attr) \
container_of(_attr, struct pmbus_sensor, attribute)
  
+#define PB_FAN_CONFIG_RPM		PB_FAN_2_RPM

+#define PB_FAN_CONFIG_INSTALLEDPB_FAN_2_INSTALLEDBUS_VIRT_


Something seems odd here. PB_FAN_2_INSTALLEDBUS_VIRT_ ?


+#define PB_FAN_CONFIG_MASK(i)  (0xff << (4 * !((i) & 1)))
+#define PB_FAN_CONFIG_GET(i, n)(((n) >> (4 * !((i) & 1))) & 
0xff)
+#define PB_FAN_CONFIG_PUT(i, n)(((n) & 0xff) << (4 * !((i) & 
1)))
+


Aren't there standard bit manipulation macros for that ? Either case, this is 
just to avoid
having to use the existing defines. Ok, but then I think it would make more 
sense to
make it generic, ie change the core to not use PB_FAN_2_RPM / PB_FAN_1_RPM etc.
but PB_FAN_RPM(index) everywhere.


+struct pmbus_fan_ctrl_attr {
+   struct device_attribute attribute;
+   char name[PMBUS_NAME_SIZE];
+};
+
+struct pmbus_fan_ctrl {
+   struct pmbus_fan_ctrl_attr fan_target;
+   struct pmbus_fan_ctrl_attr pwm;
+   struct pmbus_fan_ctrl_attr pwm_enable;
+   int index;
+   u8 page;
+   u8 id;
+   u8 config;
+   u16 command;
+};
+#define to_pmbus_fan_ctrl_attr(_attr) \
+   container_of(_attr, struct pmbus_fan_ctrl_attr, attribute)
+#define fan_target_to_pmbus_fan_ctrl(_attr) \
+   container_of(to_pmbus_fan_ctrl_attr(_attr), struct pmbus_fan_ctrl, \
+   fan_target)
+#define pwm_to_pmbus_fan_ctrl(_attr) \
+   container_of(to_pmbus_fan_ctrl_attr(_attr), struct pmbus_fan_ctrl, pwm)
+#define pwm_enable_to_pmbus_fan_ctrl(_attr) \
+   container_of(to_pmbus_fan_ctrl_attr(_attr), struct pmbus_fan_ctrl, \
+   pwm_enable)
+
  struct 

Re: [PATCH v2] staging: ccree: Use __func__ instead of function name

2017-07-11 Thread Gilad Ben-Yossef
Hello Karthik ,

Thank you for the patch.

On Thu, Jun 29, 2017 at 8:08 PM,   wrote:
> From: Karthik Tummala 
>
> Fixed following checkpatch.pl warning:
> WARNING: Prefer using '"%s...", __func__' to using
> the function's name, in a string
>
> It is prefered to use '%s & __func__' instead of function
> name for logging.
>
> Signed-off-by: Karthik Tummala 
> ---
> Changes for v2:
> v1 was a patch series, which consisted of two patches in which
> second one was already submitted by Gilad Ben-Yossef, so dropped
> that one.
>
> Patch generated on staging-testing as suggested by Greg-K H.
> ---
>  drivers/staging/ccree/ssi_aead.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/staging/ccree/ssi_aead.c 
> b/drivers/staging/ccree/ssi_aead.c
> index 1fc0b05..1168161 100644
> --- a/drivers/staging/ccree/ssi_aead.c
> +++ b/drivers/staging/ccree/ssi_aead.c
> @@ -1886,7 +1886,7 @@ static int config_gcm_context(struct aead_request *req)
> (req->cryptlen - ctx->authsize);
> __be32 counter = cpu_to_be32(2);
>
> -   SSI_LOG_DEBUG("config_gcm_context() cryptlen = %d, req->assoclen = %d 
> ctx->authsize = %d\n", cryptlen, req->assoclen, ctx->authsize);
> +   SSI_LOG_DEBUG("%s() cryptlen = %d, req->assoclen = %d ctx->authsize = 
> %d\n", __func__, cryptlen, req->assoclen, ctx->authsize);
>
> memset(req_ctx->hkey, 0, AES_BLOCK_SIZE);
>
> @@ -2198,7 +2198,7 @@ static int ssi_rfc4106_gcm_setkey(struct crypto_aead 
> *tfm, const u8 *key, unsign
> struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm);
> int rc = 0;
>
> -   SSI_LOG_DEBUG("ssi_rfc4106_gcm_setkey()  keylen %d, key %p\n", 
> keylen, key);
> +   SSI_LOG_DEBUG("%s()  keylen %d, key %p\n", __func__, keylen, key);
>
> if (keylen < 4)
> return -EINVAL;
> @@ -2216,7 +2216,7 @@ static int ssi_rfc4543_gcm_setkey(struct crypto_aead 
> *tfm, const u8 *key, unsign
> struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm);
> int rc = 0;
>
> -   SSI_LOG_DEBUG("ssi_rfc4543_gcm_setkey()  keylen %d, key %p\n", 
> keylen, key);
> +   SSI_LOG_DEBUG("%s()  keylen %d, key %p\n", __func__, keylen, key);
>
> if (keylen < 4)
> return -EINVAL;
> --
> 1.9.1
>

Acked-by: Gilad Ben-Yossef 

Gilad

-- 
Gilad Ben-Yossef
Chief Coffee Drinker

"If you take a class in large-scale robotics, can you end up in a
situation where the homework eats your dog?"
 -- Jean-Baptiste Queru


Re: [PATCH v2] staging: ccree: Use __func__ instead of function name

2017-07-11 Thread Gilad Ben-Yossef
Hello Karthik ,

Thank you for the patch.

On Thu, Jun 29, 2017 at 8:08 PM,   wrote:
> From: Karthik Tummala 
>
> Fixed following checkpatch.pl warning:
> WARNING: Prefer using '"%s...", __func__' to using
> the function's name, in a string
>
> It is prefered to use '%s & __func__' instead of function
> name for logging.
>
> Signed-off-by: Karthik Tummala 
> ---
> Changes for v2:
> v1 was a patch series, which consisted of two patches in which
> second one was already submitted by Gilad Ben-Yossef, so dropped
> that one.
>
> Patch generated on staging-testing as suggested by Greg-K H.
> ---
>  drivers/staging/ccree/ssi_aead.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/staging/ccree/ssi_aead.c 
> b/drivers/staging/ccree/ssi_aead.c
> index 1fc0b05..1168161 100644
> --- a/drivers/staging/ccree/ssi_aead.c
> +++ b/drivers/staging/ccree/ssi_aead.c
> @@ -1886,7 +1886,7 @@ static int config_gcm_context(struct aead_request *req)
> (req->cryptlen - ctx->authsize);
> __be32 counter = cpu_to_be32(2);
>
> -   SSI_LOG_DEBUG("config_gcm_context() cryptlen = %d, req->assoclen = %d 
> ctx->authsize = %d\n", cryptlen, req->assoclen, ctx->authsize);
> +   SSI_LOG_DEBUG("%s() cryptlen = %d, req->assoclen = %d ctx->authsize = 
> %d\n", __func__, cryptlen, req->assoclen, ctx->authsize);
>
> memset(req_ctx->hkey, 0, AES_BLOCK_SIZE);
>
> @@ -2198,7 +2198,7 @@ static int ssi_rfc4106_gcm_setkey(struct crypto_aead 
> *tfm, const u8 *key, unsign
> struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm);
> int rc = 0;
>
> -   SSI_LOG_DEBUG("ssi_rfc4106_gcm_setkey()  keylen %d, key %p\n", 
> keylen, key);
> +   SSI_LOG_DEBUG("%s()  keylen %d, key %p\n", __func__, keylen, key);
>
> if (keylen < 4)
> return -EINVAL;
> @@ -2216,7 +2216,7 @@ static int ssi_rfc4543_gcm_setkey(struct crypto_aead 
> *tfm, const u8 *key, unsign
> struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm);
> int rc = 0;
>
> -   SSI_LOG_DEBUG("ssi_rfc4543_gcm_setkey()  keylen %d, key %p\n", 
> keylen, key);
> +   SSI_LOG_DEBUG("%s()  keylen %d, key %p\n", __func__, keylen, key);
>
> if (keylen < 4)
> return -EINVAL;
> --
> 1.9.1
>

Acked-by: Gilad Ben-Yossef 

Gilad

-- 
Gilad Ben-Yossef
Chief Coffee Drinker

"If you take a class in large-scale robotics, can you end up in a
situation where the homework eats your dog?"
 -- Jean-Baptiste Queru


[RESEND PATCH 13/13] vfs: Delete struct fdtable

2017-07-11 Thread Sandhya Bankar
Completing the conversion of the file descriptor allocation code to use
the IDR.

This patch includes below changes:

 - Move max_fds from struct fdtable to files_struct.
 - Added fill_max_fds() routine to calculate the new value of max_fds
   to matches the old behaviour of alloc_fdtable() code which is
   user-visible through /proc.
 - Remove struct fdtable
 - Removed resize_in_progress, resize_wait from files_struct
 - Delete open_fds() & count_open_files()
 - Use READ_ONCE() instead of rcu_read_lock/unlock(). The rcu_read_lock()/
   unlock() was used to dereference the files->fdt. Now we don't use RCU to
   protect files->max_fds. So using READ_ONCE() macro to read the value of
   files->max_fds.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/compat.c |   6 +-
 fs/file.c   | 354 +++-
 fs/proc/array.c |   2 +-
 fs/proc/fd.c|   2 +-
 fs/select.c |   6 +-
 include/linux/fdtable.h |  31 +
 6 files changed, 54 insertions(+), 347 deletions(-)

diff --git a/fs/compat.c b/fs/compat.c
index c61b506..7483c9c 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1153,17 +1153,13 @@ int compat_core_sys_select(int n, compat_ulong_t __user 
*inp,
fd_set_bits fds;
void *bits;
int size, max_fds, ret = -EINVAL;
-   struct fdtable *fdt;
long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
 
if (n < 0)
goto out_nofds;
 
/* max_fds can increase, so grab it once to avoid race */
-   rcu_read_lock();
-   fdt = files_fdtable(current->files);
-   max_fds = fdt->max_fds;
-   rcu_read_unlock();
+   max_fds = READ_ONCE(current->files->max_fds);
if (n > max_fds)
n = max_fds;
 
diff --git a/fs/file.c b/fs/file.c
index 23f198b..3e6cf10 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -31,191 +31,36 @@
 unsigned int sysctl_nr_open_max =
__const_min(INT_MAX, ~(size_t)0/sizeof(void *)) & -BITS_PER_LONG;
 
-static void *alloc_fdmem(size_t size)
+static int fill_max_fds(struct files_struct *files, unsigned int nr)
 {
-   /*
-* Very large allocations can stress page reclaim, so fall back to
-* vmalloc() if the allocation size will be considered "large" by the 
VM.
-*/
-   if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) {
-   void *data = kmalloc(size, GFP_KERNEL_ACCOUNT |
-__GFP_NOWARN | __GFP_NORETRY);
-   if (data != NULL)
-   return data;
-   }
-   return __vmalloc(size, GFP_KERNEL_ACCOUNT | __GFP_HIGHMEM, PAGE_KERNEL);
-}
+   unsigned int nr_open;
 
-static void __free_fdtable(struct fdtable *fdt)
-{
-   kvfree(fdt->open_fds);
-   kfree(fdt);
-}
-
-static void free_fdtable_rcu(struct rcu_head *rcu)
-{
-   __free_fdtable(container_of(rcu, struct fdtable, rcu));
-}
-
-/*
- * Copy 'count' fd bits from the old table to the new table and clear the extra
- * space if any.  This does not copy the file pointers.  Called with the files
- * spinlock held for write.
- */
-static void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt,
-   unsigned int count)
-{
-   unsigned int cpy, set;
-
-   cpy = count / BITS_PER_BYTE;
-   set = (nfdt->max_fds - count) / BITS_PER_BYTE;
-   memcpy(nfdt->open_fds, ofdt->open_fds, cpy);
-   memset((char *)nfdt->open_fds + cpy, 0, set);
-}
+   if (likely(nr < files->max_fds))
+   return 0;
 
-/*
- * Copy all file descriptors from the old table to the new, expanded table and
- * clear the extra space.  Called with the files spinlock held for write.
- */
-static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
-{
-   BUG_ON(nfdt->max_fds < ofdt->max_fds);
-   copy_fd_bitmaps(nfdt, ofdt, ofdt->max_fds);
-}
+   nr_open = READ_ONCE(sysctl_nr_open);
 
-static struct fdtable * alloc_fdtable(unsigned int nr)
-{
-   struct fdtable *fdt;
-   void *data;
+   if (nr >= nr_open)
+   return -EMFILE;
 
/*
-* Figure out how many fds we actually want to support in this fdtable.
-* Allocation steps are keyed to the size of the fdarray, since it
-* grows far faster than any of the other dynamic data. We try to fit
-* the fdarray into comfortable page-tuned chunks: starting at 1024B
-* and growing in powers of two from there on.
+* This calculation of the new value of max_fds matches the old
+* behaviour of this code which is user-visible through /proc.
+* nr may exceed the sysctl_nr_open value by a small amount.
+* This used to be necessary to keep the bitmaps aligned, and
+* we keep it the same even though the IDR handles the bitmaps now.
 */
+
nr /= (1024 / sizeof(struct file *));
nr = 

[RESEND PATCH 13/13] vfs: Delete struct fdtable

2017-07-11 Thread Sandhya Bankar
Completing the conversion of the file descriptor allocation code to use
the IDR.

This patch includes below changes:

 - Move max_fds from struct fdtable to files_struct.
 - Added fill_max_fds() routine to calculate the new value of max_fds
   to matches the old behaviour of alloc_fdtable() code which is
   user-visible through /proc.
 - Remove struct fdtable
 - Removed resize_in_progress, resize_wait from files_struct
 - Delete open_fds() & count_open_files()
 - Use READ_ONCE() instead of rcu_read_lock/unlock(). The rcu_read_lock()/
   unlock() was used to dereference the files->fdt. Now we don't use RCU to
   protect files->max_fds. So using READ_ONCE() macro to read the value of
   files->max_fds.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/compat.c |   6 +-
 fs/file.c   | 354 +++-
 fs/proc/array.c |   2 +-
 fs/proc/fd.c|   2 +-
 fs/select.c |   6 +-
 include/linux/fdtable.h |  31 +
 6 files changed, 54 insertions(+), 347 deletions(-)

diff --git a/fs/compat.c b/fs/compat.c
index c61b506..7483c9c 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1153,17 +1153,13 @@ int compat_core_sys_select(int n, compat_ulong_t __user 
*inp,
fd_set_bits fds;
void *bits;
int size, max_fds, ret = -EINVAL;
-   struct fdtable *fdt;
long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
 
if (n < 0)
goto out_nofds;
 
/* max_fds can increase, so grab it once to avoid race */
-   rcu_read_lock();
-   fdt = files_fdtable(current->files);
-   max_fds = fdt->max_fds;
-   rcu_read_unlock();
+   max_fds = READ_ONCE(current->files->max_fds);
if (n > max_fds)
n = max_fds;
 
diff --git a/fs/file.c b/fs/file.c
index 23f198b..3e6cf10 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -31,191 +31,36 @@
 unsigned int sysctl_nr_open_max =
__const_min(INT_MAX, ~(size_t)0/sizeof(void *)) & -BITS_PER_LONG;
 
-static void *alloc_fdmem(size_t size)
+static int fill_max_fds(struct files_struct *files, unsigned int nr)
 {
-   /*
-* Very large allocations can stress page reclaim, so fall back to
-* vmalloc() if the allocation size will be considered "large" by the 
VM.
-*/
-   if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) {
-   void *data = kmalloc(size, GFP_KERNEL_ACCOUNT |
-__GFP_NOWARN | __GFP_NORETRY);
-   if (data != NULL)
-   return data;
-   }
-   return __vmalloc(size, GFP_KERNEL_ACCOUNT | __GFP_HIGHMEM, PAGE_KERNEL);
-}
+   unsigned int nr_open;
 
-static void __free_fdtable(struct fdtable *fdt)
-{
-   kvfree(fdt->open_fds);
-   kfree(fdt);
-}
-
-static void free_fdtable_rcu(struct rcu_head *rcu)
-{
-   __free_fdtable(container_of(rcu, struct fdtable, rcu));
-}
-
-/*
- * Copy 'count' fd bits from the old table to the new table and clear the extra
- * space if any.  This does not copy the file pointers.  Called with the files
- * spinlock held for write.
- */
-static void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt,
-   unsigned int count)
-{
-   unsigned int cpy, set;
-
-   cpy = count / BITS_PER_BYTE;
-   set = (nfdt->max_fds - count) / BITS_PER_BYTE;
-   memcpy(nfdt->open_fds, ofdt->open_fds, cpy);
-   memset((char *)nfdt->open_fds + cpy, 0, set);
-}
+   if (likely(nr < files->max_fds))
+   return 0;
 
-/*
- * Copy all file descriptors from the old table to the new, expanded table and
- * clear the extra space.  Called with the files spinlock held for write.
- */
-static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
-{
-   BUG_ON(nfdt->max_fds < ofdt->max_fds);
-   copy_fd_bitmaps(nfdt, ofdt, ofdt->max_fds);
-}
+   nr_open = READ_ONCE(sysctl_nr_open);
 
-static struct fdtable * alloc_fdtable(unsigned int nr)
-{
-   struct fdtable *fdt;
-   void *data;
+   if (nr >= nr_open)
+   return -EMFILE;
 
/*
-* Figure out how many fds we actually want to support in this fdtable.
-* Allocation steps are keyed to the size of the fdarray, since it
-* grows far faster than any of the other dynamic data. We try to fit
-* the fdarray into comfortable page-tuned chunks: starting at 1024B
-* and growing in powers of two from there on.
+* This calculation of the new value of max_fds matches the old
+* behaviour of this code which is user-visible through /proc.
+* nr may exceed the sysctl_nr_open value by a small amount.
+* This used to be necessary to keep the bitmaps aligned, and
+* we keep it the same even though the IDR handles the bitmaps now.
 */
+
nr /= (1024 / sizeof(struct file *));
nr = roundup_pow_of_two(nr + 1);
nr *= (1024 / 

[RESEND PATCH 12/13] vfs: Convert select to use idr_get_tag_batch()

2017-07-11 Thread Sandhya Bankar
Convert select to use idr_get_tag_batch().

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/select.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/fs/select.c b/fs/select.c
index e211227..5d20a14 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -346,32 +346,33 @@ static int poll_select_copy_remaining(struct timespec64 
*end_time,
 
 static int max_select_fd(unsigned long n, fd_set_bits *fds)
 {
-   unsigned long *open_fds;
+   unsigned long bad_fds;
unsigned long set;
int max;
-   struct fdtable *fdt;
+   struct idr *fd_idr = >files->fd_idr;
 
/* handle last in-complete long-word first */
set = ~(~0UL << (n & (BITS_PER_LONG-1)));
n /= BITS_PER_LONG;
-   fdt = files_fdtable(current->files);
-   open_fds = fdt->open_fds + n;
max = 0;
if (set) {
set &= BITS(fds, n);
if (set) {
-   if (!(set & ~*open_fds))
+   bad_fds = idr_get_tag_batch(fd_idr, (n * BITS_PER_LONG),
+   IDR_FREE);
+   if (!(set & bad_fds))
goto get_max;
return -EBADF;
}
}
while (n) {
-   open_fds--;
n--;
set = BITS(fds, n);
if (!set)
continue;
-   if (set & ~*open_fds)
+   bad_fds = idr_get_tag_batch(fd_idr, (n * BITS_PER_LONG),
+   IDR_FREE);
+   if (set & bad_fds)
return -EBADF;
if (max)
continue;
-- 
1.8.3.1



[RESEND PATCH 12/13] vfs: Convert select to use idr_get_tag_batch()

2017-07-11 Thread Sandhya Bankar
Convert select to use idr_get_tag_batch().

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/select.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/fs/select.c b/fs/select.c
index e211227..5d20a14 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -346,32 +346,33 @@ static int poll_select_copy_remaining(struct timespec64 
*end_time,
 
 static int max_select_fd(unsigned long n, fd_set_bits *fds)
 {
-   unsigned long *open_fds;
+   unsigned long bad_fds;
unsigned long set;
int max;
-   struct fdtable *fdt;
+   struct idr *fd_idr = >files->fd_idr;
 
/* handle last in-complete long-word first */
set = ~(~0UL << (n & (BITS_PER_LONG-1)));
n /= BITS_PER_LONG;
-   fdt = files_fdtable(current->files);
-   open_fds = fdt->open_fds + n;
max = 0;
if (set) {
set &= BITS(fds, n);
if (set) {
-   if (!(set & ~*open_fds))
+   bad_fds = idr_get_tag_batch(fd_idr, (n * BITS_PER_LONG),
+   IDR_FREE);
+   if (!(set & bad_fds))
goto get_max;
return -EBADF;
}
}
while (n) {
-   open_fds--;
n--;
set = BITS(fds, n);
if (!set)
continue;
-   if (set & ~*open_fds)
+   bad_fds = idr_get_tag_batch(fd_idr, (n * BITS_PER_LONG),
+   IDR_FREE);
+   if (set & bad_fds)
return -EBADF;
if (max)
continue;
-- 
1.8.3.1



[RESEND PATCH 11/13] vfs: Add init_task.h include

2017-07-11 Thread Matthew Wilcox
Removes a sparse warning about init_files() not being declared.

Signed-off-by: Matthew Wilcox 
---
 fs/file.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/file.c b/fs/file.c
index 56c5731..23f198b 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
1.8.3.1



[RESEND PATCH 11/13] vfs: Add init_task.h include

2017-07-11 Thread Matthew Wilcox
Removes a sparse warning about init_files() not being declared.

Signed-off-by: Matthew Wilcox 
---
 fs/file.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/file.c b/fs/file.c
index 56c5731..23f198b 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
1.8.3.1



Re: [PATCH 2/2] mmc: sdhci-of-at91: set clocks and presets after resume from deepest PM

2017-07-11 Thread Ludovic Desroches
On Tue, Jul 11, 2017 at 02:42:44PM +0200, Ulf Hansson wrote:
> On 16 June 2017 at 09:29, Quentin Schulz
>  wrote:
> > This adds deepest (Backup+Self-Refresh) PM support to the ATMEL SAMA5D2
> > SoC's SDHCI controller.
> >
> > When resuming from deepest state, it is required to restore preset
> > registers as the registers are lost since VDD core has been shut down
> > when entering deepest state on the SAMA5D2. The clocks need to be
> > reconfigured as well.
> 
> Right, so compared to runtime resume there is some additional
> operations that is needed during system resume. Fair enough.
> 
> However by looking at the changes below, you also change the system
> suspend operations, as it now calls sdhci_suspend_host(). Is that
> change needed? Then why?
> 
> >
> > The other registers and init process are taken care of by the SDHCI
> > core.
> >
> > Signed-off-by: Quentin Schulz 
> > ---
> >  drivers/mmc/host/sdhci-of-at91.c | 34 --
> >  1 file changed, 32 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-of-at91.c 
> > b/drivers/mmc/host/sdhci-of-at91.c
> > index fb8c6011f13d..300513fc1068 100644
> > --- a/drivers/mmc/host/sdhci-of-at91.c
> > +++ b/drivers/mmc/host/sdhci-of-at91.c
> > @@ -207,6 +207,37 @@ static int sdhci_at91_set_clks_presets(struct device 
> > *dev)
> >  }
> >
> >  #ifdef CONFIG_PM
> > +static int sdhci_at91_suspend(struct device *dev)
> > +{
> > +   struct sdhci_host *host = dev_get_drvdata(dev);
> > +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > +   struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host);
> > +   int ret;
> > +
> > +   ret = sdhci_suspend_host(host);
> > +
> 
> This is wrong, you can't call sdhci_suspend_host() unless the device
> is runtime resumed...
> 
> > +   if (host->runtime_suspended)
> > +   return ret;
> 
> ... and this is weird...
> 
> > +
> > +   clk_disable_unprepare(priv->gck);
> > +   clk_disable_unprepare(priv->hclock);
> > +   clk_disable_unprepare(priv->mainck);
> > +
> > +   return ret;
> > +}
> > +
> > +static int sdhci_at91_resume(struct device *dev)
> > +{
> > +   struct sdhci_host *host = dev_get_drvdata(dev);
> > +   int ret;
> > +
> > +   ret = sdhci_at91_set_clks_presets(dev);
> > +   if (ret)
> > +   return ret;
> 
> Instead of doing it like this, I suggest you set a new flag to true
> here, let's call it "restore_needed".
> 
> In the ->runtime_resume() callback, you check the restore_needed flag
> and performs the extra operations in that case. When that's done, the
> ->runtime_resume() callback clears the flag, as to avoid the next
> runtime resume from unnecessary doing the extra operations.
> 
> > +
> > +   return sdhci_resume_host(host);
> 
> Remove this and call pm_runtime_force_resume().
> 
> > +}
> > +
> >  static int sdhci_at91_runtime_suspend(struct device *dev)
> >  {
> > struct sdhci_host *host = dev_get_drvdata(dev);
> > @@ -256,8 +287,7 @@ static int sdhci_at91_runtime_resume(struct device *dev)
> >  #endif /* CONFIG_PM */
> >
> >  static const struct dev_pm_ops sdhci_at91_dev_pm_ops = {
> > -   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> 
> Leave the pm_runtime_force_suspend() here, unless you have other
> reasons not being described in the change log, to change the system
> suspend operations.

I think we need to keep it to be able to set the restore_needed flag, isn't it?

Regards

Ludovic

> 
> > -   pm_runtime_force_resume)
> > +   SET_SYSTEM_SLEEP_PM_OPS(sdhci_at91_suspend, sdhci_at91_resume)
> > SET_RUNTIME_PM_OPS(sdhci_at91_runtime_suspend,
> >sdhci_at91_runtime_resume,
> >NULL)
> > --
> > 2.11.0
> >
> 
> Adopting my changes should simplify the code, avoid unnecessary
> resuming the device but instead deferring that until really needed via
> runtime PM.
> 
> Kind regards
> Uffe


Re: [PATCH 2/2] mmc: sdhci-of-at91: set clocks and presets after resume from deepest PM

2017-07-11 Thread Ludovic Desroches
On Tue, Jul 11, 2017 at 02:42:44PM +0200, Ulf Hansson wrote:
> On 16 June 2017 at 09:29, Quentin Schulz
>  wrote:
> > This adds deepest (Backup+Self-Refresh) PM support to the ATMEL SAMA5D2
> > SoC's SDHCI controller.
> >
> > When resuming from deepest state, it is required to restore preset
> > registers as the registers are lost since VDD core has been shut down
> > when entering deepest state on the SAMA5D2. The clocks need to be
> > reconfigured as well.
> 
> Right, so compared to runtime resume there is some additional
> operations that is needed during system resume. Fair enough.
> 
> However by looking at the changes below, you also change the system
> suspend operations, as it now calls sdhci_suspend_host(). Is that
> change needed? Then why?
> 
> >
> > The other registers and init process are taken care of by the SDHCI
> > core.
> >
> > Signed-off-by: Quentin Schulz 
> > ---
> >  drivers/mmc/host/sdhci-of-at91.c | 34 --
> >  1 file changed, 32 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-of-at91.c 
> > b/drivers/mmc/host/sdhci-of-at91.c
> > index fb8c6011f13d..300513fc1068 100644
> > --- a/drivers/mmc/host/sdhci-of-at91.c
> > +++ b/drivers/mmc/host/sdhci-of-at91.c
> > @@ -207,6 +207,37 @@ static int sdhci_at91_set_clks_presets(struct device 
> > *dev)
> >  }
> >
> >  #ifdef CONFIG_PM
> > +static int sdhci_at91_suspend(struct device *dev)
> > +{
> > +   struct sdhci_host *host = dev_get_drvdata(dev);
> > +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > +   struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host);
> > +   int ret;
> > +
> > +   ret = sdhci_suspend_host(host);
> > +
> 
> This is wrong, you can't call sdhci_suspend_host() unless the device
> is runtime resumed...
> 
> > +   if (host->runtime_suspended)
> > +   return ret;
> 
> ... and this is weird...
> 
> > +
> > +   clk_disable_unprepare(priv->gck);
> > +   clk_disable_unprepare(priv->hclock);
> > +   clk_disable_unprepare(priv->mainck);
> > +
> > +   return ret;
> > +}
> > +
> > +static int sdhci_at91_resume(struct device *dev)
> > +{
> > +   struct sdhci_host *host = dev_get_drvdata(dev);
> > +   int ret;
> > +
> > +   ret = sdhci_at91_set_clks_presets(dev);
> > +   if (ret)
> > +   return ret;
> 
> Instead of doing it like this, I suggest you set a new flag to true
> here, let's call it "restore_needed".
> 
> In the ->runtime_resume() callback, you check the restore_needed flag
> and performs the extra operations in that case. When that's done, the
> ->runtime_resume() callback clears the flag, as to avoid the next
> runtime resume from unnecessary doing the extra operations.
> 
> > +
> > +   return sdhci_resume_host(host);
> 
> Remove this and call pm_runtime_force_resume().
> 
> > +}
> > +
> >  static int sdhci_at91_runtime_suspend(struct device *dev)
> >  {
> > struct sdhci_host *host = dev_get_drvdata(dev);
> > @@ -256,8 +287,7 @@ static int sdhci_at91_runtime_resume(struct device *dev)
> >  #endif /* CONFIG_PM */
> >
> >  static const struct dev_pm_ops sdhci_at91_dev_pm_ops = {
> > -   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> 
> Leave the pm_runtime_force_suspend() here, unless you have other
> reasons not being described in the change log, to change the system
> suspend operations.

I think we need to keep it to be able to set the restore_needed flag, isn't it?

Regards

Ludovic

> 
> > -   pm_runtime_force_resume)
> > +   SET_SYSTEM_SLEEP_PM_OPS(sdhci_at91_suspend, sdhci_at91_resume)
> > SET_RUNTIME_PM_OPS(sdhci_at91_runtime_suspend,
> >sdhci_at91_runtime_resume,
> >NULL)
> > --
> > 2.11.0
> >
> 
> Adopting my changes should simplify the code, avoid unnecessary
> resuming the device but instead deferring that until really needed via
> runtime PM.
> 
> Kind regards
> Uffe


Re: [PATCH 1/3] ASoC: codec: cpcap: new codec

2017-07-11 Thread Mark Brown
On Tue, Jul 11, 2017 at 02:13:31PM +0200, Sebastian Reichel wrote:

> How is having a subnode without a compatible property different?

You don't *need* to have the subnode, I was only mentioning that if for
some reason it was super useful for organizing the properties.


signature.asc
Description: PGP signature


Re: [PATCH 1/3] ASoC: codec: cpcap: new codec

2017-07-11 Thread Mark Brown
On Tue, Jul 11, 2017 at 02:13:31PM +0200, Sebastian Reichel wrote:

> How is having a subnode without a compatible property different?

You don't *need* to have the subnode, I was only mentioning that if for
some reason it was super useful for organizing the properties.


signature.asc
Description: PGP signature


[RESEND PATCH 10/13] vfs: Replace close_on_exec bitmap with an IDR tag

2017-07-11 Thread Sandhya Bankar
Replace close_on_exec with idr_(get,set,clear)_tag().
Through this patch, added new IDR tag FD_TAG_CLOEXEC
which is passing to idr_(get,set,clear)_tag() to
achieve close_on_exec functionality.
Also removed get_close_on_exec() and using close_on_exec() instead of that.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/exec.c   |  2 +-
 fs/fcntl.c  |  2 +-
 fs/file.c   | 85 +++--
 fs/proc/fd.c|  4 +--
 include/linux/fdtable.h | 19 +++
 include/linux/file.h|  1 -
 6 files changed, 41 insertions(+), 72 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 65145a3..2070bc6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1728,7 +1728,7 @@ static int do_execveat_common(int fd, struct filename 
*filename,
 * inaccessible after exec. Relies on having exclusive access to
 * current->files (due to unshare_files above).
 */
-   if (close_on_exec(fd, rcu_dereference_raw(current->files->fdt)))
+   if (close_on_exec(fd, current->files))
bprm->interp_flags |= BINPRM_FLAGS_PATH_INACCESSIBLE;
bprm->filename = pathbuf;
}
diff --git a/fs/fcntl.c b/fs/fcntl.c
index be8fbe2..9c2061b 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -255,7 +255,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned 
long arg,
err = f_dupfd(arg, filp, O_CLOEXEC);
break;
case F_GETFD:
-   err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
+   err = close_on_exec(fd, current->files) ? FD_CLOEXEC : 0;
break;
case F_SETFD:
err = 0;
diff --git a/fs/file.c b/fs/file.c
index 8cd77c5..56c5731 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -70,8 +70,6 @@ static void copy_fd_bitmaps(struct fdtable *nfdt, struct 
fdtable *ofdt,
set = (nfdt->max_fds - count) / BITS_PER_BYTE;
memcpy(nfdt->open_fds, ofdt->open_fds, cpy);
memset((char *)nfdt->open_fds + cpy, 0, set);
-   memcpy(nfdt->close_on_exec, ofdt->close_on_exec, cpy);
-   memset((char *)nfdt->close_on_exec + cpy, 0, set);
 }
 
 /*
@@ -115,13 +113,10 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
goto out;
fdt->max_fds = nr;
 
-   data = alloc_fdmem(max_t(size_t,
-2 * nr / BITS_PER_BYTE, L1_CACHE_BYTES));
+   data = alloc_fdmem(max_t(size_t, nr / BITS_PER_BYTE, L1_CACHE_BYTES));
if (!data)
goto out_fdt;
fdt->open_fds = data;
-   data += nr / BITS_PER_BYTE;
-   fdt->close_on_exec = data;
 
return fdt;
 
@@ -227,15 +222,16 @@ static inline bool fd_is_open(unsigned int fd, struct 
files_struct *files)
return !idr_tag_get(>fd_idr, fd, IDR_FREE);
 }
 
-static inline void __set_close_on_exec(unsigned int fd, struct fdtable *fdt)
+static inline void __set_close_on_exec(unsigned int fd,
+   struct files_struct *files)
 {
-   __set_bit(fd, fdt->close_on_exec);
+   idr_tag_set(>fd_idr, fd, FD_TAG_CLOEXEC);
 }
 
-static inline void __clear_close_on_exec(unsigned int fd, struct fdtable *fdt)
+static inline void __clear_close_on_exec(unsigned int fd,
+struct files_struct *files)
 {
-   if (test_bit(fd, fdt->close_on_exec))
-   __clear_bit(fd, fdt->close_on_exec);
+   idr_tag_clear(>fd_idr, fd, FD_TAG_CLOEXEC);
 }
 
 static inline void __set_open_fd(unsigned int fd, struct fdtable *fdt)
@@ -287,7 +283,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
init_waitqueue_head(>resize_wait);
new_fdt = >fdtab;
new_fdt->max_fds = NR_OPEN_DEFAULT;
-   new_fdt->close_on_exec = newf->close_on_exec_init;
new_fdt->open_fds = newf->open_fds_init;
 
 restart:
@@ -347,6 +342,9 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
spin_unlock(>file_lock);
goto out;
}
+
+   if (idr_tag_get(>fd_idr, i, FD_TAG_CLOEXEC))
+   idr_tag_set(>fd_idr, i, FD_TAG_CLOEXEC);
}
 
spin_unlock(>file_lock);
@@ -445,7 +443,6 @@ struct files_struct init_files = {
.fdt= _files.fdtab,
.fdtab  = {
.max_fds= NR_OPEN_DEFAULT,
-   .close_on_exec  = init_files.close_on_exec_init,
.open_fds   = init_files.open_fds_init,
},
.file_lock  = __SPIN_LOCK_UNLOCKED(init_files.file_lock),
@@ -482,9 +479,9 @@ int __alloc_fd(struct files_struct *files,
fdt = files_fdtable(files);
__set_open_fd(fd, fdt);
if (flags & O_CLOEXEC)
-   __set_close_on_exec(fd, fdt);
+   __set_close_on_exec(fd, 

[RESEND PATCH 10/13] vfs: Replace close_on_exec bitmap with an IDR tag

2017-07-11 Thread Sandhya Bankar
Replace close_on_exec with idr_(get,set,clear)_tag().
Through this patch, added new IDR tag FD_TAG_CLOEXEC
which is passing to idr_(get,set,clear)_tag() to
achieve close_on_exec functionality.
Also removed get_close_on_exec() and using close_on_exec() instead of that.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/exec.c   |  2 +-
 fs/fcntl.c  |  2 +-
 fs/file.c   | 85 +++--
 fs/proc/fd.c|  4 +--
 include/linux/fdtable.h | 19 +++
 include/linux/file.h|  1 -
 6 files changed, 41 insertions(+), 72 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 65145a3..2070bc6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1728,7 +1728,7 @@ static int do_execveat_common(int fd, struct filename 
*filename,
 * inaccessible after exec. Relies on having exclusive access to
 * current->files (due to unshare_files above).
 */
-   if (close_on_exec(fd, rcu_dereference_raw(current->files->fdt)))
+   if (close_on_exec(fd, current->files))
bprm->interp_flags |= BINPRM_FLAGS_PATH_INACCESSIBLE;
bprm->filename = pathbuf;
}
diff --git a/fs/fcntl.c b/fs/fcntl.c
index be8fbe2..9c2061b 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -255,7 +255,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned 
long arg,
err = f_dupfd(arg, filp, O_CLOEXEC);
break;
case F_GETFD:
-   err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
+   err = close_on_exec(fd, current->files) ? FD_CLOEXEC : 0;
break;
case F_SETFD:
err = 0;
diff --git a/fs/file.c b/fs/file.c
index 8cd77c5..56c5731 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -70,8 +70,6 @@ static void copy_fd_bitmaps(struct fdtable *nfdt, struct 
fdtable *ofdt,
set = (nfdt->max_fds - count) / BITS_PER_BYTE;
memcpy(nfdt->open_fds, ofdt->open_fds, cpy);
memset((char *)nfdt->open_fds + cpy, 0, set);
-   memcpy(nfdt->close_on_exec, ofdt->close_on_exec, cpy);
-   memset((char *)nfdt->close_on_exec + cpy, 0, set);
 }
 
 /*
@@ -115,13 +113,10 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
goto out;
fdt->max_fds = nr;
 
-   data = alloc_fdmem(max_t(size_t,
-2 * nr / BITS_PER_BYTE, L1_CACHE_BYTES));
+   data = alloc_fdmem(max_t(size_t, nr / BITS_PER_BYTE, L1_CACHE_BYTES));
if (!data)
goto out_fdt;
fdt->open_fds = data;
-   data += nr / BITS_PER_BYTE;
-   fdt->close_on_exec = data;
 
return fdt;
 
@@ -227,15 +222,16 @@ static inline bool fd_is_open(unsigned int fd, struct 
files_struct *files)
return !idr_tag_get(>fd_idr, fd, IDR_FREE);
 }
 
-static inline void __set_close_on_exec(unsigned int fd, struct fdtable *fdt)
+static inline void __set_close_on_exec(unsigned int fd,
+   struct files_struct *files)
 {
-   __set_bit(fd, fdt->close_on_exec);
+   idr_tag_set(>fd_idr, fd, FD_TAG_CLOEXEC);
 }
 
-static inline void __clear_close_on_exec(unsigned int fd, struct fdtable *fdt)
+static inline void __clear_close_on_exec(unsigned int fd,
+struct files_struct *files)
 {
-   if (test_bit(fd, fdt->close_on_exec))
-   __clear_bit(fd, fdt->close_on_exec);
+   idr_tag_clear(>fd_idr, fd, FD_TAG_CLOEXEC);
 }
 
 static inline void __set_open_fd(unsigned int fd, struct fdtable *fdt)
@@ -287,7 +283,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
init_waitqueue_head(>resize_wait);
new_fdt = >fdtab;
new_fdt->max_fds = NR_OPEN_DEFAULT;
-   new_fdt->close_on_exec = newf->close_on_exec_init;
new_fdt->open_fds = newf->open_fds_init;
 
 restart:
@@ -347,6 +342,9 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
spin_unlock(>file_lock);
goto out;
}
+
+   if (idr_tag_get(>fd_idr, i, FD_TAG_CLOEXEC))
+   idr_tag_set(>fd_idr, i, FD_TAG_CLOEXEC);
}
 
spin_unlock(>file_lock);
@@ -445,7 +443,6 @@ struct files_struct init_files = {
.fdt= _files.fdtab,
.fdtab  = {
.max_fds= NR_OPEN_DEFAULT,
-   .close_on_exec  = init_files.close_on_exec_init,
.open_fds   = init_files.open_fds_init,
},
.file_lock  = __SPIN_LOCK_UNLOCKED(init_files.file_lock),
@@ -482,9 +479,9 @@ int __alloc_fd(struct files_struct *files,
fdt = files_fdtable(files);
__set_open_fd(fd, fdt);
if (flags & O_CLOEXEC)
-   __set_close_on_exec(fd, fdt);
+   __set_close_on_exec(fd, files);
else
-   

Re: [RFC PATCH 3/4] pmbus: Allow dynamic fan coefficient values

2017-07-11 Thread Guenter Roeck

On 07/10/2017 06:56 AM, Andrew Jeffery wrote:

Some PMBus chips, such as the MAX31785, use different coefficients for
FAN_COMMAND_[1-4] depending on whether the fan is in PWM (percent duty)
or RPM mode. Add a callback to allow the driver to provide the
applicable coefficients to avoid imposing on devices that don't have
this requirement.



Why not just introduce another class, such as PSC_PWM ?


Signed-off-by: Andrew Jeffery 
---
  drivers/hwmon/pmbus/pmbus.h  |  18 +--
  drivers/hwmon/pmbus/pmbus_core.c | 112 ---
  2 files changed, 108 insertions(+), 22 deletions(-)

diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index 927eabc1b273..338ecc8b25a4 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -345,6 +345,12 @@ enum pmbus_sensor_classes {
  enum pmbus_data_format { linear = 0, direct, vid };
  enum vrm_version { vr11 = 0, vr12 };
  
+struct pmbus_coeffs {

+   int m; /* mantissa for direct data format */
+   int b; /* offset */
+   int R; /* exponent */
+};
+
  struct pmbus_driver_info {
int pages;  /* Total number of pages */
enum pmbus_data_format format[PSC_NUM_CLASSES];
@@ -353,9 +359,7 @@ struct pmbus_driver_info {
 * Support one set of coefficients for each sensor type
 * Used for chips providing data in direct mode.
 */
-   int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */
-   int b[PSC_NUM_CLASSES]; /* offset */
-   int R[PSC_NUM_CLASSES]; /* exponent */
+   struct pmbus_coeffs coeffs[PSC_NUM_CLASSES];
  
  	u32 func[PMBUS_PAGES];	/* Functionality, per page */

/*
@@ -382,6 +386,14 @@ struct pmbus_driver_info {
int (*identify)(struct i2c_client *client,
struct pmbus_driver_info *info);
  
+	/*

+* If a fan's coefficents change over time (e.g. between RPM and PWM
+* mode), then the driver can provide a function for retrieving the
+* currently applicable coefficients.
+*/
+   const struct pmbus_coeffs *(*get_fan_coeffs)(
+   const struct pmbus_driver_info *info, int index,
+   enum pmbus_fan_mode mode, int command);
/* Allow the driver to interpret the fan command value */
int (*get_pwm_mode)(int id, u8 fan_config, u16 fan_command);
int (*set_pwm_mode)(int id, long mode, u8 *fan_config,
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 3b0a55bbbd2c..4ff6a1fd5cce 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -58,10 +58,11 @@
  struct pmbus_sensor {
struct pmbus_sensor *next;
char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */
-   struct device_attribute attribute;
+   struct sensor_device_attribute attribute;
u8 page;/* page number */
u16 reg;/* register */
enum pmbus_sensor_classes class;/* sensor class */
+   const struct pmbus_coeffs *coeffs;
bool update;/* runtime sensor update needed */
int data;   /* Sensor data.
   Negative if there was a read error */
@@ -89,6 +90,7 @@ struct pmbus_fan_ctrl {
u8 id;
u8 config;
u16 command;
+   const struct pmbus_coeffs *coeffs;
  };
  #define to_pmbus_fan_ctrl_attr(_attr) \
container_of(_attr, struct pmbus_fan_ctrl_attr, attribute)
@@ -511,9 +513,15 @@ static long pmbus_reg2data_direct(struct pmbus_data *data,
long val = (s16) sensor->data;
long m, b, R;
  
-	m = data->info->m[sensor->class];

-   b = data->info->b[sensor->class];
-   R = data->info->R[sensor->class];
+   if (sensor->coeffs) {
+   m = sensor->coeffs->m;
+   b = sensor->coeffs->b;
+   R = sensor->coeffs->R;
+   } else {
+   m = data->info->coeffs[sensor->class].m;
+   b = data->info->coeffs[sensor->class].b;
+   R = data->info->coeffs[sensor->class].R;
+   }
  
  	if (m == 0)

return 0;
@@ -663,9 +671,15 @@ static u16 pmbus_data2reg_direct(struct pmbus_data *data,
  {
long m, b, R;
  
-	m = data->info->m[sensor->class];

-   b = data->info->b[sensor->class];
-   R = data->info->R[sensor->class];
+   if (sensor->coeffs) {
+   m = sensor->coeffs->m;
+   b = sensor->coeffs->b;
+   R = sensor->coeffs->R;
+   } else {
+   m = data->info->coeffs[sensor->class].m;
+   b = data->info->coeffs[sensor->class].b;
+   R = data->info->coeffs[sensor->class].R;
+   }
  
  	/* Power is in uW. Adjust R and b. */

if (sensor->class == PSC_POWER) {
@@ -796,7 +810,9 @@ static ssize_t pmbus_show_sensor(struct device *dev,
 struct 

Re: [RFC PATCH 3/4] pmbus: Allow dynamic fan coefficient values

2017-07-11 Thread Guenter Roeck

On 07/10/2017 06:56 AM, Andrew Jeffery wrote:

Some PMBus chips, such as the MAX31785, use different coefficients for
FAN_COMMAND_[1-4] depending on whether the fan is in PWM (percent duty)
or RPM mode. Add a callback to allow the driver to provide the
applicable coefficients to avoid imposing on devices that don't have
this requirement.



Why not just introduce another class, such as PSC_PWM ?


Signed-off-by: Andrew Jeffery 
---
  drivers/hwmon/pmbus/pmbus.h  |  18 +--
  drivers/hwmon/pmbus/pmbus_core.c | 112 ---
  2 files changed, 108 insertions(+), 22 deletions(-)

diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index 927eabc1b273..338ecc8b25a4 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -345,6 +345,12 @@ enum pmbus_sensor_classes {
  enum pmbus_data_format { linear = 0, direct, vid };
  enum vrm_version { vr11 = 0, vr12 };
  
+struct pmbus_coeffs {

+   int m; /* mantissa for direct data format */
+   int b; /* offset */
+   int R; /* exponent */
+};
+
  struct pmbus_driver_info {
int pages;  /* Total number of pages */
enum pmbus_data_format format[PSC_NUM_CLASSES];
@@ -353,9 +359,7 @@ struct pmbus_driver_info {
 * Support one set of coefficients for each sensor type
 * Used for chips providing data in direct mode.
 */
-   int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */
-   int b[PSC_NUM_CLASSES]; /* offset */
-   int R[PSC_NUM_CLASSES]; /* exponent */
+   struct pmbus_coeffs coeffs[PSC_NUM_CLASSES];
  
  	u32 func[PMBUS_PAGES];	/* Functionality, per page */

/*
@@ -382,6 +386,14 @@ struct pmbus_driver_info {
int (*identify)(struct i2c_client *client,
struct pmbus_driver_info *info);
  
+	/*

+* If a fan's coefficents change over time (e.g. between RPM and PWM
+* mode), then the driver can provide a function for retrieving the
+* currently applicable coefficients.
+*/
+   const struct pmbus_coeffs *(*get_fan_coeffs)(
+   const struct pmbus_driver_info *info, int index,
+   enum pmbus_fan_mode mode, int command);
/* Allow the driver to interpret the fan command value */
int (*get_pwm_mode)(int id, u8 fan_config, u16 fan_command);
int (*set_pwm_mode)(int id, long mode, u8 *fan_config,
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 3b0a55bbbd2c..4ff6a1fd5cce 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -58,10 +58,11 @@
  struct pmbus_sensor {
struct pmbus_sensor *next;
char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */
-   struct device_attribute attribute;
+   struct sensor_device_attribute attribute;
u8 page;/* page number */
u16 reg;/* register */
enum pmbus_sensor_classes class;/* sensor class */
+   const struct pmbus_coeffs *coeffs;
bool update;/* runtime sensor update needed */
int data;   /* Sensor data.
   Negative if there was a read error */
@@ -89,6 +90,7 @@ struct pmbus_fan_ctrl {
u8 id;
u8 config;
u16 command;
+   const struct pmbus_coeffs *coeffs;
  };
  #define to_pmbus_fan_ctrl_attr(_attr) \
container_of(_attr, struct pmbus_fan_ctrl_attr, attribute)
@@ -511,9 +513,15 @@ static long pmbus_reg2data_direct(struct pmbus_data *data,
long val = (s16) sensor->data;
long m, b, R;
  
-	m = data->info->m[sensor->class];

-   b = data->info->b[sensor->class];
-   R = data->info->R[sensor->class];
+   if (sensor->coeffs) {
+   m = sensor->coeffs->m;
+   b = sensor->coeffs->b;
+   R = sensor->coeffs->R;
+   } else {
+   m = data->info->coeffs[sensor->class].m;
+   b = data->info->coeffs[sensor->class].b;
+   R = data->info->coeffs[sensor->class].R;
+   }
  
  	if (m == 0)

return 0;
@@ -663,9 +671,15 @@ static u16 pmbus_data2reg_direct(struct pmbus_data *data,
  {
long m, b, R;
  
-	m = data->info->m[sensor->class];

-   b = data->info->b[sensor->class];
-   R = data->info->R[sensor->class];
+   if (sensor->coeffs) {
+   m = sensor->coeffs->m;
+   b = sensor->coeffs->b;
+   R = sensor->coeffs->R;
+   } else {
+   m = data->info->coeffs[sensor->class].m;
+   b = data->info->coeffs[sensor->class].b;
+   R = data->info->coeffs[sensor->class].R;
+   }
  
  	/* Power is in uW. Adjust R and b. */

if (sensor->class == PSC_POWER) {
@@ -796,7 +810,9 @@ static ssize_t pmbus_show_sensor(struct device *dev,
 struct device_attribute 

Re: A question about acpi_early_init(), and want to invoke acpi_early_init() earlier

2017-07-11 Thread Dou Liyang



At 07/11/2017 09:26 PM, Dou Liyang wrote:

Hi, Rafael

Recently, I worked for unify the interrupt delivery mode and do its
setup earlier[1]. And I met a bug about ACPI[2].

When I investigated it, I got your commit c4e1acbb35e4 (ACPI / init:
Run acpi_early_init() before timekeeping_init()).  And I reproduced the


Oops, Make a mistake,

your commit c4e1acbb35e4 (ACPI / init: Invoke early ACPI initialization 
later)


Thanks,

dou

problem you said.

Question:


In the changelog of commit:


Commit 73f7d1ca3263 (ACPI / init: Run acpi_early_init() before
timekeeping_init()) optimistically moved the early ACPI initialization
before timekeeping_init(), but that didn't work, because it broke fast
TSC calibration for Julian Wollrath on Thinkpad x121e (and most likely


Here, does the fast TSC calibration means *quick_pit_calibrate()* ?


for others too).  The reason is that acpi_early_init() enables the SCI
and that interferes with the fast TSC calibration mechanism.


I reproduced it by the following command line:
...noapic acpi_sci=level...

the original dmesg is:

[0.00] tsc: Fast TSC calibration using PIT

the broken dmesg is:

[0.001000] tsc: PIT calibration matches HPET. 1 loops

Is it right? If it is wrong, please give the right process for
reproducing.



Thus follow the original idea to execute acpi_early_init() before
efi_enter_virtual_mode() to help the EFI people for now and we can
revisit the other problem that commit 73f7d1ca3263 attempted to
address in the future (if really necessary).


If the result which I reproduced was right, I think we can do what
the commit 73f7d1ca3263 attempted to do now. And it also can fix the
bug[2].

Because my patchset[1] will setup the interrupt delivery mode earlier
than TSC initialization. So, in Fast TSC calibration, kernel is in its
final interrupt mode, not just PIC mode. The change of trigger type
will never break the Fast TSC calibration(I have tested in my box).


[1] https://lkml.org/lkml/2017/6/30/17
[2] https://lists.gt.net/xen/devel/483350


Thanks,

dou.






Re: A question about acpi_early_init(), and want to invoke acpi_early_init() earlier

2017-07-11 Thread Dou Liyang



At 07/11/2017 09:26 PM, Dou Liyang wrote:

Hi, Rafael

Recently, I worked for unify the interrupt delivery mode and do its
setup earlier[1]. And I met a bug about ACPI[2].

When I investigated it, I got your commit c4e1acbb35e4 (ACPI / init:
Run acpi_early_init() before timekeeping_init()).  And I reproduced the


Oops, Make a mistake,

your commit c4e1acbb35e4 (ACPI / init: Invoke early ACPI initialization 
later)


Thanks,

dou

problem you said.

Question:


In the changelog of commit:


Commit 73f7d1ca3263 (ACPI / init: Run acpi_early_init() before
timekeeping_init()) optimistically moved the early ACPI initialization
before timekeeping_init(), but that didn't work, because it broke fast
TSC calibration for Julian Wollrath on Thinkpad x121e (and most likely


Here, does the fast TSC calibration means *quick_pit_calibrate()* ?


for others too).  The reason is that acpi_early_init() enables the SCI
and that interferes with the fast TSC calibration mechanism.


I reproduced it by the following command line:
...noapic acpi_sci=level...

the original dmesg is:

[0.00] tsc: Fast TSC calibration using PIT

the broken dmesg is:

[0.001000] tsc: PIT calibration matches HPET. 1 loops

Is it right? If it is wrong, please give the right process for
reproducing.



Thus follow the original idea to execute acpi_early_init() before
efi_enter_virtual_mode() to help the EFI people for now and we can
revisit the other problem that commit 73f7d1ca3263 attempted to
address in the future (if really necessary).


If the result which I reproduced was right, I think we can do what
the commit 73f7d1ca3263 attempted to do now. And it also can fix the
bug[2].

Because my patchset[1] will setup the interrupt delivery mode earlier
than TSC initialization. So, in Fast TSC calibration, kernel is in its
final interrupt mode, not just PIC mode. The change of trigger type
will never break the Fast TSC calibration(I have tested in my box).


[1] https://lkml.org/lkml/2017/6/30/17
[2] https://lists.gt.net/xen/devel/483350


Thanks,

dou.






[RESEND PATCH 09/13] vfs: Rewrite close_files()

2017-07-11 Thread Sandhya Bankar
Use the IDR iteration functionality instead of the open_fds bitmap to
call filp_close() for each open file.  Also make close_files() return
void, because it no longer uses the fdtable.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/file.c | 37 +++--
 1 file changed, 11 insertions(+), 26 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index 8d67968..8cd77c5 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -373,37 +373,21 @@ struct files_struct *dup_fd(struct files_struct *oldf, 
int *errorp)
return NULL;
 }
 
-static struct fdtable *close_files(struct files_struct * files)
+static void close_files(struct files_struct * files)
 {
/*
-* It is safe to dereference the fd table without RCU or
-* ->file_lock because this is the last reference to the
-* files structure.
+* No need for RCU or ->file_lock protection because
+* this is the last reference to the files structure.
 */
-   struct fdtable *fdt = rcu_dereference_raw(files->fdt);
-   unsigned int i, j = 0;
+   struct file *file;
+   int fd;
 
-   for (;;) {
-   unsigned long set;
-   i = j * BITS_PER_LONG;
-   if (i >= fdt->max_fds)
-   break;
-   set = fdt->open_fds[j++];
-   while (set) {
-   if (set & 1) {
-   struct file *file;
-   file = idr_remove(>fd_idr, i);
-   if (file) {
-   filp_close(file, files);
-   cond_resched_rcu_qs();
-   }
-   }
-   i++;
-   set >>= 1;
-   }
+   idr_for_each_entry(>fd_idr, file, fd) {
+   filp_close(file, files);
+   cond_resched_rcu_qs();
}
 
-   return fdt;
+   idr_destroy(>fd_idr);
 }
 
 struct files_struct *get_files_struct(struct task_struct *task)
@@ -422,7 +406,8 @@ struct files_struct *get_files_struct(struct task_struct 
*task)
 void put_files_struct(struct files_struct *files)
 {
if (atomic_dec_and_test(>count)) {
-   struct fdtable *fdt = close_files(files);
+   struct fdtable *fdt = rcu_dereference_raw(files->fdt);
+   close_files(files);
 
/* free the arrays if they are not embedded */
if (fdt != >fdtab)
-- 
1.8.3.1



[RESEND PATCH 09/13] vfs: Rewrite close_files()

2017-07-11 Thread Sandhya Bankar
Use the IDR iteration functionality instead of the open_fds bitmap to
call filp_close() for each open file.  Also make close_files() return
void, because it no longer uses the fdtable.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/file.c | 37 +++--
 1 file changed, 11 insertions(+), 26 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index 8d67968..8cd77c5 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -373,37 +373,21 @@ struct files_struct *dup_fd(struct files_struct *oldf, 
int *errorp)
return NULL;
 }
 
-static struct fdtable *close_files(struct files_struct * files)
+static void close_files(struct files_struct * files)
 {
/*
-* It is safe to dereference the fd table without RCU or
-* ->file_lock because this is the last reference to the
-* files structure.
+* No need for RCU or ->file_lock protection because
+* this is the last reference to the files structure.
 */
-   struct fdtable *fdt = rcu_dereference_raw(files->fdt);
-   unsigned int i, j = 0;
+   struct file *file;
+   int fd;
 
-   for (;;) {
-   unsigned long set;
-   i = j * BITS_PER_LONG;
-   if (i >= fdt->max_fds)
-   break;
-   set = fdt->open_fds[j++];
-   while (set) {
-   if (set & 1) {
-   struct file *file;
-   file = idr_remove(>fd_idr, i);
-   if (file) {
-   filp_close(file, files);
-   cond_resched_rcu_qs();
-   }
-   }
-   i++;
-   set >>= 1;
-   }
+   idr_for_each_entry(>fd_idr, file, fd) {
+   filp_close(file, files);
+   cond_resched_rcu_qs();
}
 
-   return fdt;
+   idr_destroy(>fd_idr);
 }
 
 struct files_struct *get_files_struct(struct task_struct *task)
@@ -422,7 +406,8 @@ struct files_struct *get_files_struct(struct task_struct 
*task)
 void put_files_struct(struct files_struct *files)
 {
if (atomic_dec_and_test(>count)) {
-   struct fdtable *fdt = close_files(files);
+   struct fdtable *fdt = rcu_dereference_raw(files->fdt);
+   close_files(files);
 
/* free the arrays if they are not embedded */
if (fdt != >fdtab)
-- 
1.8.3.1



[RESEND PATCH 08/13] vfs: Use idr_tag_get() in fd_is_open().

2017-07-11 Thread Sandhya Bankar
Use idr_tag_get() in fd_is_open() to know whether a given fd is
allocated.  Also move fd_is_open() to file.c and make it static
as it is only called from one place.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/file.c   | 7 ++-
 include/linux/fdtable.h | 5 -
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index e8c6ada..8d67968 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -222,6 +222,11 @@ static int expand_files(struct files_struct *files, 
unsigned int nr)
return expanded;
 }
 
+static inline bool fd_is_open(unsigned int fd, struct files_struct *files)
+{
+   return !idr_tag_get(>fd_idr, fd, IDR_FREE);
+}
+
 static inline void __set_close_on_exec(unsigned int fd, struct fdtable *fdt)
 {
__set_bit(fd, fdt->close_on_exec);
@@ -778,7 +783,7 @@ static int do_dup2(struct files_struct *files,
 */
fdt = files_fdtable(files);
tofree = idr_find(>fd_idr, fd);
-   if (!tofree && fd_is_open(fd, fdt))
+   if (!tofree && fd_is_open(fd, files))
goto Ebusy;
get_file(file);
if (tofree) {
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 6bece35..67259f4 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -34,11 +34,6 @@ static inline bool close_on_exec(unsigned int fd, const 
struct fdtable *fdt)
return test_bit(fd, fdt->close_on_exec);
 }
 
-static inline bool fd_is_open(unsigned int fd, const struct fdtable *fdt)
-{
-   return test_bit(fd, fdt->open_fds);
-}
-
 /*
  * Open file table structure
  */
-- 
1.8.3.1



[RESEND PATCH 08/13] vfs: Use idr_tag_get() in fd_is_open().

2017-07-11 Thread Sandhya Bankar
Use idr_tag_get() in fd_is_open() to know whether a given fd is
allocated.  Also move fd_is_open() to file.c and make it static
as it is only called from one place.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/file.c   | 7 ++-
 include/linux/fdtable.h | 5 -
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index e8c6ada..8d67968 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -222,6 +222,11 @@ static int expand_files(struct files_struct *files, 
unsigned int nr)
return expanded;
 }
 
+static inline bool fd_is_open(unsigned int fd, struct files_struct *files)
+{
+   return !idr_tag_get(>fd_idr, fd, IDR_FREE);
+}
+
 static inline void __set_close_on_exec(unsigned int fd, struct fdtable *fdt)
 {
__set_bit(fd, fdt->close_on_exec);
@@ -778,7 +783,7 @@ static int do_dup2(struct files_struct *files,
 */
fdt = files_fdtable(files);
tofree = idr_find(>fd_idr, fd);
-   if (!tofree && fd_is_open(fd, fdt))
+   if (!tofree && fd_is_open(fd, files))
goto Ebusy;
get_file(file);
if (tofree) {
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 6bece35..67259f4 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -34,11 +34,6 @@ static inline bool close_on_exec(unsigned int fd, const 
struct fdtable *fdt)
return test_bit(fd, fdt->close_on_exec);
 }
 
-static inline bool fd_is_open(unsigned int fd, const struct fdtable *fdt)
-{
-   return test_bit(fd, fdt->open_fds);
-}
-
 /*
  * Open file table structure
  */
-- 
1.8.3.1



Re: [GIT pull] irq updates for 4.13

2017-07-11 Thread Thomas Gleixner
On Tue, 11 Jul 2017, Sebastian Reichel wrote:
> On Tue, Jul 11, 2017 at 12:52:17PM +0200, Thomas Gleixner wrote:
> > On Tue, 11 Jul 2017, Thomas Gleixner wrote:
> > > On Tue, 11 Jul 2017, Sebastian Reichel wrote:
> > > So this crashes in do_raw_spin_unlock_irqrestore() !?! I just have to
> > > wonder how the raw_spin_lock() succeeded. That does not make any sense.
> > 
> > can you please apply the patch below on top of 4.12? It's a backport
> > isolating the resource request changes.
> 
> Full bootlog for v4.12 + your patch is below. I used the same
> .config with oldconfig.
> [1.329315] cpcap-core spi1.0: CPCAP vendor: ST rev: 2.10 (1a)
> [1.336914] Unhandled fault: imprecise external abort (0x1406) at 
> 0x
> [1.343994] pgd = c0004000
> [1.346710] [] *pgd=
> [1.350341] Internal error: : 1406 [#1] SMP ARM
> [1.354888] Modules linked in:
> [1.357971] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
> 4.12.0-1-g2a481f732c4b #1539
> [1.365936] Hardware name: Generic OMAP4 (Flattened Device Tree)
> [1.371978] task: ee8aadc0 task.stack: ee8ac000
> [1.376556] PC is at lock_release+0x25c/0x360
> [1.380950] LR is at lock_release+0x25c/0x360

Slightly different function, but in the same way non sensical.

I used your config with the extra bits for beaglebone XM enabled and it
just works. The irq_request_resources() callback is invoked and ends up in
omap_gpio_get_direction() without any complaints.

I'm running out of ideas right now.

Thanks,

tglx


Re: [GIT pull] irq updates for 4.13

2017-07-11 Thread Thomas Gleixner
On Tue, 11 Jul 2017, Sebastian Reichel wrote:
> On Tue, Jul 11, 2017 at 12:52:17PM +0200, Thomas Gleixner wrote:
> > On Tue, 11 Jul 2017, Thomas Gleixner wrote:
> > > On Tue, 11 Jul 2017, Sebastian Reichel wrote:
> > > So this crashes in do_raw_spin_unlock_irqrestore() !?! I just have to
> > > wonder how the raw_spin_lock() succeeded. That does not make any sense.
> > 
> > can you please apply the patch below on top of 4.12? It's a backport
> > isolating the resource request changes.
> 
> Full bootlog for v4.12 + your patch is below. I used the same
> .config with oldconfig.
> [1.329315] cpcap-core spi1.0: CPCAP vendor: ST rev: 2.10 (1a)
> [1.336914] Unhandled fault: imprecise external abort (0x1406) at 
> 0x
> [1.343994] pgd = c0004000
> [1.346710] [] *pgd=
> [1.350341] Internal error: : 1406 [#1] SMP ARM
> [1.354888] Modules linked in:
> [1.357971] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
> 4.12.0-1-g2a481f732c4b #1539
> [1.365936] Hardware name: Generic OMAP4 (Flattened Device Tree)
> [1.371978] task: ee8aadc0 task.stack: ee8ac000
> [1.376556] PC is at lock_release+0x25c/0x360
> [1.380950] LR is at lock_release+0x25c/0x360

Slightly different function, but in the same way non sensical.

I used your config with the extra bits for beaglebone XM enabled and it
just works. The irq_request_resources() callback is invoked and ends up in
omap_gpio_get_direction() without any complaints.

I'm running out of ideas right now.

Thanks,

tglx


A question about acpi_early_init(), and want to invoke acpi_early_init() earlier

2017-07-11 Thread Dou Liyang

Hi, Rafael

Recently, I worked for unify the interrupt delivery mode and do its 
setup earlier[1]. And I met a bug about ACPI[2].


When I investigated it, I got your commit c4e1acbb35e4 (ACPI / init:
Run acpi_early_init() before timekeeping_init()).  And I reproduced the
problem you said.

Question:


In the changelog of commit:

> Commit 73f7d1ca3263 (ACPI / init: Run acpi_early_init() before
> timekeeping_init()) optimistically moved the early ACPI initialization
> before timekeeping_init(), but that didn't work, because it broke fast
> TSC calibration for Julian Wollrath on Thinkpad x121e (and most likely

Here, does the fast TSC calibration means *quick_pit_calibrate()* ?

> for others too).  The reason is that acpi_early_init() enables the SCI
> and that interferes with the fast TSC calibration mechanism.

I reproduced it by the following command line:
...noapic acpi_sci=level...

the original dmesg is:

[0.00] tsc: Fast TSC calibration using PIT

the broken dmesg is:

[0.001000] tsc: PIT calibration matches HPET. 1 loops

Is it right? If it is wrong, please give the right process for
reproducing.

>
> Thus follow the original idea to execute acpi_early_init() before
> efi_enter_virtual_mode() to help the EFI people for now and we can
> revisit the other problem that commit 73f7d1ca3263 attempted to
> address in the future (if really necessary).

If the result which I reproduced was right, I think we can do what
the commit 73f7d1ca3263 attempted to do now. And it also can fix the
bug[2].

Because my patchset[1] will setup the interrupt delivery mode earlier
than TSC initialization. So, in Fast TSC calibration, kernel is in its
final interrupt mode, not just PIC mode. The change of trigger type
will never break the Fast TSC calibration(I have tested in my box).


[1] https://lkml.org/lkml/2017/6/30/17
[2] https://lists.gt.net/xen/devel/483350


Thanks,

dou.





A question about acpi_early_init(), and want to invoke acpi_early_init() earlier

2017-07-11 Thread Dou Liyang

Hi, Rafael

Recently, I worked for unify the interrupt delivery mode and do its 
setup earlier[1]. And I met a bug about ACPI[2].


When I investigated it, I got your commit c4e1acbb35e4 (ACPI / init:
Run acpi_early_init() before timekeeping_init()).  And I reproduced the
problem you said.

Question:


In the changelog of commit:

> Commit 73f7d1ca3263 (ACPI / init: Run acpi_early_init() before
> timekeeping_init()) optimistically moved the early ACPI initialization
> before timekeeping_init(), but that didn't work, because it broke fast
> TSC calibration for Julian Wollrath on Thinkpad x121e (and most likely

Here, does the fast TSC calibration means *quick_pit_calibrate()* ?

> for others too).  The reason is that acpi_early_init() enables the SCI
> and that interferes with the fast TSC calibration mechanism.

I reproduced it by the following command line:
...noapic acpi_sci=level...

the original dmesg is:

[0.00] tsc: Fast TSC calibration using PIT

the broken dmesg is:

[0.001000] tsc: PIT calibration matches HPET. 1 loops

Is it right? If it is wrong, please give the right process for
reproducing.

>
> Thus follow the original idea to execute acpi_early_init() before
> efi_enter_virtual_mode() to help the EFI people for now and we can
> revisit the other problem that commit 73f7d1ca3263 attempted to
> address in the future (if really necessary).

If the result which I reproduced was right, I think we can do what
the commit 73f7d1ca3263 attempted to do now. And it also can fix the
bug[2].

Because my patchset[1] will setup the interrupt delivery mode earlier
than TSC initialization. So, in Fast TSC calibration, kernel is in its
final interrupt mode, not just PIC mode. The change of trigger type
will never break the Fast TSC calibration(I have tested in my box).


[1] https://lkml.org/lkml/2017/6/30/17
[2] https://lists.gt.net/xen/devel/483350


Thanks,

dou.





[RESEND PATCH 07/13] vfs: Remove full_fds_bits from fd allocation code path.

2017-07-11 Thread Sandhya Bankar
The IDR has removed the need to have full_fds_bits hence removing it.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/file.c   | 18 +-
 include/linux/fdtable.h |  2 --
 2 files changed, 1 insertion(+), 19 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index da3a35b..e8c6ada 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -56,9 +56,6 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
__free_fdtable(container_of(rcu, struct fdtable, rcu));
 }
 
-#define BITBIT_NR(nr)  BITS_TO_LONGS(BITS_TO_LONGS(nr))
-#define BITBIT_SIZE(nr)(BITBIT_NR(nr) * sizeof(long))
-
 /*
  * Copy 'count' fd bits from the old table to the new table and clear the extra
  * space if any.  This does not copy the file pointers.  Called with the files
@@ -75,11 +72,6 @@ static void copy_fd_bitmaps(struct fdtable *nfdt, struct 
fdtable *ofdt,
memset((char *)nfdt->open_fds + cpy, 0, set);
memcpy(nfdt->close_on_exec, ofdt->close_on_exec, cpy);
memset((char *)nfdt->close_on_exec + cpy, 0, set);
-
-   cpy = BITBIT_SIZE(count);
-   set = BITBIT_SIZE(nfdt->max_fds) - cpy;
-   memcpy(nfdt->full_fds_bits, ofdt->full_fds_bits, cpy);
-   memset((char *)nfdt->full_fds_bits + cpy, 0, set);
 }
 
 /*
@@ -124,14 +116,12 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
fdt->max_fds = nr;
 
data = alloc_fdmem(max_t(size_t,
-2 * nr / BITS_PER_BYTE + BITBIT_SIZE(nr), 
L1_CACHE_BYTES));
+2 * nr / BITS_PER_BYTE, L1_CACHE_BYTES));
if (!data)
goto out_fdt;
fdt->open_fds = data;
data += nr / BITS_PER_BYTE;
fdt->close_on_exec = data;
-   data += nr / BITS_PER_BYTE;
-   fdt->full_fds_bits = data;
 
return fdt;
 
@@ -246,15 +236,11 @@ static inline void __clear_close_on_exec(unsigned int fd, 
struct fdtable *fdt)
 static inline void __set_open_fd(unsigned int fd, struct fdtable *fdt)
 {
__set_bit(fd, fdt->open_fds);
-   fd /= BITS_PER_LONG;
-   if (!~fdt->open_fds[fd])
-   __set_bit(fd, fdt->full_fds_bits);
 }
 
 static inline void __clear_open_fd(unsigned int fd, struct fdtable *fdt)
 {
__clear_bit(fd, fdt->open_fds);
-   __clear_bit(fd / BITS_PER_LONG, fdt->full_fds_bits);
 }
 
 static unsigned int count_open_files(struct fdtable *fdt)
@@ -298,7 +284,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
new_fdt->max_fds = NR_OPEN_DEFAULT;
new_fdt->close_on_exec = newf->close_on_exec_init;
new_fdt->open_fds = newf->open_fds_init;
-   new_fdt->full_fds_bits = newf->full_fds_bits_init;
 
 restart:
idr_copy_preload(>fd_idr, GFP_KERNEL);
@@ -472,7 +457,6 @@ struct files_struct init_files = {
.max_fds= NR_OPEN_DEFAULT,
.close_on_exec  = init_files.close_on_exec_init,
.open_fds   = init_files.open_fds_init,
-   .full_fds_bits  = init_files.full_fds_bits_init,
},
.file_lock  = __SPIN_LOCK_UNLOCKED(init_files.file_lock),
.fd_idr = IDR_INIT,
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index c2a53b6..6bece35 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -26,7 +26,6 @@ struct fdtable {
unsigned int max_fds;
unsigned long *close_on_exec;
unsigned long *open_fds;
-   unsigned long *full_fds_bits;
struct rcu_head rcu;
 };
 
@@ -60,7 +59,6 @@ struct files_struct {
spinlock_t file_lock cacheline_aligned_in_smp;
unsigned long close_on_exec_init[1];
unsigned long open_fds_init[1];
-   unsigned long full_fds_bits_init[1];
 };
 
 struct file_operations;
-- 
1.8.3.1



[RESEND PATCH 07/13] vfs: Remove full_fds_bits from fd allocation code path.

2017-07-11 Thread Sandhya Bankar
The IDR has removed the need to have full_fds_bits hence removing it.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/file.c   | 18 +-
 include/linux/fdtable.h |  2 --
 2 files changed, 1 insertion(+), 19 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index da3a35b..e8c6ada 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -56,9 +56,6 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
__free_fdtable(container_of(rcu, struct fdtable, rcu));
 }
 
-#define BITBIT_NR(nr)  BITS_TO_LONGS(BITS_TO_LONGS(nr))
-#define BITBIT_SIZE(nr)(BITBIT_NR(nr) * sizeof(long))
-
 /*
  * Copy 'count' fd bits from the old table to the new table and clear the extra
  * space if any.  This does not copy the file pointers.  Called with the files
@@ -75,11 +72,6 @@ static void copy_fd_bitmaps(struct fdtable *nfdt, struct 
fdtable *ofdt,
memset((char *)nfdt->open_fds + cpy, 0, set);
memcpy(nfdt->close_on_exec, ofdt->close_on_exec, cpy);
memset((char *)nfdt->close_on_exec + cpy, 0, set);
-
-   cpy = BITBIT_SIZE(count);
-   set = BITBIT_SIZE(nfdt->max_fds) - cpy;
-   memcpy(nfdt->full_fds_bits, ofdt->full_fds_bits, cpy);
-   memset((char *)nfdt->full_fds_bits + cpy, 0, set);
 }
 
 /*
@@ -124,14 +116,12 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
fdt->max_fds = nr;
 
data = alloc_fdmem(max_t(size_t,
-2 * nr / BITS_PER_BYTE + BITBIT_SIZE(nr), 
L1_CACHE_BYTES));
+2 * nr / BITS_PER_BYTE, L1_CACHE_BYTES));
if (!data)
goto out_fdt;
fdt->open_fds = data;
data += nr / BITS_PER_BYTE;
fdt->close_on_exec = data;
-   data += nr / BITS_PER_BYTE;
-   fdt->full_fds_bits = data;
 
return fdt;
 
@@ -246,15 +236,11 @@ static inline void __clear_close_on_exec(unsigned int fd, 
struct fdtable *fdt)
 static inline void __set_open_fd(unsigned int fd, struct fdtable *fdt)
 {
__set_bit(fd, fdt->open_fds);
-   fd /= BITS_PER_LONG;
-   if (!~fdt->open_fds[fd])
-   __set_bit(fd, fdt->full_fds_bits);
 }
 
 static inline void __clear_open_fd(unsigned int fd, struct fdtable *fdt)
 {
__clear_bit(fd, fdt->open_fds);
-   __clear_bit(fd / BITS_PER_LONG, fdt->full_fds_bits);
 }
 
 static unsigned int count_open_files(struct fdtable *fdt)
@@ -298,7 +284,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
new_fdt->max_fds = NR_OPEN_DEFAULT;
new_fdt->close_on_exec = newf->close_on_exec_init;
new_fdt->open_fds = newf->open_fds_init;
-   new_fdt->full_fds_bits = newf->full_fds_bits_init;
 
 restart:
idr_copy_preload(>fd_idr, GFP_KERNEL);
@@ -472,7 +457,6 @@ struct files_struct init_files = {
.max_fds= NR_OPEN_DEFAULT,
.close_on_exec  = init_files.close_on_exec_init,
.open_fds   = init_files.open_fds_init,
-   .full_fds_bits  = init_files.full_fds_bits_init,
},
.file_lock  = __SPIN_LOCK_UNLOCKED(init_files.file_lock),
.fd_idr = IDR_INIT,
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index c2a53b6..6bece35 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -26,7 +26,6 @@ struct fdtable {
unsigned int max_fds;
unsigned long *close_on_exec;
unsigned long *open_fds;
-   unsigned long *full_fds_bits;
struct rcu_head rcu;
 };
 
@@ -60,7 +59,6 @@ struct files_struct {
spinlock_t file_lock cacheline_aligned_in_smp;
unsigned long close_on_exec_init[1];
unsigned long open_fds_init[1];
-   unsigned long full_fds_bits_init[1];
 };
 
 struct file_operations;
-- 
1.8.3.1



Re: [PATCH] [media] staging/imx: remove confusing IS_ERR_OR_NULL usage

2017-07-11 Thread Arnd Bergmann
On Thu, Jun 29, 2017 at 11:13 AM, Philipp Zabel  wrote:

>> @@ -134,23 +134,26 @@ static void csi_idmac_put_ipu_resources(struct 
>> csi_priv *priv)
>>  static int csi_idmac_get_ipu_resources(struct csi_priv *priv)
>>  {
>>   int ch_num, ret;
>> + struct ipu_smfc *smfc, *idmac_ch;
>
> This should be
>
> +   struct ipuv3_channel *idmac_ch;
> +   struct ipu_smfc *smfc;
>
> instead.

Fixed in v2 now.

>
> ... this changes behaviour:
>
> imx-media: imx_media_of_parse failed with -17
> imx-media: probe of capture-subsystem failed with error -17
>
> We must continue to return NULL here if imxsd == -EEXIST:
>
> -   return imxsd;
> +   return PTR_ERR(imxsd) == -EEXIST ? NULL : imxsd;
>
> or change the code where of_parse_subdev is called (from
> imx_media_of_parse, and recursively from of_parse_subdev) to not handle
> the -EEXIST return value as an error.
>
> With those fixed,
>
> Reviewed-by: Philipp Zabel 
> Tested-by: Philipp Zabel 

I thought about it some more and tried to find a better solution for this
function, which is now a bit different, so I did not add your tags.

Can you have another look at v2? This time, of_parse_subdev separates
the return code from the pointer, which seems less confusing in a function
like that. There are in fact two cases where we return NULL and it's
not clear if the caller should treat that as success or failure. I've left
the current behavior the same but added comments there.

 Arnd


Re: [PATCH] [media] staging/imx: remove confusing IS_ERR_OR_NULL usage

2017-07-11 Thread Arnd Bergmann
On Thu, Jun 29, 2017 at 11:13 AM, Philipp Zabel  wrote:

>> @@ -134,23 +134,26 @@ static void csi_idmac_put_ipu_resources(struct 
>> csi_priv *priv)
>>  static int csi_idmac_get_ipu_resources(struct csi_priv *priv)
>>  {
>>   int ch_num, ret;
>> + struct ipu_smfc *smfc, *idmac_ch;
>
> This should be
>
> +   struct ipuv3_channel *idmac_ch;
> +   struct ipu_smfc *smfc;
>
> instead.

Fixed in v2 now.

>
> ... this changes behaviour:
>
> imx-media: imx_media_of_parse failed with -17
> imx-media: probe of capture-subsystem failed with error -17
>
> We must continue to return NULL here if imxsd == -EEXIST:
>
> -   return imxsd;
> +   return PTR_ERR(imxsd) == -EEXIST ? NULL : imxsd;
>
> or change the code where of_parse_subdev is called (from
> imx_media_of_parse, and recursively from of_parse_subdev) to not handle
> the -EEXIST return value as an error.
>
> With those fixed,
>
> Reviewed-by: Philipp Zabel 
> Tested-by: Philipp Zabel 

I thought about it some more and tried to find a better solution for this
function, which is now a bit different, so I did not add your tags.

Can you have another look at v2? This time, of_parse_subdev separates
the return code from the pointer, which seems less confusing in a function
like that. There are in fact two cases where we return NULL and it's
not clear if the caller should treat that as success or failure. I've left
the current behavior the same but added comments there.

 Arnd


[RESEND PATCH 06/13] vfs: Remove next_fd from fd alloc code path.

2017-07-11 Thread Sandhya Bankar
The IDR is used in file descriptor allocation code to
allocate new file descriptor so, no need of next_fd to
track next file descriptor.
Hence removing it from file descriptor allocation code path.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/file.c   | 6 --
 include/linux/fdtable.h | 1 -
 2 files changed, 7 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index 1c000d8..da3a35b 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -294,7 +294,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
idr_init(>fd_idr);
newf->resize_in_progress = false;
init_waitqueue_head(>resize_wait);
-   newf->next_fd = 0;
new_fdt = >fdtab;
new_fdt->max_fds = NR_OPEN_DEFAULT;
new_fdt->close_on_exec = newf->close_on_exec_init;
@@ -506,9 +505,6 @@ int __alloc_fd(struct files_struct *files,
goto out;
}
 
-   if (start <= files->next_fd)
-   files->next_fd = fd + 1;
-
fdt = files_fdtable(files);
__set_open_fd(fd, fdt);
if (flags & O_CLOEXEC)
@@ -538,8 +534,6 @@ static void __put_unused_fd(struct files_struct *files, 
unsigned int fd)
 {
struct fdtable *fdt = files_fdtable(files);
__clear_open_fd(fd, fdt);
-   if (fd < files->next_fd)
-   files->next_fd = fd;
 }
 
 void put_unused_fd(unsigned int fd)
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 4072f24..c2a53b6 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -58,7 +58,6 @@ struct files_struct {
* written part on a separate cache line in SMP
*/
spinlock_t file_lock cacheline_aligned_in_smp;
-   unsigned int next_fd;
unsigned long close_on_exec_init[1];
unsigned long open_fds_init[1];
unsigned long full_fds_bits_init[1];
-- 
1.8.3.1



[RESEND PATCH 06/13] vfs: Remove next_fd from fd alloc code path.

2017-07-11 Thread Sandhya Bankar
The IDR is used in file descriptor allocation code to
allocate new file descriptor so, no need of next_fd to
track next file descriptor.
Hence removing it from file descriptor allocation code path.

Signed-off-by: Sandhya Bankar 
Signed-off-by: Matthew Wilcox 
---
 fs/file.c   | 6 --
 include/linux/fdtable.h | 1 -
 2 files changed, 7 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index 1c000d8..da3a35b 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -294,7 +294,6 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
idr_init(>fd_idr);
newf->resize_in_progress = false;
init_waitqueue_head(>resize_wait);
-   newf->next_fd = 0;
new_fdt = >fdtab;
new_fdt->max_fds = NR_OPEN_DEFAULT;
new_fdt->close_on_exec = newf->close_on_exec_init;
@@ -506,9 +505,6 @@ int __alloc_fd(struct files_struct *files,
goto out;
}
 
-   if (start <= files->next_fd)
-   files->next_fd = fd + 1;
-
fdt = files_fdtable(files);
__set_open_fd(fd, fdt);
if (flags & O_CLOEXEC)
@@ -538,8 +534,6 @@ static void __put_unused_fd(struct files_struct *files, 
unsigned int fd)
 {
struct fdtable *fdt = files_fdtable(files);
__clear_open_fd(fd, fdt);
-   if (fd < files->next_fd)
-   files->next_fd = fd;
 }
 
 void put_unused_fd(unsigned int fd)
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 4072f24..c2a53b6 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -58,7 +58,6 @@ struct files_struct {
* written part on a separate cache line in SMP
*/
spinlock_t file_lock cacheline_aligned_in_smp;
-   unsigned int next_fd;
unsigned long close_on_exec_init[1];
unsigned long open_fds_init[1];
unsigned long full_fds_bits_init[1];
-- 
1.8.3.1



Re: [PATCH 8/9] RISC-V: User-facing API

2017-07-11 Thread Will Deacon
On Mon, Jul 10, 2017 at 01:00:29PM -0700, Palmer Dabbelt wrote:
> On Thu, 06 Jul 2017 08:45:13 PDT (-0700), will.dea...@arm.com wrote:
> > On Thu, Jul 06, 2017 at 08:34:27AM -0700, Christoph Hellwig wrote:
> >> On Thu, Jul 06, 2017 at 09:55:03AM +0100, Will Deacon wrote:
> >> > Agreed on the indirection; it feels like this is something that should 
> >> > be in
> >> > the vDSO, which could use the cmpxchg instruction if it's available, or
> >> > otherwise just uses plain loads and stores.
> 
> These are already in the vDSO, and use the corresponding atomic instructions 
> on
> systems with the A extension.  The vDSO routines call the system calls in 
> non-A
> systems.  As far as I can tell that's necessary to preserve atomicity, which 
> we
> currently do by disabling scheduling.  If there's a way to do this without
> entering the kernel then I'd be happy to support it, but I'm not sure how we
> could maintain atomicity using only regular loads and stores.

Take a look at the ARM code I mentioned. You can do away with the syscall if
you notice that you preempt a thread inside the critical section of the
vDSO, and, in that case you resume execution at a known "restart" address.

> >> Even that seems like a lot of indirection for something that is in
> >> the critical fast path for synchronization.  I really can't understand
> >> how a new ISA / ABI could even come up with an idea as stupid as making
> >> essential synchronization primitives optional.
> >
> > No disagreement there!
> 
> The default set of multilibs on Linux are:
> 
>  * rv32imac: 32-bit; Multiply, Atomic, and Compressed extensions
>  * rv32imafdc: like above, but with single+double float
>  * rv64imac: 64-bit, Multiply, Atomic and Compressed
>  * rv64imafdc: like above, but with single+double float
> 
> all of which support the A extension.  We certainly don't plan on building any
> systems that support Linux without the A extension at SiFive, so I'm fine
> removing the system call -- this was originally added by a user, so there was
> at least enough interest for someone to add the system call.
> 
> We've found people are retrofitting other cores to run RISC-V, and I could
> certainly imagine an older design that lacks a beefy enough memory system to
> support our atomics (which are LR/SC based) being a design that might arise.
> There's a lot of systems where people don't seem to care that much about the
> performance and just want something to work -- if they're on such a tiny 
> system
> they can't implement the A extension then they're probably not going to be
> doing a lot of atomics anyway, so maybe it doesn't matter if atomics are slow.
> As the cost for supporting these A-less systems seems fairly small, it seemed
> like the right thing to do -- one of the points of making RISC-V have many
> optional extensions was to let people pick the ones they view as important.
> Since I don't know the performance constraints of their systems or the cost of
> implementing the A extension in their design, I'm not really qualified to tell
> them a cmpxchg syscall is a bad idea.

The problem is that by supporting these hypothetical designs that can't do
atomics, you hurt sensible designs that *can* do the atomics because you
force them to take an additional indirection that could otherwise be
avoided.

Will


Re: [PATCH 8/9] RISC-V: User-facing API

2017-07-11 Thread Will Deacon
On Mon, Jul 10, 2017 at 01:00:29PM -0700, Palmer Dabbelt wrote:
> On Thu, 06 Jul 2017 08:45:13 PDT (-0700), will.dea...@arm.com wrote:
> > On Thu, Jul 06, 2017 at 08:34:27AM -0700, Christoph Hellwig wrote:
> >> On Thu, Jul 06, 2017 at 09:55:03AM +0100, Will Deacon wrote:
> >> > Agreed on the indirection; it feels like this is something that should 
> >> > be in
> >> > the vDSO, which could use the cmpxchg instruction if it's available, or
> >> > otherwise just uses plain loads and stores.
> 
> These are already in the vDSO, and use the corresponding atomic instructions 
> on
> systems with the A extension.  The vDSO routines call the system calls in 
> non-A
> systems.  As far as I can tell that's necessary to preserve atomicity, which 
> we
> currently do by disabling scheduling.  If there's a way to do this without
> entering the kernel then I'd be happy to support it, but I'm not sure how we
> could maintain atomicity using only regular loads and stores.

Take a look at the ARM code I mentioned. You can do away with the syscall if
you notice that you preempt a thread inside the critical section of the
vDSO, and, in that case you resume execution at a known "restart" address.

> >> Even that seems like a lot of indirection for something that is in
> >> the critical fast path for synchronization.  I really can't understand
> >> how a new ISA / ABI could even come up with an idea as stupid as making
> >> essential synchronization primitives optional.
> >
> > No disagreement there!
> 
> The default set of multilibs on Linux are:
> 
>  * rv32imac: 32-bit; Multiply, Atomic, and Compressed extensions
>  * rv32imafdc: like above, but with single+double float
>  * rv64imac: 64-bit, Multiply, Atomic and Compressed
>  * rv64imafdc: like above, but with single+double float
> 
> all of which support the A extension.  We certainly don't plan on building any
> systems that support Linux without the A extension at SiFive, so I'm fine
> removing the system call -- this was originally added by a user, so there was
> at least enough interest for someone to add the system call.
> 
> We've found people are retrofitting other cores to run RISC-V, and I could
> certainly imagine an older design that lacks a beefy enough memory system to
> support our atomics (which are LR/SC based) being a design that might arise.
> There's a lot of systems where people don't seem to care that much about the
> performance and just want something to work -- if they're on such a tiny 
> system
> they can't implement the A extension then they're probably not going to be
> doing a lot of atomics anyway, so maybe it doesn't matter if atomics are slow.
> As the cost for supporting these A-less systems seems fairly small, it seemed
> like the right thing to do -- one of the points of making RISC-V have many
> optional extensions was to let people pick the ones they view as important.
> Since I don't know the performance constraints of their systems or the cost of
> implementing the A extension in their design, I'm not really qualified to tell
> them a cmpxchg syscall is a bad idea.

The problem is that by supporting these hypothetical designs that can't do
atomics, you hurt sensible designs that *can* do the atomics because you
force them to take an additional indirection that could otherwise be
avoided.

Will


[RESEND PATCH 05/13] vfs: Replace array of file pointers with an IDR

2017-07-11 Thread Sandhya Bankar
Instead of storing all the file pointers in a single array, use an
IDR.  It is RCU-safe, and does not need to be reallocated when the
fd array grows.  It also handles allocation of new file descriptors.

Signed-off-by: Sandhya Bankar 
[mawil...@microsoft.com: fixes]
Signed-off-by: Matthew Wilcox 
---
 fs/file.c   | 180 
 include/linux/fdtable.h |  10 +--
 2 files changed, 79 insertions(+), 111 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index ad6f094..1c000d8 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -47,7 +47,6 @@ static void *alloc_fdmem(size_t size)
 
 static void __free_fdtable(struct fdtable *fdt)
 {
-   kvfree(fdt->fd);
kvfree(fdt->open_fds);
kfree(fdt);
 }
@@ -89,15 +88,7 @@ static void copy_fd_bitmaps(struct fdtable *nfdt, struct 
fdtable *ofdt,
  */
 static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
 {
-   unsigned int cpy, set;
-
BUG_ON(nfdt->max_fds < ofdt->max_fds);
-
-   cpy = ofdt->max_fds * sizeof(struct file *);
-   set = (nfdt->max_fds - ofdt->max_fds) * sizeof(struct file *);
-   memcpy(nfdt->fd, ofdt->fd, cpy);
-   memset((char *)nfdt->fd + cpy, 0, set);
-
copy_fd_bitmaps(nfdt, ofdt, ofdt->max_fds);
 }
 
@@ -131,15 +122,11 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
if (!fdt)
goto out;
fdt->max_fds = nr;
-   data = alloc_fdmem(nr * sizeof(struct file *));
-   if (!data)
-   goto out_fdt;
-   fdt->fd = data;
 
data = alloc_fdmem(max_t(size_t,
 2 * nr / BITS_PER_BYTE + BITBIT_SIZE(nr), 
L1_CACHE_BYTES));
if (!data)
-   goto out_arr;
+   goto out_fdt;
fdt->open_fds = data;
data += nr / BITS_PER_BYTE;
fdt->close_on_exec = data;
@@ -148,8 +135,6 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
 
return fdt;
 
-out_arr:
-   kvfree(fdt->fd);
 out_fdt:
kfree(fdt);
 out:
@@ -170,6 +155,7 @@ static int expand_fdtable(struct files_struct *files, 
unsigned int nr)
struct fdtable *new_fdt, *cur_fdt;
 
spin_unlock(>file_lock);
+   idr_preload_end();
new_fdt = alloc_fdtable(nr);
 
/* make sure all __fd_install() have seen resize_in_progress
@@ -178,6 +164,7 @@ static int expand_fdtable(struct files_struct *files, 
unsigned int nr)
if (atomic_read(>count) > 1)
synchronize_sched();
 
+   idr_preload(GFP_KERNEL);
spin_lock(>file_lock);
if (!new_fdt)
return -ENOMEM;
@@ -228,8 +215,10 @@ static int expand_files(struct files_struct *files, 
unsigned int nr)
 
if (unlikely(files->resize_in_progress)) {
spin_unlock(>file_lock);
+   idr_preload_end();
expanded = 1;
wait_event(files->resize_wait, !files->resize_in_progress);
+   idr_preload(GFP_KERNEL);
spin_lock(>file_lock);
goto repeat;
}
@@ -290,8 +279,8 @@ static unsigned int count_open_files(struct fdtable *fdt)
 struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
 {
struct files_struct *newf;
-   struct file **old_fds, **new_fds;
unsigned int open_files, i;
+   struct file *f;
struct fdtable *old_fdt, *new_fdt;
 
*errorp = -ENOMEM;
@@ -302,6 +291,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
atomic_set(>count, 1);
 
spin_lock_init(>file_lock);
+   idr_init(>fd_idr);
newf->resize_in_progress = false;
init_waitqueue_head(>resize_wait);
newf->next_fd = 0;
@@ -310,8 +300,9 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
new_fdt->close_on_exec = newf->close_on_exec_init;
new_fdt->open_fds = newf->open_fds_init;
new_fdt->full_fds_bits = newf->full_fds_bits_init;
-   new_fdt->fd = >fd_array[0];
 
+restart:
+   idr_copy_preload(>fd_idr, GFP_KERNEL);
spin_lock(>file_lock);
old_fdt = files_fdtable(oldf);
open_files = count_open_files(old_fdt);
@@ -321,6 +312,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
 */
while (unlikely(open_files > new_fdt->max_fds)) {
spin_unlock(>file_lock);
+   idr_preload_end();
 
if (new_fdt != >fdtab)
__free_fdtable(new_fdt);
@@ -343,41 +335,50 @@ struct files_struct *dup_fd(struct files_struct *oldf, 
int *errorp)
 * who knows it may have a new bigger fd table. We need
 * the latest pointer.
 */
+   idr_copy_preload(>fd_idr, GFP_KERNEL);
spin_lock(>file_lock);
old_fdt = files_fdtable(oldf);
open_files = 

[RESEND PATCH 05/13] vfs: Replace array of file pointers with an IDR

2017-07-11 Thread Sandhya Bankar
Instead of storing all the file pointers in a single array, use an
IDR.  It is RCU-safe, and does not need to be reallocated when the
fd array grows.  It also handles allocation of new file descriptors.

Signed-off-by: Sandhya Bankar 
[mawil...@microsoft.com: fixes]
Signed-off-by: Matthew Wilcox 
---
 fs/file.c   | 180 
 include/linux/fdtable.h |  10 +--
 2 files changed, 79 insertions(+), 111 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index ad6f094..1c000d8 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -47,7 +47,6 @@ static void *alloc_fdmem(size_t size)
 
 static void __free_fdtable(struct fdtable *fdt)
 {
-   kvfree(fdt->fd);
kvfree(fdt->open_fds);
kfree(fdt);
 }
@@ -89,15 +88,7 @@ static void copy_fd_bitmaps(struct fdtable *nfdt, struct 
fdtable *ofdt,
  */
 static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt)
 {
-   unsigned int cpy, set;
-
BUG_ON(nfdt->max_fds < ofdt->max_fds);
-
-   cpy = ofdt->max_fds * sizeof(struct file *);
-   set = (nfdt->max_fds - ofdt->max_fds) * sizeof(struct file *);
-   memcpy(nfdt->fd, ofdt->fd, cpy);
-   memset((char *)nfdt->fd + cpy, 0, set);
-
copy_fd_bitmaps(nfdt, ofdt, ofdt->max_fds);
 }
 
@@ -131,15 +122,11 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
if (!fdt)
goto out;
fdt->max_fds = nr;
-   data = alloc_fdmem(nr * sizeof(struct file *));
-   if (!data)
-   goto out_fdt;
-   fdt->fd = data;
 
data = alloc_fdmem(max_t(size_t,
 2 * nr / BITS_PER_BYTE + BITBIT_SIZE(nr), 
L1_CACHE_BYTES));
if (!data)
-   goto out_arr;
+   goto out_fdt;
fdt->open_fds = data;
data += nr / BITS_PER_BYTE;
fdt->close_on_exec = data;
@@ -148,8 +135,6 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
 
return fdt;
 
-out_arr:
-   kvfree(fdt->fd);
 out_fdt:
kfree(fdt);
 out:
@@ -170,6 +155,7 @@ static int expand_fdtable(struct files_struct *files, 
unsigned int nr)
struct fdtable *new_fdt, *cur_fdt;
 
spin_unlock(>file_lock);
+   idr_preload_end();
new_fdt = alloc_fdtable(nr);
 
/* make sure all __fd_install() have seen resize_in_progress
@@ -178,6 +164,7 @@ static int expand_fdtable(struct files_struct *files, 
unsigned int nr)
if (atomic_read(>count) > 1)
synchronize_sched();
 
+   idr_preload(GFP_KERNEL);
spin_lock(>file_lock);
if (!new_fdt)
return -ENOMEM;
@@ -228,8 +215,10 @@ static int expand_files(struct files_struct *files, 
unsigned int nr)
 
if (unlikely(files->resize_in_progress)) {
spin_unlock(>file_lock);
+   idr_preload_end();
expanded = 1;
wait_event(files->resize_wait, !files->resize_in_progress);
+   idr_preload(GFP_KERNEL);
spin_lock(>file_lock);
goto repeat;
}
@@ -290,8 +279,8 @@ static unsigned int count_open_files(struct fdtable *fdt)
 struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
 {
struct files_struct *newf;
-   struct file **old_fds, **new_fds;
unsigned int open_files, i;
+   struct file *f;
struct fdtable *old_fdt, *new_fdt;
 
*errorp = -ENOMEM;
@@ -302,6 +291,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
atomic_set(>count, 1);
 
spin_lock_init(>file_lock);
+   idr_init(>fd_idr);
newf->resize_in_progress = false;
init_waitqueue_head(>resize_wait);
newf->next_fd = 0;
@@ -310,8 +300,9 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
new_fdt->close_on_exec = newf->close_on_exec_init;
new_fdt->open_fds = newf->open_fds_init;
new_fdt->full_fds_bits = newf->full_fds_bits_init;
-   new_fdt->fd = >fd_array[0];
 
+restart:
+   idr_copy_preload(>fd_idr, GFP_KERNEL);
spin_lock(>file_lock);
old_fdt = files_fdtable(oldf);
open_files = count_open_files(old_fdt);
@@ -321,6 +312,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int 
*errorp)
 */
while (unlikely(open_files > new_fdt->max_fds)) {
spin_unlock(>file_lock);
+   idr_preload_end();
 
if (new_fdt != >fdtab)
__free_fdtable(new_fdt);
@@ -343,41 +335,50 @@ struct files_struct *dup_fd(struct files_struct *oldf, 
int *errorp)
 * who knows it may have a new bigger fd table. We need
 * the latest pointer.
 */
+   idr_copy_preload(>fd_idr, GFP_KERNEL);
spin_lock(>file_lock);
old_fdt = files_fdtable(oldf);
open_files = count_open_files(old_fdt);
}
 
+   if 

[PATCH v2] [media] staging/imx: remove confusing IS_ERR_OR_NULL usage

2017-07-11 Thread Arnd Bergmann
While looking at a compiler warning, I noticed the use of
IS_ERR_OR_NULL, which is generally a sign of a bad API design
and should be avoided.

In this driver, this is fairly easy, we can simply stop storing
error pointers in persistent structures, and change the two
functions that might return either a NULL pointer or an error
code to consistently return error pointers when failing.

of_parse_subdev() now separates the error code and the pointer
it looks up, to clarify the interface. There are two cases
where this function originally returns 'NULL', and I have
changed that to '0' for success to keep the current behavior,
though returning an error would also make sense there.

Fixes: e130291212df ("[media] media: Add i.MX media core driver")
Signed-off-by: Arnd Bergmann 
---
v2: fix type mismatch
v3: rework of_parse_subdev() as well.
---
 drivers/staging/media/imx/imx-ic-prpencvf.c | 41 ---
 drivers/staging/media/imx/imx-media-csi.c   | 30 ++---
 drivers/staging/media/imx/imx-media-dev.c   |  4 +--
 drivers/staging/media/imx/imx-media-of.c| 50 -
 drivers/staging/media/imx/imx-media-vdic.c  | 37 +++--
 5 files changed, 90 insertions(+), 72 deletions(-)

diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c 
b/drivers/staging/media/imx/imx-ic-prpencvf.c
index ed363fe3b3d0..7a9d9f32f989 100644
--- a/drivers/staging/media/imx/imx-ic-prpencvf.c
+++ b/drivers/staging/media/imx/imx-ic-prpencvf.c
@@ -134,19 +134,19 @@ static inline struct prp_priv *sd_to_priv(struct 
v4l2_subdev *sd)
 
 static void prp_put_ipu_resources(struct prp_priv *priv)
 {
-   if (!IS_ERR_OR_NULL(priv->ic))
+   if (priv->ic)
ipu_ic_put(priv->ic);
priv->ic = NULL;
 
-   if (!IS_ERR_OR_NULL(priv->out_ch))
+   if (priv->out_ch)
ipu_idmac_put(priv->out_ch);
priv->out_ch = NULL;
 
-   if (!IS_ERR_OR_NULL(priv->rot_in_ch))
+   if (priv->rot_in_ch)
ipu_idmac_put(priv->rot_in_ch);
priv->rot_in_ch = NULL;
 
-   if (!IS_ERR_OR_NULL(priv->rot_out_ch))
+   if (priv->rot_out_ch)
ipu_idmac_put(priv->rot_out_ch);
priv->rot_out_ch = NULL;
 }
@@ -154,43 +154,46 @@ static void prp_put_ipu_resources(struct prp_priv *priv)
 static int prp_get_ipu_resources(struct prp_priv *priv)
 {
struct imx_ic_priv *ic_priv = priv->ic_priv;
+   struct ipu_ic *ic;
+   struct ipuv3_channel *out_ch, *rot_in_ch, *rot_out_ch;
int ret, task = ic_priv->task_id;
 
priv->ipu = priv->md->ipu[ic_priv->ipu_id];
 
-   priv->ic = ipu_ic_get(priv->ipu, task);
-   if (IS_ERR(priv->ic)) {
+   ic = ipu_ic_get(priv->ipu, task);
+   if (IS_ERR(ic)) {
v4l2_err(_priv->sd, "failed to get IC\n");
-   ret = PTR_ERR(priv->ic);
+   ret = PTR_ERR(ic);
goto out;
}
+   priv->ic = ic;
 
-   priv->out_ch = ipu_idmac_get(priv->ipu,
-prp_channel[task].out_ch);
-   if (IS_ERR(priv->out_ch)) {
+   out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].out_ch);
+   if (IS_ERR(out_ch)) {
v4l2_err(_priv->sd, "could not get IDMAC channel %u\n",
 prp_channel[task].out_ch);
-   ret = PTR_ERR(priv->out_ch);
+   ret = PTR_ERR(out_ch);
goto out;
}
+   priv->out_ch = out_ch;
 
-   priv->rot_in_ch = ipu_idmac_get(priv->ipu,
-   prp_channel[task].rot_in_ch);
-   if (IS_ERR(priv->rot_in_ch)) {
+   rot_in_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_in_ch);
+   if (IS_ERR(rot_in_ch)) {
v4l2_err(_priv->sd, "could not get IDMAC channel %u\n",
 prp_channel[task].rot_in_ch);
-   ret = PTR_ERR(priv->rot_in_ch);
+   ret = PTR_ERR(rot_in_ch);
goto out;
}
+   priv->rot_in_ch = rot_in_ch;
 
-   priv->rot_out_ch = ipu_idmac_get(priv->ipu,
-prp_channel[task].rot_out_ch);
-   if (IS_ERR(priv->rot_out_ch)) {
+   rot_out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_out_ch);
+   if (IS_ERR(rot_out_ch)) {
v4l2_err(_priv->sd, "could not get IDMAC channel %u\n",
 prp_channel[task].rot_out_ch);
-   ret = PTR_ERR(priv->rot_out_ch);
+   ret = PTR_ERR(rot_out_ch);
goto out;
}
+   priv->rot_out_ch = rot_out_ch;
 
return 0;
 out:
diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index a2d26693912e..17fd1e61dd5d 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -122,11 +122,11 @@ static inline struct csi_priv *sd_to_dev(struct 
v4l2_subdev *sdev)
 
 static void 

[PATCH v2] [media] staging/imx: remove confusing IS_ERR_OR_NULL usage

2017-07-11 Thread Arnd Bergmann
While looking at a compiler warning, I noticed the use of
IS_ERR_OR_NULL, which is generally a sign of a bad API design
and should be avoided.

In this driver, this is fairly easy, we can simply stop storing
error pointers in persistent structures, and change the two
functions that might return either a NULL pointer or an error
code to consistently return error pointers when failing.

of_parse_subdev() now separates the error code and the pointer
it looks up, to clarify the interface. There are two cases
where this function originally returns 'NULL', and I have
changed that to '0' for success to keep the current behavior,
though returning an error would also make sense there.

Fixes: e130291212df ("[media] media: Add i.MX media core driver")
Signed-off-by: Arnd Bergmann 
---
v2: fix type mismatch
v3: rework of_parse_subdev() as well.
---
 drivers/staging/media/imx/imx-ic-prpencvf.c | 41 ---
 drivers/staging/media/imx/imx-media-csi.c   | 30 ++---
 drivers/staging/media/imx/imx-media-dev.c   |  4 +--
 drivers/staging/media/imx/imx-media-of.c| 50 -
 drivers/staging/media/imx/imx-media-vdic.c  | 37 +++--
 5 files changed, 90 insertions(+), 72 deletions(-)

diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c 
b/drivers/staging/media/imx/imx-ic-prpencvf.c
index ed363fe3b3d0..7a9d9f32f989 100644
--- a/drivers/staging/media/imx/imx-ic-prpencvf.c
+++ b/drivers/staging/media/imx/imx-ic-prpencvf.c
@@ -134,19 +134,19 @@ static inline struct prp_priv *sd_to_priv(struct 
v4l2_subdev *sd)
 
 static void prp_put_ipu_resources(struct prp_priv *priv)
 {
-   if (!IS_ERR_OR_NULL(priv->ic))
+   if (priv->ic)
ipu_ic_put(priv->ic);
priv->ic = NULL;
 
-   if (!IS_ERR_OR_NULL(priv->out_ch))
+   if (priv->out_ch)
ipu_idmac_put(priv->out_ch);
priv->out_ch = NULL;
 
-   if (!IS_ERR_OR_NULL(priv->rot_in_ch))
+   if (priv->rot_in_ch)
ipu_idmac_put(priv->rot_in_ch);
priv->rot_in_ch = NULL;
 
-   if (!IS_ERR_OR_NULL(priv->rot_out_ch))
+   if (priv->rot_out_ch)
ipu_idmac_put(priv->rot_out_ch);
priv->rot_out_ch = NULL;
 }
@@ -154,43 +154,46 @@ static void prp_put_ipu_resources(struct prp_priv *priv)
 static int prp_get_ipu_resources(struct prp_priv *priv)
 {
struct imx_ic_priv *ic_priv = priv->ic_priv;
+   struct ipu_ic *ic;
+   struct ipuv3_channel *out_ch, *rot_in_ch, *rot_out_ch;
int ret, task = ic_priv->task_id;
 
priv->ipu = priv->md->ipu[ic_priv->ipu_id];
 
-   priv->ic = ipu_ic_get(priv->ipu, task);
-   if (IS_ERR(priv->ic)) {
+   ic = ipu_ic_get(priv->ipu, task);
+   if (IS_ERR(ic)) {
v4l2_err(_priv->sd, "failed to get IC\n");
-   ret = PTR_ERR(priv->ic);
+   ret = PTR_ERR(ic);
goto out;
}
+   priv->ic = ic;
 
-   priv->out_ch = ipu_idmac_get(priv->ipu,
-prp_channel[task].out_ch);
-   if (IS_ERR(priv->out_ch)) {
+   out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].out_ch);
+   if (IS_ERR(out_ch)) {
v4l2_err(_priv->sd, "could not get IDMAC channel %u\n",
 prp_channel[task].out_ch);
-   ret = PTR_ERR(priv->out_ch);
+   ret = PTR_ERR(out_ch);
goto out;
}
+   priv->out_ch = out_ch;
 
-   priv->rot_in_ch = ipu_idmac_get(priv->ipu,
-   prp_channel[task].rot_in_ch);
-   if (IS_ERR(priv->rot_in_ch)) {
+   rot_in_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_in_ch);
+   if (IS_ERR(rot_in_ch)) {
v4l2_err(_priv->sd, "could not get IDMAC channel %u\n",
 prp_channel[task].rot_in_ch);
-   ret = PTR_ERR(priv->rot_in_ch);
+   ret = PTR_ERR(rot_in_ch);
goto out;
}
+   priv->rot_in_ch = rot_in_ch;
 
-   priv->rot_out_ch = ipu_idmac_get(priv->ipu,
-prp_channel[task].rot_out_ch);
-   if (IS_ERR(priv->rot_out_ch)) {
+   rot_out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_out_ch);
+   if (IS_ERR(rot_out_ch)) {
v4l2_err(_priv->sd, "could not get IDMAC channel %u\n",
 prp_channel[task].rot_out_ch);
-   ret = PTR_ERR(priv->rot_out_ch);
+   ret = PTR_ERR(rot_out_ch);
goto out;
}
+   priv->rot_out_ch = rot_out_ch;
 
return 0;
 out:
diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index a2d26693912e..17fd1e61dd5d 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -122,11 +122,11 @@ static inline struct csi_priv *sd_to_dev(struct 
v4l2_subdev *sdev)
 
 static void 

Re: [PATCH 00/16] omap_hsmmc: Add ADMA support and UHS/HS200/DDR support

2017-07-11 Thread Ulf Hansson
On 16 June 2017 at 14:45, Kishon Vijay Abraham I  wrote:
> This is the final part of the series originally sent as
> part of [2].
>
> This series adds UHS, HS200, DDR mode and ADMA support to
> omap_hsmmc driver used to improve the throughput of MMC/SD in dra7
> SoCs.
>
> Changes from [2]:
> *) No more updating omap2plus_defconfig or multi_v7_defconfig is
>required, so those patches are removed.
> *) Addressed Rob Herring's comment on implementing a function
>instead of having a macro while getting pinctrl state.
>
> This series is created on top of [3], [4], [5] AND [6]
> (i.e after
>   ARM: dts: omap3-overo: Remove "vqmmc-supply" property from MMC dt node
>   omap_hsmmc: use mmc_regulator_get_supply() to get regulators
>   omap*: Fixes/Cleanups for MMC devicetree node
>   ARM: dts: Add iodelay data for MMC)
>
> The functionality implemented in this series was sent before ([1]) but
> was never followed up since supporting high speed modes in dra7 required
> IODelay values to be configured. With IODelay driver being merged into
> kernel, sending it as a fresh series with support for configuring IODelay
> values.

Is it safe to queue this via mmc tree for 4.14 or is there a
dependency I must consider? The above didn't quite tell me that, could
you please elaborate.

>
> Suggestions of migrating to sdhci driver (from omap_hsmmc driver) is not
> addressed since
> *) tuning ratio of MMC in dra7 is different from sdhci
> *) IOdelay is required for dra7
> *) GPIO based card detect is not supported in sdhci

Lots of sdhci drivers calls mmc_of_parse(), and uses the mmc slot gpio
APIs, so I don't this this is correct statement.

> *) Some of the registers don't always have correct values as in sdhci
>(like PSTATE).
> Supporting all of these in sdhci will result in adding lot of quirks in
> sdhci driver.

Is it really that much different? It would be nice if some really took
on the challenge of converting omap_hsmmc into an sdhci variant.

Especially by looking at the number new lines added in this series, I
am starting to think that we have reached this point. That in
conjunction with that sdhci is maintained and well supported,
comparing to what the omap_hsmmc driver seems to be.

>
> This series has been tested on beagleboard, pandaboard, beaglebone-black,
> beaglebone, am335x-evm, am437x-evm, dra7xx-evm, dra72x-evm, am571x-idk
> and am572x-idk.
>
> I can split the series to go into Ulf Hansson's tree and Tony's tree
> separately if that is required.
>
> [1] -> https://lkml.org/lkml/2015/8/25/213
> [2] -> https://lkml.org/lkml/2017/5/19/19
>
> [3] -> https://lkml.org/lkml/2017/6/9/206
> [4] -> https://lkml.org/lkml/2017/6/7/169
> [5] -> https://www.spinics.net/lists/arm-kernel/msg586215.html /
>http://www.spinics.net/lists/devicetree/msg180747.html
> [6] -> 
> https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1423381.html
>
> Kishon Vijay Abraham I (15):
>   mmc: host: omap_hsmmc: Support pbias and vmmc_aux to switch to 1.8v
>   mmc: host: omap_hsmmc: Separate setting voltage capabilities from bus
> power
>   mmc: host: omap_hsmmc: Remove incorrect voltage switch sequence
>   mmc: host: omap_hsmmc: Add voltage switch support for UHS SD card
>   mmc: host: omap_hsmmc: Set clk rate to the max frequency
>   mmc: host: omap_hsmmc: Add tuning support
>   mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd
>   mmc: host: omap_hsmmc: Prepare *set_timing() to be used for iodelay
> setting
>   mmc: host: omap_hsmmc: Add new compatible string to support dra7
>   mmc: host: omap_hsmmc: Fix error path sequence
>   mmc: host: omap_hsmmc: Add support to set IODELAY values
>   mmc: host: omap_hsmmc: Remove *use_dma* member
>   mmc: host: omap_hsmmc: Enable ADMA2
>   ARM: dts: dra7: Use new dra7-specific compatible string
>   ARM: dts: dra7: Add supported MMC/SD modes in MMC dt nodes
>
> Mugunthan V N (1):
>   mmc: host: omap_hsmmc: Add software timer when timeout greater than
> hardware capablility
>
>  .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |6 +
>  arch/arm/boot/dts/am571x-idk.dts   |1 +
>  arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts  |1 +
>  arch/arm/boot/dts/am57xx-beagle-x15.dts|6 +
>  arch/arm/boot/dts/am57xx-idk-common.dtsi   |1 +
>  arch/arm/boot/dts/dra7.dtsi|   22 +-
>  drivers/mmc/host/omap_hsmmc.c  | 1179 
> 
>  include/linux/platform_data/hsmmc-omap.h   |2 +
>  8 files changed, 1021 insertions(+), 197 deletions(-)
>
> --
> 2.11.0
>

Kind regards
Ulf Hansson


Re: [PATCH 00/16] omap_hsmmc: Add ADMA support and UHS/HS200/DDR support

2017-07-11 Thread Ulf Hansson
On 16 June 2017 at 14:45, Kishon Vijay Abraham I  wrote:
> This is the final part of the series originally sent as
> part of [2].
>
> This series adds UHS, HS200, DDR mode and ADMA support to
> omap_hsmmc driver used to improve the throughput of MMC/SD in dra7
> SoCs.
>
> Changes from [2]:
> *) No more updating omap2plus_defconfig or multi_v7_defconfig is
>required, so those patches are removed.
> *) Addressed Rob Herring's comment on implementing a function
>instead of having a macro while getting pinctrl state.
>
> This series is created on top of [3], [4], [5] AND [6]
> (i.e after
>   ARM: dts: omap3-overo: Remove "vqmmc-supply" property from MMC dt node
>   omap_hsmmc: use mmc_regulator_get_supply() to get regulators
>   omap*: Fixes/Cleanups for MMC devicetree node
>   ARM: dts: Add iodelay data for MMC)
>
> The functionality implemented in this series was sent before ([1]) but
> was never followed up since supporting high speed modes in dra7 required
> IODelay values to be configured. With IODelay driver being merged into
> kernel, sending it as a fresh series with support for configuring IODelay
> values.

Is it safe to queue this via mmc tree for 4.14 or is there a
dependency I must consider? The above didn't quite tell me that, could
you please elaborate.

>
> Suggestions of migrating to sdhci driver (from omap_hsmmc driver) is not
> addressed since
> *) tuning ratio of MMC in dra7 is different from sdhci
> *) IOdelay is required for dra7
> *) GPIO based card detect is not supported in sdhci

Lots of sdhci drivers calls mmc_of_parse(), and uses the mmc slot gpio
APIs, so I don't this this is correct statement.

> *) Some of the registers don't always have correct values as in sdhci
>(like PSTATE).
> Supporting all of these in sdhci will result in adding lot of quirks in
> sdhci driver.

Is it really that much different? It would be nice if some really took
on the challenge of converting omap_hsmmc into an sdhci variant.

Especially by looking at the number new lines added in this series, I
am starting to think that we have reached this point. That in
conjunction with that sdhci is maintained and well supported,
comparing to what the omap_hsmmc driver seems to be.

>
> This series has been tested on beagleboard, pandaboard, beaglebone-black,
> beaglebone, am335x-evm, am437x-evm, dra7xx-evm, dra72x-evm, am571x-idk
> and am572x-idk.
>
> I can split the series to go into Ulf Hansson's tree and Tony's tree
> separately if that is required.
>
> [1] -> https://lkml.org/lkml/2015/8/25/213
> [2] -> https://lkml.org/lkml/2017/5/19/19
>
> [3] -> https://lkml.org/lkml/2017/6/9/206
> [4] -> https://lkml.org/lkml/2017/6/7/169
> [5] -> https://www.spinics.net/lists/arm-kernel/msg586215.html /
>http://www.spinics.net/lists/devicetree/msg180747.html
> [6] -> 
> https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1423381.html
>
> Kishon Vijay Abraham I (15):
>   mmc: host: omap_hsmmc: Support pbias and vmmc_aux to switch to 1.8v
>   mmc: host: omap_hsmmc: Separate setting voltage capabilities from bus
> power
>   mmc: host: omap_hsmmc: Remove incorrect voltage switch sequence
>   mmc: host: omap_hsmmc: Add voltage switch support for UHS SD card
>   mmc: host: omap_hsmmc: Set clk rate to the max frequency
>   mmc: host: omap_hsmmc: Add tuning support
>   mmc: host: omap_hsmmc: Allow io voltage switch even for fixed vdd
>   mmc: host: omap_hsmmc: Prepare *set_timing() to be used for iodelay
> setting
>   mmc: host: omap_hsmmc: Add new compatible string to support dra7
>   mmc: host: omap_hsmmc: Fix error path sequence
>   mmc: host: omap_hsmmc: Add support to set IODELAY values
>   mmc: host: omap_hsmmc: Remove *use_dma* member
>   mmc: host: omap_hsmmc: Enable ADMA2
>   ARM: dts: dra7: Use new dra7-specific compatible string
>   ARM: dts: dra7: Add supported MMC/SD modes in MMC dt nodes
>
> Mugunthan V N (1):
>   mmc: host: omap_hsmmc: Add software timer when timeout greater than
> hardware capablility
>
>  .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |6 +
>  arch/arm/boot/dts/am571x-idk.dts   |1 +
>  arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts  |1 +
>  arch/arm/boot/dts/am57xx-beagle-x15.dts|6 +
>  arch/arm/boot/dts/am57xx-idk-common.dtsi   |1 +
>  arch/arm/boot/dts/dra7.dtsi|   22 +-
>  drivers/mmc/host/omap_hsmmc.c  | 1179 
> 
>  include/linux/platform_data/hsmmc-omap.h   |2 +
>  8 files changed, 1021 insertions(+), 197 deletions(-)
>
> --
> 2.11.0
>

Kind regards
Ulf Hansson


Re: [PATCH v4 02/14] drm/atomic-helper: update lut props directly in ..._legacy_gamma_set

2017-07-11 Thread Peter Rosin
On 2017-07-11 10:02, Daniel Vetter wrote:
> On Thu, Jul 06, 2017 at 02:20:36PM +0200, Peter Rosin wrote:
>> Do not waste cycles looking up the property id when we have the
>> actual property already.
>>
>> Signed-off-by: Peter Rosin 
> 
> With the names adjusted per my comments on patch 1 this lgtm. Btw good
> practice is to cc original authors of the code, a combo of git blame and
> scripts/get_maintainers.pl helps with that.

Yes, agreed, my defense is that with a series that touches lots of files,
the Cc list can get ridiculously long. When I have such a series, most of
the files touched are generally for some mechanical and mostly uninteresting
cleanup. And this change falls in that category, it's simply not that
interesting. Anyway, I maybe trimmed the Cc list too harshly, and will Cc
Lionel for the next iteration.

Cheers,
peda

> -Daniel
> 
>> ---
>>  drivers/gpu/drm/drm_atomic_helper.c | 23 ---
>>  1 file changed, 8 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
>> b/drivers/gpu/drm/drm_atomic_helper.c
>> index 667ec97..5a4a344 100644
>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>> @@ -3769,11 +3769,11 @@ int drm_atomic_helper_legacy_gamma_set(struct 
>> drm_crtc *crtc,
>> struct drm_modeset_acquire_ctx *ctx)
>>  {
>>  struct drm_device *dev = crtc->dev;
>> -struct drm_mode_config *config = >mode_config;
>>  struct drm_atomic_state *state;
>>  struct drm_crtc_state *crtc_state;
>>  struct drm_property_blob *blob = NULL;
>>  struct drm_color_lut *blob_data;
>> +bool replaced = false;
>>  int i, ret = 0;
>>  
>>  state = drm_atomic_state_alloc(crtc->dev);
>> @@ -3805,20 +3805,13 @@ int drm_atomic_helper_legacy_gamma_set(struct 
>> drm_crtc *crtc,
>>  }
>>  
>>  /* Reset DEGAMMA_LUT and CTM properties. */
>> -ret = drm_atomic_crtc_set_property(crtc, crtc_state,
>> -config->degamma_lut_property, 0);
>> -if (ret)
>> -goto fail;
>> -
>> -ret = drm_atomic_crtc_set_property(crtc, crtc_state,
>> -config->ctm_property, 0);
>> -if (ret)
>> -goto fail;
>> -
>> -ret = drm_atomic_crtc_set_property(crtc, crtc_state,
>> -config->gamma_lut_property, blob->base.id);
>> -if (ret)
>> -goto fail;
>> +drm_atomic_replace_property_blob(_state->degamma_lut,
>> + NULL, );
>> +drm_atomic_replace_property_blob(_state->ctm,
>> + NULL, );
>> +drm_atomic_replace_property_blob(_state->gamma_lut,
>> + blob, );
>> +crtc_state->color_mgmt_changed |= replaced;
>>  
>>  ret = drm_atomic_commit(state);
>>  
>> -- 
>> 2.1.4
>>
>> ___
>> dri-devel mailing list
>> dri-de...@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 



Re: [PATCH v4 02/14] drm/atomic-helper: update lut props directly in ..._legacy_gamma_set

2017-07-11 Thread Peter Rosin
On 2017-07-11 10:02, Daniel Vetter wrote:
> On Thu, Jul 06, 2017 at 02:20:36PM +0200, Peter Rosin wrote:
>> Do not waste cycles looking up the property id when we have the
>> actual property already.
>>
>> Signed-off-by: Peter Rosin 
> 
> With the names adjusted per my comments on patch 1 this lgtm. Btw good
> practice is to cc original authors of the code, a combo of git blame and
> scripts/get_maintainers.pl helps with that.

Yes, agreed, my defense is that with a series that touches lots of files,
the Cc list can get ridiculously long. When I have such a series, most of
the files touched are generally for some mechanical and mostly uninteresting
cleanup. And this change falls in that category, it's simply not that
interesting. Anyway, I maybe trimmed the Cc list too harshly, and will Cc
Lionel for the next iteration.

Cheers,
peda

> -Daniel
> 
>> ---
>>  drivers/gpu/drm/drm_atomic_helper.c | 23 ---
>>  1 file changed, 8 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
>> b/drivers/gpu/drm/drm_atomic_helper.c
>> index 667ec97..5a4a344 100644
>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>> @@ -3769,11 +3769,11 @@ int drm_atomic_helper_legacy_gamma_set(struct 
>> drm_crtc *crtc,
>> struct drm_modeset_acquire_ctx *ctx)
>>  {
>>  struct drm_device *dev = crtc->dev;
>> -struct drm_mode_config *config = >mode_config;
>>  struct drm_atomic_state *state;
>>  struct drm_crtc_state *crtc_state;
>>  struct drm_property_blob *blob = NULL;
>>  struct drm_color_lut *blob_data;
>> +bool replaced = false;
>>  int i, ret = 0;
>>  
>>  state = drm_atomic_state_alloc(crtc->dev);
>> @@ -3805,20 +3805,13 @@ int drm_atomic_helper_legacy_gamma_set(struct 
>> drm_crtc *crtc,
>>  }
>>  
>>  /* Reset DEGAMMA_LUT and CTM properties. */
>> -ret = drm_atomic_crtc_set_property(crtc, crtc_state,
>> -config->degamma_lut_property, 0);
>> -if (ret)
>> -goto fail;
>> -
>> -ret = drm_atomic_crtc_set_property(crtc, crtc_state,
>> -config->ctm_property, 0);
>> -if (ret)
>> -goto fail;
>> -
>> -ret = drm_atomic_crtc_set_property(crtc, crtc_state,
>> -config->gamma_lut_property, blob->base.id);
>> -if (ret)
>> -goto fail;
>> +drm_atomic_replace_property_blob(_state->degamma_lut,
>> + NULL, );
>> +drm_atomic_replace_property_blob(_state->ctm,
>> + NULL, );
>> +drm_atomic_replace_property_blob(_state->gamma_lut,
>> + blob, );
>> +crtc_state->color_mgmt_changed |= replaced;
>>  
>>  ret = drm_atomic_commit(state);
>>  
>> -- 
>> 2.1.4
>>
>> ___
>> dri-devel mailing list
>> dri-de...@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 



Re: [PATCH] perf/core: generate overflow signal when samples are dropped (WAS: Re: [REGRESSION] perf/core: PMU interrupts dropped if we entered the kernel in the "skid" region)

2017-07-11 Thread Jin, Yao



On 7/11/2017 5:03 PM, Ingo Molnar wrote:

* Kyle Huey  wrote:


On Wed, Jul 5, 2017 at 10:07 PM, Robert O'Callahan  wrote:

On Tue, Jul 4, 2017 at 3:21 AM, Mark Rutland  wrote:

Should any of those be moved into the "should be dropped" pile?

Why not be conservative and clear every sample you're not sure about?

We'd appreciate a fix sooner rather than later here, since rr is
currently broken on every stable Linux kernel and our attempts to
implement a workaround have failed.

(We have separate "interrupt" and "measure" counters, and I thought we
might work around this regression by programming the "interrupt"
counter to count kernel events as well as user events (interrupting
early is OK), but that caused our (completely separate) "measure"
counter to report off-by-one results (!), which seems to be a
different bug present on a range of older kernels.)

This seems to have stalled out here unfortunately.

Can we get a consensus (from ingo or peterz?) on Mark's question?  Or,
alternatively, can we move the patch at the top of this thread forward
on the stable branches until we do reach an answer to that question?

We've abandoned hope of working around this problem in rr and are
currently broken for all of our users with an up-to-date kernel, so
the situation for us is rather dire at the moment I'm afraid.

Sorry about that - I've queued up a revert for the original commit and will send
the fix to Linus later today. I've added a -stable tag as well so it can be
forwarded to Greg the moment it hits upstream.

We should do the original fix as well, but in a version that does not skip the
sample but zeroes out the RIP and registers (or sets them all to -1LL) - and 
also
covers other possible places where skid-RIP is exposed, such as LBR.

Thanks,

Ingo


Could we provide 2 options in user space when enabling the event sampling?

One option is for the use case like rr debugger which only cares the PMI 
interrupt but doesn't care the skid. The skid samples doesn't need to be 
dropped.


The other option is for the use case which needs the accurate sample 
data. For this option, the skid samples are dropped.


I would suggest to let the user space make the decision to choose which 
option.


Thanks
Jin Yao




Re: [PATCH] perf/core: generate overflow signal when samples are dropped (WAS: Re: [REGRESSION] perf/core: PMU interrupts dropped if we entered the kernel in the "skid" region)

2017-07-11 Thread Jin, Yao



On 7/11/2017 5:03 PM, Ingo Molnar wrote:

* Kyle Huey  wrote:


On Wed, Jul 5, 2017 at 10:07 PM, Robert O'Callahan  wrote:

On Tue, Jul 4, 2017 at 3:21 AM, Mark Rutland  wrote:

Should any of those be moved into the "should be dropped" pile?

Why not be conservative and clear every sample you're not sure about?

We'd appreciate a fix sooner rather than later here, since rr is
currently broken on every stable Linux kernel and our attempts to
implement a workaround have failed.

(We have separate "interrupt" and "measure" counters, and I thought we
might work around this regression by programming the "interrupt"
counter to count kernel events as well as user events (interrupting
early is OK), but that caused our (completely separate) "measure"
counter to report off-by-one results (!), which seems to be a
different bug present on a range of older kernels.)

This seems to have stalled out here unfortunately.

Can we get a consensus (from ingo or peterz?) on Mark's question?  Or,
alternatively, can we move the patch at the top of this thread forward
on the stable branches until we do reach an answer to that question?

We've abandoned hope of working around this problem in rr and are
currently broken for all of our users with an up-to-date kernel, so
the situation for us is rather dire at the moment I'm afraid.

Sorry about that - I've queued up a revert for the original commit and will send
the fix to Linus later today. I've added a -stable tag as well so it can be
forwarded to Greg the moment it hits upstream.

We should do the original fix as well, but in a version that does not skip the
sample but zeroes out the RIP and registers (or sets them all to -1LL) - and 
also
covers other possible places where skid-RIP is exposed, such as LBR.

Thanks,

Ingo


Could we provide 2 options in user space when enabling the event sampling?

One option is for the use case like rr debugger which only cares the PMI 
interrupt but doesn't care the skid. The skid samples doesn't need to be 
dropped.


The other option is for the use case which needs the accurate sample 
data. For this option, the skid samples are dropped.


I would suggest to let the user space make the decision to choose which 
option.


Thanks
Jin Yao




[RESEND PATCH 04/13] idr, radix-tree: Implement copy_preload

2017-07-11 Thread Matthew Wilcox
In the file descriptor table duplication code (called at fork()), we
need to duplicate an IDR.  But we have to do it under a lock (so another
thread doesn't open/close a fd in the middle), and there's no suitable
preload operation for this today.  Adding just idr_copy_preload() isn't
enough as another thread could grow the fd table between starting the
preload and acquiring the lock.  We also need idr_check_preload() to be
called after acquiring the lock.

Signed-off-by: Matthew Wilcox 
---
 include/linux/idr.h | 32 +++
 include/linux/radix-tree.h  |  3 ++
 lib/radix-tree.c| 83 +
 tools/testing/radix-tree/idr-test.c | 24 +
 tools/testing/radix-tree/linux/radix-tree.h |  2 +
 tools/testing/radix-tree/main.c | 38 +
 6 files changed, 182 insertions(+)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index d43cf01..eed1c1a 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -166,6 +166,38 @@ static inline bool idr_is_empty(const struct idr *idr)
 }
 
 /**
+ * idr_copy_preload - preload for idr_copy()
+ * @src: IDR to be copied from
+ * @gfp: Allocation mask to use for preloading
+ *
+ * Preallocates enough memory for a call to idr_copy().  This function
+ * returns with preemption disabled.  Call idr_preload_end() once the
+ * copy has completed.
+ *
+ * Return: -ENOMEM if the memory could not be allocated.
+ */
+static inline int idr_copy_preload(const struct idr *src, gfp_t gfp)
+{
+   return radix_tree_copy_preload(>idr_rt, gfp);
+}
+
+/**
+ * idr_check_preload - Check the preload is still sufficient
+ * @src: IDR to be copied from
+ *
+ * Between the successful allocation of memory and acquiring the lock that
+ * protects @src, the IDR may have expanded.  If this function returns
+ * false, more memory needs to be preallocated.
+ *
+ * Return: true if enough memory remains allocated, false to retry the
+ * preallocation.
+ */
+static inline bool idr_check_preload(const struct idr *src)
+{
+   return radix_tree_check_preload(>idr_rt);
+}
+
+/**
  * idr_preload_end - end preload section started with idr_preload()
  *
  * Each idr_preload() should be matched with an invocation of this
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index f701e0b..f53d004 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -354,6 +354,9 @@ static inline void radix_tree_preload_end(void)
preempt_enable();
 }
 
+int radix_tree_copy_preload(const struct radix_tree_root *, gfp_t);
+bool radix_tree_check_preload(const struct radix_tree_root *);
+
 int radix_tree_split_preload(unsigned old_order, unsigned new_order, gfp_t);
 int radix_tree_split(struct radix_tree_root *, unsigned long index,
unsigned new_order);
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 855ac8e..c1d75224 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -277,6 +277,55 @@ static unsigned long next_index(unsigned long index,
return (index & ~node_maxindex(node)) + (offset << node->shift);
 }
 
+/**
+ * radix_tree_count_nodes - Returns the number of nodes in this tree
+ * @root: radix tree root
+ *
+ * This routine does not examine every node in the tree; it assumes that
+ * all entries in the tree at level 1 are nodes.  It will overestimate
+ * the number of nodes in the tree in the presence of entries of order
+ * RADIX_TREE_MAP_SHIFT or higher.
+ */
+static unsigned long radix_tree_count_nodes(const struct radix_tree_root *root)
+{
+   struct radix_tree_node *node, *child;
+   unsigned long n = 1;
+   void *entry = rcu_dereference_raw(root->rnode);
+   unsigned int offset = 0;
+
+   if (!radix_tree_is_internal_node(entry))
+   return 0;
+
+   node = entry_to_node(entry);
+   if (!node->shift)
+   return n;
+
+   n += node->count;
+   if (node->shift == RADIX_TREE_MAP_SHIFT)
+   return n;
+
+   while (node) {
+   if (offset == RADIX_TREE_MAP_SIZE) {
+   offset = node->offset + 1;
+   node = node->parent;
+   continue;
+   }
+
+   entry = rcu_dereference_raw(node->slots[offset]);
+   offset++;
+   if (!radix_tree_is_internal_node(entry))
+   continue;
+   child = entry_to_node(entry);
+   n += child->count;
+   if (node->shift <= 2 * RADIX_TREE_MAP_SHIFT)
+   continue;
+   offset = 0;
+   node = child;
+   }
+
+   return n;
+}
+
 #ifndef __KERNEL__
 static void dump_node(struct radix_tree_node *node, unsigned long index)
 {
@@ -530,6 +579,40 @@ int radix_tree_maybe_preload(gfp_t gfp_mask)
 }
 EXPORT_SYMBOL(radix_tree_maybe_preload);
 
+/**
+ * radix_tree_copy_preload - preload 

[RESEND PATCH 04/13] idr, radix-tree: Implement copy_preload

2017-07-11 Thread Matthew Wilcox
In the file descriptor table duplication code (called at fork()), we
need to duplicate an IDR.  But we have to do it under a lock (so another
thread doesn't open/close a fd in the middle), and there's no suitable
preload operation for this today.  Adding just idr_copy_preload() isn't
enough as another thread could grow the fd table between starting the
preload and acquiring the lock.  We also need idr_check_preload() to be
called after acquiring the lock.

Signed-off-by: Matthew Wilcox 
---
 include/linux/idr.h | 32 +++
 include/linux/radix-tree.h  |  3 ++
 lib/radix-tree.c| 83 +
 tools/testing/radix-tree/idr-test.c | 24 +
 tools/testing/radix-tree/linux/radix-tree.h |  2 +
 tools/testing/radix-tree/main.c | 38 +
 6 files changed, 182 insertions(+)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index d43cf01..eed1c1a 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -166,6 +166,38 @@ static inline bool idr_is_empty(const struct idr *idr)
 }
 
 /**
+ * idr_copy_preload - preload for idr_copy()
+ * @src: IDR to be copied from
+ * @gfp: Allocation mask to use for preloading
+ *
+ * Preallocates enough memory for a call to idr_copy().  This function
+ * returns with preemption disabled.  Call idr_preload_end() once the
+ * copy has completed.
+ *
+ * Return: -ENOMEM if the memory could not be allocated.
+ */
+static inline int idr_copy_preload(const struct idr *src, gfp_t gfp)
+{
+   return radix_tree_copy_preload(>idr_rt, gfp);
+}
+
+/**
+ * idr_check_preload - Check the preload is still sufficient
+ * @src: IDR to be copied from
+ *
+ * Between the successful allocation of memory and acquiring the lock that
+ * protects @src, the IDR may have expanded.  If this function returns
+ * false, more memory needs to be preallocated.
+ *
+ * Return: true if enough memory remains allocated, false to retry the
+ * preallocation.
+ */
+static inline bool idr_check_preload(const struct idr *src)
+{
+   return radix_tree_check_preload(>idr_rt);
+}
+
+/**
  * idr_preload_end - end preload section started with idr_preload()
  *
  * Each idr_preload() should be matched with an invocation of this
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index f701e0b..f53d004 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -354,6 +354,9 @@ static inline void radix_tree_preload_end(void)
preempt_enable();
 }
 
+int radix_tree_copy_preload(const struct radix_tree_root *, gfp_t);
+bool radix_tree_check_preload(const struct radix_tree_root *);
+
 int radix_tree_split_preload(unsigned old_order, unsigned new_order, gfp_t);
 int radix_tree_split(struct radix_tree_root *, unsigned long index,
unsigned new_order);
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 855ac8e..c1d75224 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -277,6 +277,55 @@ static unsigned long next_index(unsigned long index,
return (index & ~node_maxindex(node)) + (offset << node->shift);
 }
 
+/**
+ * radix_tree_count_nodes - Returns the number of nodes in this tree
+ * @root: radix tree root
+ *
+ * This routine does not examine every node in the tree; it assumes that
+ * all entries in the tree at level 1 are nodes.  It will overestimate
+ * the number of nodes in the tree in the presence of entries of order
+ * RADIX_TREE_MAP_SHIFT or higher.
+ */
+static unsigned long radix_tree_count_nodes(const struct radix_tree_root *root)
+{
+   struct radix_tree_node *node, *child;
+   unsigned long n = 1;
+   void *entry = rcu_dereference_raw(root->rnode);
+   unsigned int offset = 0;
+
+   if (!radix_tree_is_internal_node(entry))
+   return 0;
+
+   node = entry_to_node(entry);
+   if (!node->shift)
+   return n;
+
+   n += node->count;
+   if (node->shift == RADIX_TREE_MAP_SHIFT)
+   return n;
+
+   while (node) {
+   if (offset == RADIX_TREE_MAP_SIZE) {
+   offset = node->offset + 1;
+   node = node->parent;
+   continue;
+   }
+
+   entry = rcu_dereference_raw(node->slots[offset]);
+   offset++;
+   if (!radix_tree_is_internal_node(entry))
+   continue;
+   child = entry_to_node(entry);
+   n += child->count;
+   if (node->shift <= 2 * RADIX_TREE_MAP_SHIFT)
+   continue;
+   offset = 0;
+   node = child;
+   }
+
+   return n;
+}
+
 #ifndef __KERNEL__
 static void dump_node(struct radix_tree_node *node, unsigned long index)
 {
@@ -530,6 +579,40 @@ int radix_tree_maybe_preload(gfp_t gfp_mask)
 }
 EXPORT_SYMBOL(radix_tree_maybe_preload);
 
+/**
+ * radix_tree_copy_preload - preload for radix_tree_copy()
+ 

[RESEND PATCH 03/13] idr, radix-tree: Add get_tag_batch function

2017-07-11 Thread Matthew Wilcox
To implement select() on top of the IDR, we need to be able to get the
tags which represent the open files in bulk.  For this user, it makes
sense to get a batch of BITS_PER_LONG tags at a time, and until another
user shows up that wants something different, let's enforce that instead
of coping with arbitrary offsets.

Signed-off-by: Matthew Wilcox 
---
 include/linux/idr.h |  6 
 include/linux/radix-tree.h  |  2 ++
 lib/radix-tree.c| 55 -
 tools/testing/radix-tree/idr-test.c | 20 ++
 tools/testing/radix-tree/test.h |  2 +-
 5 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index 9f71e63..d43cf01 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -147,6 +147,12 @@ static inline bool idr_tag_get(const struct idr *idr, int 
id, unsigned int tag)
return radix_tree_tag_get(>idr_rt, id, tag);
 }
 
+static inline unsigned long idr_get_tag_batch(const struct idr *idr, int id,
+   unsigned int tag)
+{
+   return radix_tree_get_tag_batch(>idr_rt, id, tag);
+}
+
 static inline void idr_init(struct idr *idr)
 {
INIT_RADIX_TREE(>idr_rt, IDR_RT_MARKER);
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 3e57350..f701e0b 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -339,6 +339,8 @@ void radix_tree_iter_tag_set(struct radix_tree_root *,
const struct radix_tree_iter *iter, unsigned int tag);
 void radix_tree_iter_tag_clear(struct radix_tree_root *,
const struct radix_tree_iter *iter, unsigned int tag);
+unsigned long radix_tree_get_tag_batch(const struct radix_tree_root *,
+   unsigned long index, unsigned int tag);
 unsigned int radix_tree_gang_lookup_tag(const struct radix_tree_root *,
void **results, unsigned long first_index,
unsigned int max_items, unsigned int tag);
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 6723384..855ac8e 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -181,7 +181,8 @@ static inline void root_tag_clear_all(struct 
radix_tree_root *root)
root->gfp_mask &= (1 << ROOT_TAG_SHIFT) - 1;
 }
 
-static inline int root_tag_get(const struct radix_tree_root *root, unsigned 
tag)
+static inline bool root_tag_get(const struct radix_tree_root *root,
+   unsigned tag)
 {
return (__force int)root->gfp_mask & (1 << (tag + ROOT_TAG_SHIFT));
 }
@@ -1571,6 +1572,58 @@ int radix_tree_tag_get(const struct radix_tree_root 
*root,
 }
 EXPORT_SYMBOL(radix_tree_tag_get);
 
+static unsigned long
+__radix_tree_get_tag_batch(const struct radix_tree_root *root,
+   unsigned long index, unsigned int tag)
+{
+   struct radix_tree_node *node;
+   void __rcu **slot = NULL;
+   bool idr_free = is_idr(root) && (tag == IDR_FREE);
+
+   __radix_tree_lookup(root, index, , );
+   if (!slot)
+   return idr_free ? ~0UL : 0;
+   if (!node)
+   return root_tag_get(root, tag) | (idr_free ? ~1UL : 0);
+   if (node->shift)
+   return idr_free ? ~0UL : 0;
+   return node->tags[tag][(index / BITS_PER_LONG) &
+   (RADIX_TREE_TAG_LONGS - 1)];
+}
+
+/**
+ * radix_tree_get_tag_batch() - get a batch of tags
+ * @root: radix tree root
+ * @index: start index of batch
+ * @tag: tag to get
+ *
+ * Get a batch of BITS_PER_LONG tags.  The only values of @index
+ * permitted are multiples of BITS_PER_LONG.
+ *
+ * Return: The tags for the next BITS_PER_LONG indices.
+ */
+unsigned long radix_tree_get_tag_batch(const struct radix_tree_root *root,
+   unsigned long index, unsigned int tag)
+{
+   unsigned long bits = 0;
+   unsigned shift = BITS_PER_LONG > RADIX_TREE_MAP_SIZE ? \
+   RADIX_TREE_MAP_SIZE : 0;
+
+   if (WARN_ON_ONCE(index & (BITS_PER_LONG - 1)))
+   return bits;
+
+   index += BITS_PER_LONG;
+   for (;;) {
+   index -= RADIX_TREE_MAP_SIZE;
+   bits |= __radix_tree_get_tag_batch(root, index, tag);
+   if (!(index & (BITS_PER_LONG - 1)))
+   break;
+   bits <<= shift;
+   }
+
+   return bits;
+}
+
 static inline void __set_iter_shift(struct radix_tree_iter *iter,
unsigned int shift)
 {
diff --git a/tools/testing/radix-tree/idr-test.c 
b/tools/testing/radix-tree/idr-test.c
index 334ce1c..3f9f429 100644
--- a/tools/testing/radix-tree/idr-test.c
+++ b/tools/testing/radix-tree/idr-test.c
@@ -139,6 +139,8 @@ void idr_tag_test(void)
DEFINE_IDR(idr);
struct item *item;
 
+   

[RESEND PATCH 03/13] idr, radix-tree: Add get_tag_batch function

2017-07-11 Thread Matthew Wilcox
To implement select() on top of the IDR, we need to be able to get the
tags which represent the open files in bulk.  For this user, it makes
sense to get a batch of BITS_PER_LONG tags at a time, and until another
user shows up that wants something different, let's enforce that instead
of coping with arbitrary offsets.

Signed-off-by: Matthew Wilcox 
---
 include/linux/idr.h |  6 
 include/linux/radix-tree.h  |  2 ++
 lib/radix-tree.c| 55 -
 tools/testing/radix-tree/idr-test.c | 20 ++
 tools/testing/radix-tree/test.h |  2 +-
 5 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index 9f71e63..d43cf01 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -147,6 +147,12 @@ static inline bool idr_tag_get(const struct idr *idr, int 
id, unsigned int tag)
return radix_tree_tag_get(>idr_rt, id, tag);
 }
 
+static inline unsigned long idr_get_tag_batch(const struct idr *idr, int id,
+   unsigned int tag)
+{
+   return radix_tree_get_tag_batch(>idr_rt, id, tag);
+}
+
 static inline void idr_init(struct idr *idr)
 {
INIT_RADIX_TREE(>idr_rt, IDR_RT_MARKER);
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 3e57350..f701e0b 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -339,6 +339,8 @@ void radix_tree_iter_tag_set(struct radix_tree_root *,
const struct radix_tree_iter *iter, unsigned int tag);
 void radix_tree_iter_tag_clear(struct radix_tree_root *,
const struct radix_tree_iter *iter, unsigned int tag);
+unsigned long radix_tree_get_tag_batch(const struct radix_tree_root *,
+   unsigned long index, unsigned int tag);
 unsigned int radix_tree_gang_lookup_tag(const struct radix_tree_root *,
void **results, unsigned long first_index,
unsigned int max_items, unsigned int tag);
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 6723384..855ac8e 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -181,7 +181,8 @@ static inline void root_tag_clear_all(struct 
radix_tree_root *root)
root->gfp_mask &= (1 << ROOT_TAG_SHIFT) - 1;
 }
 
-static inline int root_tag_get(const struct radix_tree_root *root, unsigned 
tag)
+static inline bool root_tag_get(const struct radix_tree_root *root,
+   unsigned tag)
 {
return (__force int)root->gfp_mask & (1 << (tag + ROOT_TAG_SHIFT));
 }
@@ -1571,6 +1572,58 @@ int radix_tree_tag_get(const struct radix_tree_root 
*root,
 }
 EXPORT_SYMBOL(radix_tree_tag_get);
 
+static unsigned long
+__radix_tree_get_tag_batch(const struct radix_tree_root *root,
+   unsigned long index, unsigned int tag)
+{
+   struct radix_tree_node *node;
+   void __rcu **slot = NULL;
+   bool idr_free = is_idr(root) && (tag == IDR_FREE);
+
+   __radix_tree_lookup(root, index, , );
+   if (!slot)
+   return idr_free ? ~0UL : 0;
+   if (!node)
+   return root_tag_get(root, tag) | (idr_free ? ~1UL : 0);
+   if (node->shift)
+   return idr_free ? ~0UL : 0;
+   return node->tags[tag][(index / BITS_PER_LONG) &
+   (RADIX_TREE_TAG_LONGS - 1)];
+}
+
+/**
+ * radix_tree_get_tag_batch() - get a batch of tags
+ * @root: radix tree root
+ * @index: start index of batch
+ * @tag: tag to get
+ *
+ * Get a batch of BITS_PER_LONG tags.  The only values of @index
+ * permitted are multiples of BITS_PER_LONG.
+ *
+ * Return: The tags for the next BITS_PER_LONG indices.
+ */
+unsigned long radix_tree_get_tag_batch(const struct radix_tree_root *root,
+   unsigned long index, unsigned int tag)
+{
+   unsigned long bits = 0;
+   unsigned shift = BITS_PER_LONG > RADIX_TREE_MAP_SIZE ? \
+   RADIX_TREE_MAP_SIZE : 0;
+
+   if (WARN_ON_ONCE(index & (BITS_PER_LONG - 1)))
+   return bits;
+
+   index += BITS_PER_LONG;
+   for (;;) {
+   index -= RADIX_TREE_MAP_SIZE;
+   bits |= __radix_tree_get_tag_batch(root, index, tag);
+   if (!(index & (BITS_PER_LONG - 1)))
+   break;
+   bits <<= shift;
+   }
+
+   return bits;
+}
+
 static inline void __set_iter_shift(struct radix_tree_iter *iter,
unsigned int shift)
 {
diff --git a/tools/testing/radix-tree/idr-test.c 
b/tools/testing/radix-tree/idr-test.c
index 334ce1c..3f9f429 100644
--- a/tools/testing/radix-tree/idr-test.c
+++ b/tools/testing/radix-tree/idr-test.c
@@ -139,6 +139,8 @@ void idr_tag_test(void)
DEFINE_IDR(idr);
struct item *item;
 
+   assert(idr_get_tag_batch(, 0, 

[RESEND PATCH 02/13] idr: Add idr_for_each_entry_tagged()

2017-07-11 Thread Matthew Wilcox
Add the ability to iterate over tagged entries in the IDR with
idr_get_next_tag() and idr_for_each_entry_tagged().

Signed-off-by: Matthew Wilcox 
---
 include/linux/idr.h | 15 ++-
 lib/idr.c   | 30 +-
 tools/testing/radix-tree/idr-test.c | 18 ++
 tools/testing/radix-tree/test.c |  9 +++--
 tools/testing/radix-tree/test.h |  1 +
 5 files changed, 61 insertions(+), 12 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index 7eb4432..9f71e63 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -84,7 +84,8 @@ static inline void idr_set_cursor(struct idr *idr, unsigned 
int val)
 int idr_alloc_cyclic(struct idr *, void *entry, int start, int end, gfp_t);
 int idr_for_each(const struct idr *,
 int (*fn)(int id, void *p, void *data), void *data);
-void *idr_get_next(struct idr *, int *nextid);
+void *idr_get_next(const struct idr *, int *nextid);
+void *idr_get_next_tag(const struct idr *, int *nextid, unsigned int tag);
 void *idr_replace(struct idr *, void *, int id);
 void idr_destroy(struct idr *);
 
@@ -213,6 +214,18 @@ static inline void *idr_find(const struct idr *idr, int id)
 entry; \
 ++id, (entry) = idr_get_next((idr), &(id)))
 
+/**
+ * idr_for_each_entry_tagged - iterate over IDs with a set tag
+ * @idr: IDR handle
+ * @entry: The pointer stored in @idr
+ * @id: The index of @entry in @idr
+ * @tag: tag to search for
+ */
+#define idr_for_each_entry_tagged(idr, entry, id, tag) \
+   for (id = 0;\
+((entry) = idr_get_next_tag(idr, &(id), (tag))) != NULL;   \
+++id)
+
 /*
  * IDA - IDR based id allocator, use when translation from id to
  * pointer isn't necessary.
diff --git a/lib/idr.c b/lib/idr.c
index b13682b..68e39c3 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -120,7 +120,7 @@ int idr_for_each(const struct idr *idr,
  * to the ID of the found value.  To use in a loop, the value pointed to by
  * nextid must be incremented by the user.
  */
-void *idr_get_next(struct idr *idr, int *nextid)
+void *idr_get_next(const struct idr *idr, int *nextid)
 {
struct radix_tree_iter iter;
void __rcu **slot;
@@ -135,6 +135,34 @@ void *idr_get_next(struct idr *idr, int *nextid)
 EXPORT_SYMBOL(idr_get_next);
 
 /**
+ * idr_get_next_tag - Find next tagged entry
+ * @idr: idr handle
+ * @nextid: Pointer to lowest possible ID to return
+ * @tag: tag to search for
+ *
+ * Returns the next tagged entry in the tree with an ID greater than
+ * or equal to the value pointed to by @nextid.  On exit, @nextid is updated
+ * to the ID of the found value.  To use in a loop, the value pointed to by
+ * nextid must be incremented by the user.  If a NULL entry is tagged, it
+ * will be returned.
+ */
+void *idr_get_next_tag(const struct idr *idr, int *nextid, unsigned int tag)
+{
+   struct radix_tree_iter iter;
+   void __rcu **slot;
+
+   radix_tree_iter_init(, *nextid);
+   slot = radix_tree_next_chunk(>idr_rt, ,
+   RADIX_TREE_ITER_TAGGED | tag);
+   if (!slot)
+   return NULL;
+
+   *nextid = iter.index;
+   return rcu_dereference_raw(*slot);
+}
+EXPORT_UNUSED_SYMBOL(idr_get_next_tag);
+
+/**
  * idr_replace - replace pointer for given id
  * @idr: idr handle
  * @ptr: New pointer to associate with the ID
diff --git a/tools/testing/radix-tree/idr-test.c 
b/tools/testing/radix-tree/idr-test.c
index fd94bee..334ce1c 100644
--- a/tools/testing/radix-tree/idr-test.c
+++ b/tools/testing/radix-tree/idr-test.c
@@ -23,19 +23,15 @@
 
 int item_idr_free(int id, void *p, void *data)
 {
-   struct item *item = p;
-   assert(item->index == id);
-   free(p);
-
+   item_free(p, id);
return 0;
 }
 
 void item_idr_remove(struct idr *idr, int id)
 {
struct item *item = idr_find(idr, id);
-   assert(item->index == id);
idr_remove(idr, id);
-   free(item);
+   item_free(item, id);
 }
 
 void idr_alloc_test(void)
@@ -139,11 +135,13 @@ void idr_null_test(void)
 
 void idr_tag_test(void)
 {
-   unsigned int i;
+   int i;
DEFINE_IDR(idr);
+   struct item *item;
 
for (i = 0; i < 100; i++) {
-   assert(idr_alloc(, NULL, 0, 0, GFP_KERNEL) == i);
+   item = item_create(i, 0);
+   assert(idr_alloc(, item, 0, 0, GFP_KERNEL) == i);
if (i % 7 == 0)
idr_tag_set(, i, IDR_TEST);
}
@@ -157,6 +155,10 @@ void idr_tag_test(void)
assert(idr_tag_get(, i, IDR_TEST) == (i % 14 == 7));
}
 
+   idr_for_each_entry_tagged(, item, i, IDR_TEST) {
+   assert(item->index % 14 == 7);
+   }
+
idr_for_each(, item_idr_free, );

[RESEND PATCH 02/13] idr: Add idr_for_each_entry_tagged()

2017-07-11 Thread Matthew Wilcox
Add the ability to iterate over tagged entries in the IDR with
idr_get_next_tag() and idr_for_each_entry_tagged().

Signed-off-by: Matthew Wilcox 
---
 include/linux/idr.h | 15 ++-
 lib/idr.c   | 30 +-
 tools/testing/radix-tree/idr-test.c | 18 ++
 tools/testing/radix-tree/test.c |  9 +++--
 tools/testing/radix-tree/test.h |  1 +
 5 files changed, 61 insertions(+), 12 deletions(-)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index 7eb4432..9f71e63 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -84,7 +84,8 @@ static inline void idr_set_cursor(struct idr *idr, unsigned 
int val)
 int idr_alloc_cyclic(struct idr *, void *entry, int start, int end, gfp_t);
 int idr_for_each(const struct idr *,
 int (*fn)(int id, void *p, void *data), void *data);
-void *idr_get_next(struct idr *, int *nextid);
+void *idr_get_next(const struct idr *, int *nextid);
+void *idr_get_next_tag(const struct idr *, int *nextid, unsigned int tag);
 void *idr_replace(struct idr *, void *, int id);
 void idr_destroy(struct idr *);
 
@@ -213,6 +214,18 @@ static inline void *idr_find(const struct idr *idr, int id)
 entry; \
 ++id, (entry) = idr_get_next((idr), &(id)))
 
+/**
+ * idr_for_each_entry_tagged - iterate over IDs with a set tag
+ * @idr: IDR handle
+ * @entry: The pointer stored in @idr
+ * @id: The index of @entry in @idr
+ * @tag: tag to search for
+ */
+#define idr_for_each_entry_tagged(idr, entry, id, tag) \
+   for (id = 0;\
+((entry) = idr_get_next_tag(idr, &(id), (tag))) != NULL;   \
+++id)
+
 /*
  * IDA - IDR based id allocator, use when translation from id to
  * pointer isn't necessary.
diff --git a/lib/idr.c b/lib/idr.c
index b13682b..68e39c3 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -120,7 +120,7 @@ int idr_for_each(const struct idr *idr,
  * to the ID of the found value.  To use in a loop, the value pointed to by
  * nextid must be incremented by the user.
  */
-void *idr_get_next(struct idr *idr, int *nextid)
+void *idr_get_next(const struct idr *idr, int *nextid)
 {
struct radix_tree_iter iter;
void __rcu **slot;
@@ -135,6 +135,34 @@ void *idr_get_next(struct idr *idr, int *nextid)
 EXPORT_SYMBOL(idr_get_next);
 
 /**
+ * idr_get_next_tag - Find next tagged entry
+ * @idr: idr handle
+ * @nextid: Pointer to lowest possible ID to return
+ * @tag: tag to search for
+ *
+ * Returns the next tagged entry in the tree with an ID greater than
+ * or equal to the value pointed to by @nextid.  On exit, @nextid is updated
+ * to the ID of the found value.  To use in a loop, the value pointed to by
+ * nextid must be incremented by the user.  If a NULL entry is tagged, it
+ * will be returned.
+ */
+void *idr_get_next_tag(const struct idr *idr, int *nextid, unsigned int tag)
+{
+   struct radix_tree_iter iter;
+   void __rcu **slot;
+
+   radix_tree_iter_init(, *nextid);
+   slot = radix_tree_next_chunk(>idr_rt, ,
+   RADIX_TREE_ITER_TAGGED | tag);
+   if (!slot)
+   return NULL;
+
+   *nextid = iter.index;
+   return rcu_dereference_raw(*slot);
+}
+EXPORT_UNUSED_SYMBOL(idr_get_next_tag);
+
+/**
  * idr_replace - replace pointer for given id
  * @idr: idr handle
  * @ptr: New pointer to associate with the ID
diff --git a/tools/testing/radix-tree/idr-test.c 
b/tools/testing/radix-tree/idr-test.c
index fd94bee..334ce1c 100644
--- a/tools/testing/radix-tree/idr-test.c
+++ b/tools/testing/radix-tree/idr-test.c
@@ -23,19 +23,15 @@
 
 int item_idr_free(int id, void *p, void *data)
 {
-   struct item *item = p;
-   assert(item->index == id);
-   free(p);
-
+   item_free(p, id);
return 0;
 }
 
 void item_idr_remove(struct idr *idr, int id)
 {
struct item *item = idr_find(idr, id);
-   assert(item->index == id);
idr_remove(idr, id);
-   free(item);
+   item_free(item, id);
 }
 
 void idr_alloc_test(void)
@@ -139,11 +135,13 @@ void idr_null_test(void)
 
 void idr_tag_test(void)
 {
-   unsigned int i;
+   int i;
DEFINE_IDR(idr);
+   struct item *item;
 
for (i = 0; i < 100; i++) {
-   assert(idr_alloc(, NULL, 0, 0, GFP_KERNEL) == i);
+   item = item_create(i, 0);
+   assert(idr_alloc(, item, 0, 0, GFP_KERNEL) == i);
if (i % 7 == 0)
idr_tag_set(, i, IDR_TEST);
}
@@ -157,6 +155,10 @@ void idr_tag_test(void)
assert(idr_tag_get(, i, IDR_TEST) == (i % 14 == 7));
}
 
+   idr_for_each_entry_tagged(, item, i, IDR_TEST) {
+   assert(item->index % 14 == 7);
+   }
+
idr_for_each(, item_idr_free, );
idr_destroy();
 }
diff 

drivers/usb/typec/ucsi/ucsi.h:331:59: warning: 'struct device' declared inside parameter list

2017-07-11 Thread kbuild test robot
tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   548aa0e3c516d906dae5edb1fc9a1ad2e490120a
commit: c1b0bc2dabfa884dea49c02adaf3cd6b52b33d2f usb: typec: Add support for 
UCSI interface
date:   2 weeks ago
config: x86_64-randconfig-in0-07111558 (attached as .config)
compiler: gcc-4.6 (Debian 4.6.4-7) 4.6.4
reproduce:
git checkout c1b0bc2dabfa884dea49c02adaf3cd6b52b33d2f
# save the attached .config to linux build tree
make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   In file included from drivers/usb/typec/ucsi/trace.h:9:0,
from drivers/usb/typec/ucsi/trace.c:2:
>> drivers/usb/typec/ucsi/ucsi.h:331:59: warning: 'struct device' declared 
>> inside parameter list [enabled by default]
>> drivers/usb/typec/ucsi/ucsi.h:331:59: warning: its scope is only this 
>> definition or declaration, which is probably not what you want [enabled by 
>> default]

vim +331 drivers/usb/typec/ucsi/ucsi.h

   330  
 > 331  struct ucsi *ucsi_register_ppm(struct device *dev, struct ucsi_ppm 
 > *ppm);
   332  void ucsi_unregister_ppm(struct ucsi *ucsi);
   333  void ucsi_notify(struct ucsi *ucsi);
   334  

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


.config.gz
Description: application/gzip


drivers/usb/typec/ucsi/ucsi.h:331:59: warning: 'struct device' declared inside parameter list

2017-07-11 Thread kbuild test robot
tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   548aa0e3c516d906dae5edb1fc9a1ad2e490120a
commit: c1b0bc2dabfa884dea49c02adaf3cd6b52b33d2f usb: typec: Add support for 
UCSI interface
date:   2 weeks ago
config: x86_64-randconfig-in0-07111558 (attached as .config)
compiler: gcc-4.6 (Debian 4.6.4-7) 4.6.4
reproduce:
git checkout c1b0bc2dabfa884dea49c02adaf3cd6b52b33d2f
# save the attached .config to linux build tree
make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   In file included from drivers/usb/typec/ucsi/trace.h:9:0,
from drivers/usb/typec/ucsi/trace.c:2:
>> drivers/usb/typec/ucsi/ucsi.h:331:59: warning: 'struct device' declared 
>> inside parameter list [enabled by default]
>> drivers/usb/typec/ucsi/ucsi.h:331:59: warning: its scope is only this 
>> definition or declaration, which is probably not what you want [enabled by 
>> default]

vim +331 drivers/usb/typec/ucsi/ucsi.h

   330  
 > 331  struct ucsi *ucsi_register_ppm(struct device *dev, struct ucsi_ppm 
 > *ppm);
   332  void ucsi_unregister_ppm(struct ucsi *ucsi);
   333  void ucsi_notify(struct ucsi *ucsi);
   334  

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


.config.gz
Description: application/gzip


Re: [RFC PATCH v1 04/11] sched/idle: make the fast idle path for short idle periods

2017-07-11 Thread Paul E. McKenney
On Mon, Jul 10, 2017 at 09:38:34AM +0800, Aubrey Li wrote:
> From: Aubrey Li 
> 
> The system will enter a fast idle loop if the predicted idle period
> is shorter than the threshold.
> ---
>  kernel/sched/idle.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
> index cf6c11f..16a766c 100644
> --- a/kernel/sched/idle.c
> +++ b/kernel/sched/idle.c
> @@ -280,6 +280,8 @@ static void cpuidle_generic(void)
>   */
>  static void do_idle(void)
>  {
> + unsigned int predicted_idle_us;
> + unsigned int short_idle_threshold = jiffies_to_usecs(1) / 2;
>   /*
>* If the arch has a polling bit, we maintain an invariant:
>*
> @@ -291,7 +293,12 @@ static void do_idle(void)
> 
>   __current_set_polling();
> 
> - cpuidle_generic();
> + predicted_idle_us = cpuidle_predict();
> +
> + if (likely(predicted_idle_us < short_idle_threshold))
> + cpuidle_fast();

What if we get here from nohz_full usermode execution?  In that
case, if I remember correctly, the scheduling-clock interrupt
will still be disabled, and would have to be re-enabled before
we could safely invoke cpuidle_fast().

Or am I missing something here?

Thanx, Paul

> + else
> + cpuidle_generic();
> 
>   __current_clr_polling();
> 
> -- 
> 2.7.4
> 



Re: [RFC PATCH v1 04/11] sched/idle: make the fast idle path for short idle periods

2017-07-11 Thread Paul E. McKenney
On Mon, Jul 10, 2017 at 09:38:34AM +0800, Aubrey Li wrote:
> From: Aubrey Li 
> 
> The system will enter a fast idle loop if the predicted idle period
> is shorter than the threshold.
> ---
>  kernel/sched/idle.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
> index cf6c11f..16a766c 100644
> --- a/kernel/sched/idle.c
> +++ b/kernel/sched/idle.c
> @@ -280,6 +280,8 @@ static void cpuidle_generic(void)
>   */
>  static void do_idle(void)
>  {
> + unsigned int predicted_idle_us;
> + unsigned int short_idle_threshold = jiffies_to_usecs(1) / 2;
>   /*
>* If the arch has a polling bit, we maintain an invariant:
>*
> @@ -291,7 +293,12 @@ static void do_idle(void)
> 
>   __current_set_polling();
> 
> - cpuidle_generic();
> + predicted_idle_us = cpuidle_predict();
> +
> + if (likely(predicted_idle_us < short_idle_threshold))
> + cpuidle_fast();

What if we get here from nohz_full usermode execution?  In that
case, if I remember correctly, the scheduling-clock interrupt
will still be disabled, and would have to be re-enabled before
we could safely invoke cpuidle_fast().

Or am I missing something here?

Thanx, Paul

> + else
> + cpuidle_generic();
> 
>   __current_clr_polling();
> 
> -- 
> 2.7.4
> 



<    6   7   8   9   10   11   12   13   14   15   >