Skip to content

Commit 90cf590

Browse files
committed
At Linux 5.6.6, and it compiles and boots.
1 parent 2418779 commit 90cf590

1 file changed

Lines changed: 65 additions & 14 deletions

File tree

sys/external/bsd/drm2/dist/drm/i915/i915_perf.c

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,20 +3023,75 @@ static int i915_perf_read(struct file *file,
30233023
struct uio *buf,
30243024
kauth_cred_t count, /* XXX dummy */
30253025
int ppos) /* XXX dummy */
3026+
{
3027+
struct i915_perf_stream *stream = file->f_data;
3028+
struct i915_perf *perf = stream->perf;
3029+
int ret;
3030+
size_t offset_delta = 0;
3031+
3032+
/* To ensure it's handled consistently we simply treat all reads of a
3033+
* disabled stream as an error. In particular it might otherwise lead
3034+
* to a deadlock for blocking file descriptors...
3035+
*/
3036+
if (!stream->enabled)
3037+
return -EIO;
3038+
3039+
buf->uio_offset = *offset;
3040+
if (!(file->f_flag & FNONBLOCK))
3041+
{
3042+
/* There's the small chance of false positives from
3043+
* stream->ops->wait_unlocked.
3044+
*
3045+
* E.g. with single context filtering since we only wait until
3046+
* oabuffer has >= 1 report we don't immediately know whether
3047+
* any reports really belong to the current context
3048+
*/
3049+
do {
3050+
ret = stream->ops->wait_unlocked(stream);
3051+
if (ret)
3052+
return ret;
3053+
3054+
mutex_lock(&perf->lock);
3055+
offset_delta=buf->uio_offset;
3056+
ret = stream->ops->read(stream, buf, count, 0);
3057+
offset_delta=buf->uio_offset-offset_delta;
3058+
mutex_unlock(&perf->lock);
3059+
} while (!(*offset) && !ret);
3060+
} else {
3061+
mutex_lock(&perf->lock);
3062+
offset_delta=buf->uio_offset;
3063+
ret = stream->ops->read(stream, buf, count, 0);
3064+
offset_delta=buf->uio_offset-offset_delta;
3065+
mutex_unlock(&perf->lock);
3066+
}
3067+
3068+
/* We allow the poll checking to sometimes report false positive EPOLLIN
3069+
* events where we might actually report EAGAIN on read() if there's
3070+
* not really any data available. In this situation though we don't
3071+
* want to enter a busy loop between poll() reporting a EPOLLIN event
3072+
* and read() returning -EAGAIN. Clearing the oa.pollin state here
3073+
* effectively ensures we back off until the next hrtimer callback
3074+
* before reporting another EPOLLIN event.
3075+
* The exception to this is if ops->read() returned -ENOSPC which means
3076+
* that more OA data is available than could fit in the user provided
3077+
* buffer. In this case we want the next poll() call to not block.
3078+
*/
3079+
if (ret != -ENOSPC)
3080+
stream->pollin = false;
3081+
3082+
/* Possible values for ret are 0, -EFAULT, -ENOSPC, -EIO, ... */
3083+
return (offset_delta) ?: (ret ?: -EAGAIN);
3084+
}
3085+
30263086
#else
30273087
static ssize_t i915_perf_read(struct file *file,
30283088
char __user *buf,
30293089
size_t count,
30303090
loff_t *ppos)
3031-
#endif
30323091
{
3033-
#ifdef __NetBSD__
3034-
struct i915_perf_stream *stream = file->f_data;
3035-
#else
30363092
struct i915_perf_stream *stream = file->private_data;
3037-
#endif
30383093
struct i915_perf *perf = stream->perf;
3039-
size_t offset2 = 0;
3094+
size_t offset = 0;
30403095
int ret;
30413096

30423097
/* To ensure it's handled consistently we simply treat all reads of a
@@ -3046,12 +3101,7 @@ static ssize_t i915_perf_read(struct file *file,
30463101
if (!stream->enabled)
30473102
return -EIO;
30483103

3049-
#ifdef __NetBSD__
3050-
buf->uio_offset = *offset;
3051-
if (!(file->f_flag & FNONBLOCK))
3052-
#else
30533104
if (!(file->f_flags & O_NONBLOCK))
3054-
#endif
30553105
{
30563106
/* There's the small chance of false positives from
30573107
* stream->ops->wait_unlocked.
@@ -3066,12 +3116,12 @@ static ssize_t i915_perf_read(struct file *file,
30663116
return ret;
30673117

30683118
mutex_lock(&perf->lock);
3069-
ret = stream->ops->read(stream, buf, count, &offset2);
3119+
ret = stream->ops->read(stream, buf, count, &offset);
30703120
mutex_unlock(&perf->lock);
30713121
} while (!offset2 && !ret);
30723122
} else {
30733123
mutex_lock(&perf->lock);
3074-
ret = stream->ops->read(stream, buf, count, &offset2);
3124+
ret = stream->ops->read(stream, buf, count, &offset);
30753125
mutex_unlock(&perf->lock);
30763126
}
30773127

@@ -3090,8 +3140,9 @@ static ssize_t i915_perf_read(struct file *file,
30903140
stream->pollin = false;
30913141

30923142
/* Possible values for ret are 0, -EFAULT, -ENOSPC, -EIO, ... */
3093-
return offset2 ?: (ret ?: -EAGAIN);
3143+
return offset ?: (ret ?: -EAGAIN);
30943144
}
3145+
#endif
30953146

30963147
static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer)
30973148
{

0 commit comments

Comments
 (0)