Messages in this thread Patch in this message | | | Date | Mon, 23 Nov 2015 10:51:36 +0100 | From | Peter Zijlstra <> | Subject | Re: [PATCH tip/locking/core v10 5/7] locking/pvqspinlock: Collect slowpath lock statistics |
| |
On Mon, Nov 09, 2015 at 07:09:25PM -0500, Waiman Long wrote: > +static ssize_t qstat_read(struct file *file, char __user *user_buf, > + size_t count, loff_t *ppos) > +{ > + char buf[64]; > + int cpu, counter, len; > + u64 stat = 0, kicks = 0; > + > + /* > + * Get the counter ID stored in file->f_inode->i_private > + */ > + if (!file->f_inode) { > + WARN_ON_ONCE(1); > + return -EBADF; > + } > + counter = (long)(file->f_inode->i_private); > + > + if (counter >= qstat_num) > + return -EBADF; > + > + for_each_possible_cpu(cpu) { > + stat += per_cpu(qstats[counter], cpu); > + /* > + * Need to sum additional counter for some of them > + */ > + switch (counter) { > + > + case qstat_pv_latency_kick: > + case qstat_pv_hash_hops: > + kicks += per_cpu(qstats[qstat_pv_kick_unlock], cpu); > + break; > + > + case qstat_pv_latency_wake: > + kicks += per_cpu(qstats[qstat_pv_kick_wake], cpu); > + break; > + } > + } > + > + if (counter == qstat_pv_hash_hops) { > + /* > + * Return a X.XX decimal number > + */ > + len = snprintf(buf, sizeof(buf) - 1, "%llu.%02llu\n", > + stat/kicks, ((stat%kicks)*100 + kicks/2)/kicks); > + } else { > + /* > + * Round to the nearest ns > + */ > + if ((counter == qstat_pv_latency_kick) || > + (counter == qstat_pv_latency_wake)) > + stat = kicks ? (stat + kicks/2)/kicks : 0; > + len = snprintf(buf, sizeof(buf) - 1, "%llu\n", stat); > + } > + > + return simple_read_from_buffer(user_buf, count, ppos, buf, len); > +}
That doesn't work on 32bit.
--- --- a/kernel/locking/qspinlock_stat.h +++ b/kernel/locking/qspinlock_stat.h @@ -127,18 +127,25 @@ static ssize_t qstat_read(struct file *f } if (counter == qstat_pv_hash_hops) { + u64 frac; + + frac = 100ULL * do_div(stat, kicks); + frac = DIV_ROUND_CLOSEST_ULL(frac, kicks); + /* * Return a X.XX decimal number */ - len = snprintf(buf, sizeof(buf) - 1, "%llu.%02llu\n", - stat/kicks, ((stat%kicks)*100 + kicks/2)/kicks); + len = snprintf(buf, sizeof(buf) - 1, "%llu.%02llu\n", stat, frac); } else { /* * Round to the nearest ns */ if ((counter == qstat_pv_latency_kick) || - (counter == qstat_pv_latency_wake)) - stat = kicks ? (stat + kicks/2)/kicks : 0; + (counter == qstat_pv_latency_wake)) { + stat = 0; + if (kicks) + stat = DIV_ROUND_CLOSEST_ULL(stat, kicks); + } len = snprintf(buf, sizeof(buf) - 1, "%llu\n", stat); }
| |