Import of kernel-6.12.0-55.22.1.el10_0
This commit is contained in:
parent
9ef2f6a227
commit
c071e463bc
@ -12,7 +12,7 @@ RHEL_MINOR = 0
|
|||||||
#
|
#
|
||||||
# Use this spot to avoid future merge conflicts.
|
# Use this spot to avoid future merge conflicts.
|
||||||
# Do not trim this comment.
|
# Do not trim this comment.
|
||||||
RHEL_RELEASE = 55.21.1
|
RHEL_RELEASE = 55.22.1
|
||||||
|
|
||||||
#
|
#
|
||||||
# RHEL_REBASE_NUM
|
# RHEL_REBASE_NUM
|
||||||
|
|||||||
@ -1395,6 +1395,11 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
|
|||||||
ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
|
ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Validate message length before proceeding */
|
||||||
|
if (msgs[i].buf[0] == 0 || msgs[i].buf[0] > I2C_SMBUS_BLOCK_MAX)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Set the msg length from first byte */
|
/* Set the msg length from first byte */
|
||||||
msgs[i].len += msgs[i].buf[0];
|
msgs[i].len += msgs[i].buf[0];
|
||||||
dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);
|
dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);
|
||||||
|
|||||||
@ -1579,6 +1579,40 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain,
|
|||||||
uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
|
uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl,
|
||||||
|
struct uvc_fh *new_handle)
|
||||||
|
{
|
||||||
|
lockdep_assert_held(&handle->chain->ctrl_mutex);
|
||||||
|
|
||||||
|
if (new_handle) {
|
||||||
|
if (ctrl->handle)
|
||||||
|
dev_warn_ratelimited(&handle->stream->dev->udev->dev,
|
||||||
|
"UVC non compliance: Setting an async control with a pending operation.");
|
||||||
|
|
||||||
|
if (new_handle == ctrl->handle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ctrl->handle) {
|
||||||
|
WARN_ON(!ctrl->handle->pending_async_ctrls);
|
||||||
|
if (ctrl->handle->pending_async_ctrls)
|
||||||
|
ctrl->handle->pending_async_ctrls--;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl->handle = new_handle;
|
||||||
|
handle->pending_async_ctrls++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cannot clear the handle for a control not owned by us.*/
|
||||||
|
if (WARN_ON(ctrl->handle != handle))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ctrl->handle = NULL;
|
||||||
|
if (WARN_ON(!handle->pending_async_ctrls))
|
||||||
|
return;
|
||||||
|
handle->pending_async_ctrls--;
|
||||||
|
}
|
||||||
|
|
||||||
void uvc_ctrl_status_event(struct uvc_video_chain *chain,
|
void uvc_ctrl_status_event(struct uvc_video_chain *chain,
|
||||||
struct uvc_control *ctrl, const u8 *data)
|
struct uvc_control *ctrl, const u8 *data)
|
||||||
{
|
{
|
||||||
@ -1588,8 +1622,12 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain,
|
|||||||
|
|
||||||
mutex_lock(&chain->ctrl_mutex);
|
mutex_lock(&chain->ctrl_mutex);
|
||||||
|
|
||||||
|
/* Flush the control cache, the data might have changed. */
|
||||||
|
ctrl->loaded = 0;
|
||||||
|
|
||||||
handle = ctrl->handle;
|
handle = ctrl->handle;
|
||||||
ctrl->handle = NULL;
|
if (handle)
|
||||||
|
uvc_ctrl_set_handle(handle, ctrl, NULL);
|
||||||
|
|
||||||
list_for_each_entry(mapping, &ctrl->info.mappings, list) {
|
list_for_each_entry(mapping, &ctrl->info.mappings, list) {
|
||||||
s32 value = __uvc_ctrl_get_value(mapping, data);
|
s32 value = __uvc_ctrl_get_value(mapping, data);
|
||||||
@ -1640,10 +1678,8 @@ bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain,
|
|||||||
struct uvc_device *dev = chain->dev;
|
struct uvc_device *dev = chain->dev;
|
||||||
struct uvc_ctrl_work *w = &dev->async_ctrl;
|
struct uvc_ctrl_work *w = &dev->async_ctrl;
|
||||||
|
|
||||||
if (list_empty(&ctrl->info.mappings)) {
|
if (list_empty(&ctrl->info.mappings))
|
||||||
ctrl->handle = NULL;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
w->data = data;
|
w->data = data;
|
||||||
w->urb = urb;
|
w->urb = urb;
|
||||||
@ -1811,7 +1847,10 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int uvc_ctrl_commit_entity(struct uvc_device *dev,
|
static int uvc_ctrl_commit_entity(struct uvc_device *dev,
|
||||||
struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)
|
struct uvc_fh *handle,
|
||||||
|
struct uvc_entity *entity,
|
||||||
|
int rollback,
|
||||||
|
struct uvc_control **err_ctrl)
|
||||||
{
|
{
|
||||||
struct uvc_control *ctrl;
|
struct uvc_control *ctrl;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -1859,6 +1898,10 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
|
|||||||
*err_ctrl = ctrl;
|
*err_ctrl = ctrl;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rollback && handle &&
|
||||||
|
ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
|
||||||
|
uvc_ctrl_set_handle(handle, ctrl, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1895,8 +1938,8 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
|
|||||||
|
|
||||||
/* Find the control. */
|
/* Find the control. */
|
||||||
list_for_each_entry(entity, &chain->entities, chain) {
|
list_for_each_entry(entity, &chain->entities, chain) {
|
||||||
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
|
ret = uvc_ctrl_commit_entity(chain->dev, handle, entity,
|
||||||
&err_ctrl);
|
rollback, &err_ctrl);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ctrls)
|
if (ctrls)
|
||||||
ctrls->error_idx =
|
ctrls->error_idx =
|
||||||
@ -1941,6 +1984,8 @@ int uvc_ctrl_set(struct uvc_fh *handle,
|
|||||||
s32 max;
|
s32 max;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
lockdep_assert_held(&chain->ctrl_mutex);
|
||||||
|
|
||||||
if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0)
|
if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
@ -2046,9 +2091,6 @@ int uvc_ctrl_set(struct uvc_fh *handle,
|
|||||||
mapping->set(mapping, value,
|
mapping->set(mapping, value,
|
||||||
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
|
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
|
||||||
|
|
||||||
if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
|
|
||||||
ctrl->handle = handle;
|
|
||||||
|
|
||||||
ctrl->dirty = 1;
|
ctrl->dirty = 1;
|
||||||
ctrl->modified = 1;
|
ctrl->modified = 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2377,7 +2419,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev)
|
|||||||
ctrl->dirty = 1;
|
ctrl->dirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);
|
ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2770,6 +2812,26 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uvc_ctrl_cleanup_fh(struct uvc_fh *handle)
|
||||||
|
{
|
||||||
|
struct uvc_entity *entity;
|
||||||
|
|
||||||
|
guard(mutex)(&handle->chain->ctrl_mutex);
|
||||||
|
|
||||||
|
if (!handle->pending_async_ctrls)
|
||||||
|
return;
|
||||||
|
|
||||||
|
list_for_each_entry(entity, &handle->chain->dev->entities, list) {
|
||||||
|
for (unsigned int i = 0; i < entity->ncontrols; ++i) {
|
||||||
|
if (entity->controls[i].handle != handle)
|
||||||
|
continue;
|
||||||
|
uvc_ctrl_set_handle(handle, &entity->controls[i], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN_ON(handle->pending_async_ctrls);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cleanup device controls.
|
* Cleanup device controls.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
unsigned int uvc_clock_param = CLOCK_MONOTONIC;
|
unsigned int uvc_clock_param = CLOCK_MONOTONIC;
|
||||||
unsigned int uvc_hw_timestamps_param;
|
unsigned int uvc_hw_timestamps_param;
|
||||||
unsigned int uvc_no_drop_param;
|
unsigned int uvc_no_drop_param = 1;
|
||||||
static unsigned int uvc_quirks_param = -1;
|
static unsigned int uvc_quirks_param = -1;
|
||||||
unsigned int uvc_dbg_param;
|
unsigned int uvc_dbg_param;
|
||||||
unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
|
unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
|
||||||
@ -1949,7 +1949,7 @@ int uvc_register_video_device(struct uvc_device *dev,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Initialize the video buffers queue. */
|
/* Initialize the video buffers queue. */
|
||||||
ret = uvc_queue_init(queue, type, !uvc_no_drop_param);
|
ret = uvc_queue_init(queue, type);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -2387,8 +2387,25 @@ module_param_call(clock, uvc_clock_param_set, uvc_clock_param_get,
|
|||||||
MODULE_PARM_DESC(clock, "Video buffers timestamp clock");
|
MODULE_PARM_DESC(clock, "Video buffers timestamp clock");
|
||||||
module_param_named(hwtimestamps, uvc_hw_timestamps_param, uint, 0644);
|
module_param_named(hwtimestamps, uvc_hw_timestamps_param, uint, 0644);
|
||||||
MODULE_PARM_DESC(hwtimestamps, "Use hardware timestamps");
|
MODULE_PARM_DESC(hwtimestamps, "Use hardware timestamps");
|
||||||
module_param_named(nodrop, uvc_no_drop_param, uint, 0644);
|
|
||||||
|
static int param_set_nodrop(const char *val, const struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
pr_warn_once("uvcvideo: "
|
||||||
|
DEPRECATED
|
||||||
|
"nodrop parameter will be eventually removed.\n");
|
||||||
|
return param_set_bool(val, kp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct kernel_param_ops param_ops_nodrop = {
|
||||||
|
.set = param_set_nodrop,
|
||||||
|
.get = param_get_uint,
|
||||||
|
};
|
||||||
|
|
||||||
|
param_check_uint(nodrop, &uvc_no_drop_param);
|
||||||
|
module_param_cb(nodrop, ¶m_ops_nodrop, &uvc_no_drop_param, 0644);
|
||||||
|
__MODULE_PARM_TYPE(nodrop, "uint");
|
||||||
MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
|
MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
|
||||||
|
|
||||||
module_param_named(quirks, uvc_quirks_param, uint, 0644);
|
module_param_named(quirks, uvc_quirks_param, uint, 0644);
|
||||||
MODULE_PARM_DESC(quirks, "Forced device quirks");
|
MODULE_PARM_DESC(quirks, "Forced device quirks");
|
||||||
module_param_named(trace, uvc_dbg_param, uint, 0644);
|
module_param_named(trace, uvc_dbg_param, uint, 0644);
|
||||||
|
|||||||
@ -212,8 +212,7 @@ static const struct vb2_ops uvc_meta_queue_qops = {
|
|||||||
.stop_streaming = uvc_stop_streaming,
|
.stop_streaming = uvc_stop_streaming,
|
||||||
};
|
};
|
||||||
|
|
||||||
int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
|
int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
|
||||||
int drop_corrupted)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -243,7 +242,6 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
|
|||||||
mutex_init(&queue->mutex);
|
mutex_init(&queue->mutex);
|
||||||
spin_lock_init(&queue->irqlock);
|
spin_lock_init(&queue->irqlock);
|
||||||
INIT_LIST_HEAD(&queue->irqqueue);
|
INIT_LIST_HEAD(&queue->irqqueue);
|
||||||
queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -476,14 +474,15 @@ static void uvc_queue_buffer_complete(struct kref *ref)
|
|||||||
struct vb2_buffer *vb = &buf->buf.vb2_buf;
|
struct vb2_buffer *vb = &buf->buf.vb2_buf;
|
||||||
struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
|
struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
|
||||||
|
|
||||||
if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) {
|
if (buf->error && !uvc_no_drop_param) {
|
||||||
uvc_queue_buffer_requeue(queue, buf);
|
uvc_queue_buffer_requeue(queue, buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
|
buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
|
||||||
vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
|
vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
|
||||||
vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
|
vb2_buffer_done(&buf->buf.vb2_buf, buf->error ? VB2_BUF_STATE_ERROR :
|
||||||
|
VB2_BUF_STATE_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -269,6 +269,7 @@ int uvc_status_init(struct uvc_device *dev)
|
|||||||
dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
|
dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||||
if (!dev->int_urb) {
|
if (!dev->int_urb) {
|
||||||
kfree(dev->status);
|
kfree(dev->status);
|
||||||
|
dev->status = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -659,6 +659,8 @@ static int uvc_v4l2_release(struct file *file)
|
|||||||
|
|
||||||
uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
|
uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
|
||||||
|
|
||||||
|
uvc_ctrl_cleanup_fh(handle);
|
||||||
|
|
||||||
/* Only free resources if this is a privileged handle. */
|
/* Only free resources if this is a privileged handle. */
|
||||||
if (uvc_has_privileges(handle))
|
if (uvc_has_privileges(handle))
|
||||||
uvc_queue_release(&stream->queue);
|
uvc_queue_release(&stream->queue);
|
||||||
|
|||||||
@ -316,7 +316,6 @@ struct uvc_buffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define UVC_QUEUE_DISCONNECTED (1 << 0)
|
#define UVC_QUEUE_DISCONNECTED (1 << 0)
|
||||||
#define UVC_QUEUE_DROP_CORRUPTED (1 << 1)
|
|
||||||
|
|
||||||
struct uvc_video_queue {
|
struct uvc_video_queue {
|
||||||
struct vb2_queue queue;
|
struct vb2_queue queue;
|
||||||
@ -337,7 +336,11 @@ struct uvc_video_chain {
|
|||||||
struct uvc_entity *processing; /* Processing unit */
|
struct uvc_entity *processing; /* Processing unit */
|
||||||
struct uvc_entity *selector; /* Selector unit */
|
struct uvc_entity *selector; /* Selector unit */
|
||||||
|
|
||||||
struct mutex ctrl_mutex; /* Protects ctrl.info */
|
struct mutex ctrl_mutex; /*
|
||||||
|
* Protects ctrl.info,
|
||||||
|
* ctrl.handle and
|
||||||
|
* uvc_fh.pending_async_ctrls
|
||||||
|
*/
|
||||||
|
|
||||||
struct v4l2_prio_state prio; /* V4L2 priority state */
|
struct v4l2_prio_state prio; /* V4L2 priority state */
|
||||||
u32 caps; /* V4L2 chain-wide caps */
|
u32 caps; /* V4L2 chain-wide caps */
|
||||||
@ -612,6 +615,7 @@ struct uvc_fh {
|
|||||||
struct uvc_video_chain *chain;
|
struct uvc_video_chain *chain;
|
||||||
struct uvc_streaming *stream;
|
struct uvc_streaming *stream;
|
||||||
enum uvc_handle_state state;
|
enum uvc_handle_state state;
|
||||||
|
unsigned int pending_async_ctrls;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uvc_driver {
|
struct uvc_driver {
|
||||||
@ -674,8 +678,7 @@ extern struct uvc_driver uvc_driver;
|
|||||||
struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
|
struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
|
||||||
|
|
||||||
/* Video buffers queue management. */
|
/* Video buffers queue management. */
|
||||||
int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
|
int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type);
|
||||||
int drop_corrupted);
|
|
||||||
void uvc_queue_release(struct uvc_video_queue *queue);
|
void uvc_queue_release(struct uvc_video_queue *queue);
|
||||||
int uvc_request_buffers(struct uvc_video_queue *queue,
|
int uvc_request_buffers(struct uvc_video_queue *queue,
|
||||||
struct v4l2_requestbuffers *rb);
|
struct v4l2_requestbuffers *rb);
|
||||||
@ -795,6 +798,8 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
|
|||||||
int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
|
int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
|
||||||
struct uvc_xu_control_query *xqry);
|
struct uvc_xu_control_query *xqry);
|
||||||
|
|
||||||
|
void uvc_ctrl_cleanup_fh(struct uvc_fh *handle);
|
||||||
|
|
||||||
/* Utility functions */
|
/* Utility functions */
|
||||||
struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
|
struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
|
||||||
u8 epaddr);
|
u8 epaddr);
|
||||||
|
|||||||
@ -1197,7 +1197,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||||||
|
|
||||||
if (tlv_len != sizeof(*fseq_ver))
|
if (tlv_len != sizeof(*fseq_ver))
|
||||||
goto invalid_tlv_len;
|
goto invalid_tlv_len;
|
||||||
IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %s\n",
|
IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n",
|
||||||
fseq_ver->version);
|
fseq_ver->version);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -302,11 +302,17 @@ static struct airq_info *new_airq_info(int index)
|
|||||||
static unsigned long *get_airq_indicator(struct virtqueue *vqs[], int nvqs,
|
static unsigned long *get_airq_indicator(struct virtqueue *vqs[], int nvqs,
|
||||||
u64 *first, void **airq_info)
|
u64 *first, void **airq_info)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j, queue_idx, highest_queue_idx = -1;
|
||||||
struct airq_info *info;
|
struct airq_info *info;
|
||||||
unsigned long *indicator_addr = NULL;
|
unsigned long *indicator_addr = NULL;
|
||||||
unsigned long bit, flags;
|
unsigned long bit, flags;
|
||||||
|
|
||||||
|
/* Array entries without an actual queue pointer must be ignored. */
|
||||||
|
for (i = 0; i < nvqs; i++) {
|
||||||
|
if (vqs[i])
|
||||||
|
highest_queue_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAX_AIRQ_AREAS && !indicator_addr; i++) {
|
for (i = 0; i < MAX_AIRQ_AREAS && !indicator_addr; i++) {
|
||||||
mutex_lock(&airq_areas_lock);
|
mutex_lock(&airq_areas_lock);
|
||||||
if (!airq_areas[i])
|
if (!airq_areas[i])
|
||||||
@ -316,7 +322,7 @@ static unsigned long *get_airq_indicator(struct virtqueue *vqs[], int nvqs,
|
|||||||
if (!info)
|
if (!info)
|
||||||
return NULL;
|
return NULL;
|
||||||
write_lock_irqsave(&info->lock, flags);
|
write_lock_irqsave(&info->lock, flags);
|
||||||
bit = airq_iv_alloc(info->aiv, nvqs);
|
bit = airq_iv_alloc(info->aiv, highest_queue_idx + 1);
|
||||||
if (bit == -1UL) {
|
if (bit == -1UL) {
|
||||||
/* Not enough vacancies. */
|
/* Not enough vacancies. */
|
||||||
write_unlock_irqrestore(&info->lock, flags);
|
write_unlock_irqrestore(&info->lock, flags);
|
||||||
@ -325,8 +331,10 @@ static unsigned long *get_airq_indicator(struct virtqueue *vqs[], int nvqs,
|
|||||||
*first = bit;
|
*first = bit;
|
||||||
*airq_info = info;
|
*airq_info = info;
|
||||||
indicator_addr = info->aiv->vector;
|
indicator_addr = info->aiv->vector;
|
||||||
for (j = 0; j < nvqs; j++) {
|
for (j = 0, queue_idx = 0; j < nvqs; j++) {
|
||||||
airq_iv_set_ptr(info->aiv, bit + j,
|
if (!vqs[j])
|
||||||
|
continue;
|
||||||
|
airq_iv_set_ptr(info->aiv, bit + queue_idx++,
|
||||||
(unsigned long)vqs[j]);
|
(unsigned long)vqs[j]);
|
||||||
}
|
}
|
||||||
write_unlock_irqrestore(&info->lock, flags);
|
write_unlock_irqrestore(&info->lock, flags);
|
||||||
|
|||||||
@ -2867,6 +2867,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
|||||||
void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
|
void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
|
||||||
pmd_t *pmd, bool freeze, struct folio *folio)
|
pmd_t *pmd, bool freeze, struct folio *folio)
|
||||||
{
|
{
|
||||||
|
bool pmd_migration = is_pmd_migration_entry(*pmd);
|
||||||
|
|
||||||
VM_WARN_ON_ONCE(folio && !folio_test_pmd_mappable(folio));
|
VM_WARN_ON_ONCE(folio && !folio_test_pmd_mappable(folio));
|
||||||
VM_WARN_ON_ONCE(!IS_ALIGNED(address, HPAGE_PMD_SIZE));
|
VM_WARN_ON_ONCE(!IS_ALIGNED(address, HPAGE_PMD_SIZE));
|
||||||
VM_WARN_ON_ONCE(folio && !folio_test_locked(folio));
|
VM_WARN_ON_ONCE(folio && !folio_test_locked(folio));
|
||||||
@ -2877,9 +2879,12 @@ void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
|
|||||||
* require a folio to check the PMD against. Otherwise, there
|
* require a folio to check the PMD against. Otherwise, there
|
||||||
* is a risk of replacing the wrong folio.
|
* is a risk of replacing the wrong folio.
|
||||||
*/
|
*/
|
||||||
if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) ||
|
if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) || pmd_migration) {
|
||||||
is_pmd_migration_entry(*pmd)) {
|
/*
|
||||||
if (folio && folio != pmd_folio(*pmd))
|
* Do not apply pmd_folio() to a migration entry; and folio lock
|
||||||
|
* guarantees that it must be of the wrong folio anyway.
|
||||||
|
*/
|
||||||
|
if (folio && (pmd_migration || folio != pmd_folio(*pmd)))
|
||||||
return;
|
return;
|
||||||
__split_huge_pmd_locked(vma, pmd, address, freeze);
|
__split_huge_pmd_locked(vma, pmd, address, freeze);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1369,7 +1369,8 @@ svc_process_common(struct svc_rqst *rqstp)
|
|||||||
case SVC_OK:
|
case SVC_OK:
|
||||||
break;
|
break;
|
||||||
case SVC_GARBAGE:
|
case SVC_GARBAGE:
|
||||||
goto err_garbage_args;
|
rqstp->rq_auth_stat = rpc_autherr_badcred;
|
||||||
|
goto err_bad_auth;
|
||||||
case SVC_SYSERR:
|
case SVC_SYSERR:
|
||||||
goto err_system_err;
|
goto err_system_err;
|
||||||
case SVC_DENIED:
|
case SVC_DENIED:
|
||||||
@ -1510,14 +1511,6 @@ err_bad_proc:
|
|||||||
*rqstp->rq_accept_statp = rpc_proc_unavail;
|
*rqstp->rq_accept_statp = rpc_proc_unavail;
|
||||||
goto sendit;
|
goto sendit;
|
||||||
|
|
||||||
err_garbage_args:
|
|
||||||
svc_printk(rqstp, "failed to decode RPC header\n");
|
|
||||||
|
|
||||||
if (serv->sv_stats)
|
|
||||||
serv->sv_stats->rpcbadfmt++;
|
|
||||||
*rqstp->rq_accept_statp = rpc_garbage_args;
|
|
||||||
goto sendit;
|
|
||||||
|
|
||||||
err_system_err:
|
err_system_err:
|
||||||
if (serv->sv_stats)
|
if (serv->sv_stats)
|
||||||
serv->sv_stats->rpcbadfmt++;
|
serv->sv_stats->rpcbadfmt++;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user