mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-11 05:17:10 +09:00
Merge tag 'v4.9.280' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroidg12-4.9.y
This is the 4.9.280 stable release Change-Id: Ie6399895549f1a654c91a752251a89a873c659af
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 279
|
||||
SUBLEVEL = 280
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -584,7 +584,7 @@ void
|
||||
smp_send_stop(void)
|
||||
{
|
||||
cpumask_t to_whom;
|
||||
cpumask_copy(&to_whom, cpu_possible_mask);
|
||||
cpumask_copy(&to_whom, cpu_online_mask);
|
||||
cpumask_clear_cpu(smp_processor_id(), &to_whom);
|
||||
#ifdef DEBUG_IPI_MSG
|
||||
if (hard_smp_processor_id() != boot_cpu_id)
|
||||
|
||||
@@ -286,7 +286,7 @@ LDFLAGS += -m $(ld-emul)
|
||||
|
||||
ifdef CONFIG_MIPS
|
||||
CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
|
||||
egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
|
||||
egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \
|
||||
sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g')
|
||||
ifdef CONFIG_64BIT
|
||||
CHECKFLAGS += -m64
|
||||
|
||||
@@ -48,7 +48,8 @@ static struct plat_serial8250_port uart8250_data[] = {
|
||||
.mapbase = 0x1f000900, /* The CBUS UART */
|
||||
.irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2,
|
||||
.uartclk = 3686400, /* Twice the usual clk! */
|
||||
.iotype = UPIO_MEM32,
|
||||
.iotype = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) ?
|
||||
UPIO_MEM32BE : UPIO_MEM32,
|
||||
.flags = CBUS_UART_FLAGS,
|
||||
.regshift = 3,
|
||||
},
|
||||
|
||||
@@ -771,9 +771,10 @@ void x86_pmu_stop(struct perf_event *event, int flags);
|
||||
|
||||
static inline void x86_pmu_disable_event(struct perf_event *event)
|
||||
{
|
||||
u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask);
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
|
||||
wrmsrl(hwc->config_base, hwc->config);
|
||||
wrmsrl(hwc->config_base, hwc->config & ~disable_mask);
|
||||
}
|
||||
|
||||
void x86_pmu_enable_event(struct perf_event *event);
|
||||
|
||||
@@ -50,7 +50,16 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
|
||||
} else {
|
||||
/* read */
|
||||
requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
|
||||
pipe = usb_rcvctrlpipe(d->udev, 0);
|
||||
|
||||
/*
|
||||
* Zero-length transfers must use usb_sndctrlpipe() and
|
||||
* rtl28xxu_identify_state() uses a zero-length i2c read
|
||||
* command to determine the chip type.
|
||||
*/
|
||||
if (req->size)
|
||||
pipe = usb_rcvctrlpipe(d->udev, 0);
|
||||
else
|
||||
pipe = usb_sndctrlpipe(d->udev, 0);
|
||||
}
|
||||
|
||||
ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value,
|
||||
|
||||
@@ -1370,6 +1370,7 @@ static int vb2_start_streaming(struct vb2_queue *q)
|
||||
int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
|
||||
{
|
||||
struct vb2_buffer *vb;
|
||||
enum vb2_buffer_state orig_state;
|
||||
int ret;
|
||||
|
||||
if (q->error) {
|
||||
@@ -1399,6 +1400,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
|
||||
* Add to the queued buffers list, a buffer will stay on it until
|
||||
* dequeued in dqbuf.
|
||||
*/
|
||||
orig_state = vb->state;
|
||||
list_add_tail(&vb->queued_entry, &q->queued_list);
|
||||
q->queued_count++;
|
||||
q->waiting_for_buffers = false;
|
||||
@@ -1429,8 +1431,17 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb)
|
||||
if (q->streaming && !q->start_streaming_called &&
|
||||
q->queued_count >= q->min_buffers_needed) {
|
||||
ret = vb2_start_streaming(q);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
/*
|
||||
* Since vb2_core_qbuf will return with an error,
|
||||
* we should return it to state DEQUEUED since
|
||||
* the error indicates that the buffer wasn't queued.
|
||||
*/
|
||||
list_del(&vb->queued_entry);
|
||||
q->queued_count--;
|
||||
vb->state = orig_state;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
dprintk(1, "qbuf of buffer %d succeeded\n", vb->index);
|
||||
|
||||
@@ -2672,7 +2672,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||
}
|
||||
|
||||
/* Allocated memory for FW statistics */
|
||||
if (bnx2x_alloc_fw_stats_mem(bp))
|
||||
rc = bnx2x_alloc_fw_stats_mem(bp);
|
||||
if (rc)
|
||||
LOAD_ERROR_EXIT(bp, load_error0);
|
||||
|
||||
/* request pf to initialize status blocks */
|
||||
|
||||
@@ -3546,13 +3546,13 @@ fec_drv_remove(struct platform_device *pdev)
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
of_node_put(fep->phy_node);
|
||||
free_netdev(ndev);
|
||||
|
||||
clk_disable_unprepare(fep->clk_ahb);
|
||||
clk_disable_unprepare(fep->clk_ipg);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
free_netdev(ndev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -817,7 +817,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
printk(version);
|
||||
#endif
|
||||
|
||||
i = pci_enable_device(pdev);
|
||||
i = pcim_enable_device(pdev);
|
||||
if (i) return i;
|
||||
|
||||
/* natsemi has a non-standard PM control register
|
||||
@@ -850,7 +850,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
ioaddr = ioremap(iostart, iosize);
|
||||
if (!ioaddr) {
|
||||
i = -ENOMEM;
|
||||
goto err_ioremap;
|
||||
goto err_pci_request_regions;
|
||||
}
|
||||
|
||||
/* Work around the dropped serial bit. */
|
||||
@@ -968,9 +968,6 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
err_register_netdev:
|
||||
iounmap(ioaddr);
|
||||
|
||||
err_ioremap:
|
||||
pci_release_regions(pdev);
|
||||
|
||||
err_pci_request_regions:
|
||||
free_netdev(dev);
|
||||
return i;
|
||||
@@ -3228,7 +3225,6 @@ static void natsemi_remove1(struct pci_dev *pdev)
|
||||
|
||||
NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround);
|
||||
unregister_netdev (dev);
|
||||
pci_release_regions (pdev);
|
||||
iounmap(ioaddr);
|
||||
free_netdev (dev);
|
||||
}
|
||||
|
||||
@@ -3539,13 +3539,13 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev)
|
||||
|
||||
kfree(vdev->vpaths);
|
||||
|
||||
/* we are safe to free it now */
|
||||
free_netdev(dev);
|
||||
|
||||
vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered",
|
||||
buf);
|
||||
vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf,
|
||||
__func__, __LINE__);
|
||||
|
||||
/* we are safe to free it now */
|
||||
free_netdev(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -155,7 +155,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev)
|
||||
"driver lock acquired\n");
|
||||
return 1;
|
||||
}
|
||||
ssleep(1);
|
||||
mdelay(1000);
|
||||
} while (++i < 10);
|
||||
|
||||
netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n");
|
||||
@@ -3287,7 +3287,7 @@ static int ql_adapter_reset(struct ql3_adapter *qdev)
|
||||
if ((value & ISP_CONTROL_SR) == 0)
|
||||
break;
|
||||
|
||||
ssleep(1);
|
||||
mdelay(1000);
|
||||
} while ((--max_wait_time));
|
||||
|
||||
/*
|
||||
@@ -3323,7 +3323,7 @@ static int ql_adapter_reset(struct ql3_adapter *qdev)
|
||||
ispControlStatus);
|
||||
if ((value & ISP_CONTROL_FSR) == 0)
|
||||
break;
|
||||
ssleep(1);
|
||||
mdelay(1000);
|
||||
} while ((--max_wait_time));
|
||||
}
|
||||
if (max_wait_time == 0)
|
||||
|
||||
@@ -1179,9 +1179,8 @@ static int xemaclite_of_probe(struct platform_device *ofdev)
|
||||
}
|
||||
|
||||
dev_info(dev,
|
||||
"Xilinx EmacLite at 0x%08X mapped to 0x%08X, irq=%d\n",
|
||||
(unsigned int __force)ndev->mem_start,
|
||||
(unsigned int __force)lp->base_addr, ndev->irq);
|
||||
"Xilinx EmacLite at 0x%08X mapped to 0x%p, irq=%d\n",
|
||||
(unsigned int __force)ndev->mem_start, lp->base_addr, ndev->irq);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
||||
@@ -285,7 +285,7 @@ static struct channel *ppp_find_channel(struct ppp_net *pn, int unit);
|
||||
static int ppp_connect_channel(struct channel *pch, int unit);
|
||||
static int ppp_disconnect_channel(struct channel *pch);
|
||||
static void ppp_destroy_channel(struct channel *pch);
|
||||
static int unit_get(struct idr *p, void *ptr);
|
||||
static int unit_get(struct idr *p, void *ptr, int min);
|
||||
static int unit_set(struct idr *p, void *ptr, int n);
|
||||
static void unit_put(struct idr *p, int n);
|
||||
static void *unit_find(struct idr *p, int n);
|
||||
@@ -976,9 +976,20 @@ static int ppp_unit_register(struct ppp *ppp, int unit, bool ifname_is_set)
|
||||
mutex_lock(&pn->all_ppp_mutex);
|
||||
|
||||
if (unit < 0) {
|
||||
ret = unit_get(&pn->units_idr, ppp);
|
||||
ret = unit_get(&pn->units_idr, ppp, 0);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
if (!ifname_is_set) {
|
||||
while (1) {
|
||||
snprintf(ppp->dev->name, IFNAMSIZ, "ppp%i", ret);
|
||||
if (!__dev_get_by_name(ppp->ppp_net, ppp->dev->name))
|
||||
break;
|
||||
unit_put(&pn->units_idr, ret);
|
||||
ret = unit_get(&pn->units_idr, ppp, ret + 1);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Caller asked for a specific unit number. Fail with -EEXIST
|
||||
* if unavailable. For backward compatibility, return -EEXIST
|
||||
@@ -3265,9 +3276,9 @@ static int unit_set(struct idr *p, void *ptr, int n)
|
||||
}
|
||||
|
||||
/* get new free unit number and associate pointer with it */
|
||||
static int unit_get(struct idr *p, void *ptr)
|
||||
static int unit_get(struct idr *p, void *ptr, int min)
|
||||
{
|
||||
return idr_alloc(p, ptr, 0, 0, GFP_KERNEL);
|
||||
return idr_alloc(p, ptr, min, 0, GFP_KERNEL);
|
||||
}
|
||||
|
||||
/* put unit number back to a pool */
|
||||
|
||||
@@ -755,12 +755,16 @@ static inline void disable_net_traffic(pegasus_t *pegasus)
|
||||
set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp);
|
||||
}
|
||||
|
||||
static inline void get_interrupt_interval(pegasus_t *pegasus)
|
||||
static inline int get_interrupt_interval(pegasus_t *pegasus)
|
||||
{
|
||||
u16 data;
|
||||
u8 interval;
|
||||
int ret;
|
||||
|
||||
ret = read_eprom_word(pegasus, 4, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
read_eprom_word(pegasus, 4, &data);
|
||||
interval = data >> 8;
|
||||
if (pegasus->usb->speed != USB_SPEED_HIGH) {
|
||||
if (interval < 0x80) {
|
||||
@@ -775,6 +779,8 @@ static inline void get_interrupt_interval(pegasus_t *pegasus)
|
||||
}
|
||||
}
|
||||
pegasus->intr_interval = interval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_carrier(struct net_device *net)
|
||||
@@ -1191,7 +1197,9 @@ static int pegasus_probe(struct usb_interface *intf,
|
||||
| NETIF_MSG_PROBE | NETIF_MSG_LINK);
|
||||
|
||||
pegasus->features = usb_dev_id[dev_index].private;
|
||||
get_interrupt_interval(pegasus);
|
||||
res = get_interrupt_interval(pegasus);
|
||||
if (res)
|
||||
goto out2;
|
||||
if (reset_mac(pegasus)) {
|
||||
dev_err(&intf->dev, "can't reset MAC\n");
|
||||
res = -EIO;
|
||||
|
||||
@@ -105,6 +105,7 @@ static int i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *i
|
||||
for (i = 0;i<socket_count;i++) {
|
||||
sockets[i].card_state = 1; /* 1 = present but empty */
|
||||
sockets[i].io_base = pci_resource_start(dev, 0);
|
||||
sockets[i].dev = dev;
|
||||
sockets[i].socket.features |= SS_CAP_PCCARD;
|
||||
sockets[i].socket.map_size = 0x1000;
|
||||
sockets[i].socket.irq_mask = 0;
|
||||
|
||||
@@ -217,7 +217,7 @@ static unsigned int sr_get_events(struct scsi_device *sdev)
|
||||
else if (med->media_event_code == 2)
|
||||
return DISK_EVENT_MEDIA_CHANGE;
|
||||
else if (med->media_event_code == 3)
|
||||
return DISK_EVENT_EJECT_REQUEST;
|
||||
return DISK_EVENT_MEDIA_CHANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,7 +277,11 @@ static const struct serial8250_config uart_config[] = {
|
||||
/* Uart divisor latch read */
|
||||
static int default_serial_dl_read(struct uart_8250_port *up)
|
||||
{
|
||||
return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
|
||||
/* Assign these in pieces to truncate any bits above 7. */
|
||||
unsigned char dll = serial_in(up, UART_DLL);
|
||||
unsigned char dlm = serial_in(up, UART_DLM);
|
||||
|
||||
return dll | dlm << 8;
|
||||
}
|
||||
|
||||
/* Uart divisor latch write */
|
||||
@@ -1262,9 +1266,11 @@ static void autoconfig(struct uart_8250_port *up)
|
||||
serial_out(up, UART_LCR, 0);
|
||||
|
||||
serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
|
||||
scratch = serial_in(up, UART_IIR) >> 6;
|
||||
|
||||
switch (scratch) {
|
||||
/* Assign this as it is to truncate any bits above 7. */
|
||||
scratch = serial_in(up, UART_IIR);
|
||||
|
||||
switch (scratch >> 6) {
|
||||
case 0:
|
||||
autoconfig_8250(up);
|
||||
break;
|
||||
|
||||
@@ -1342,16 +1342,10 @@ static void usbtmc_interrupt(struct urb *urb)
|
||||
case -EOVERFLOW:
|
||||
dev_err(dev, "overflow with length %d, actual length is %d\n",
|
||||
data->iin_wMaxPacketSize, urb->actual_length);
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
case -EILSEQ:
|
||||
case -ETIME:
|
||||
default:
|
||||
/* urb terminated, clean up */
|
||||
dev_dbg(dev, "urb terminated, status: %d\n", status);
|
||||
return;
|
||||
default:
|
||||
dev_err(dev, "unknown status received: %d\n", status);
|
||||
}
|
||||
exit:
|
||||
rv = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
|
||||
@@ -199,7 +199,11 @@ static void otg_start_hnp_polling(struct otg_fsm *fsm)
|
||||
if (!fsm->host_req_flag)
|
||||
return;
|
||||
|
||||
INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work);
|
||||
if (!fsm->hnp_work_inited) {
|
||||
INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work);
|
||||
fsm->hnp_work_inited = true;
|
||||
}
|
||||
|
||||
schedule_delayed_work(&fsm->hnp_polling_work,
|
||||
msecs_to_jiffies(T_HOST_REQ_POLL));
|
||||
}
|
||||
|
||||
@@ -312,6 +312,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
|
||||
if (pdev->vendor == PCI_VENDOR_ID_STMICRO
|
||||
&& pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST)
|
||||
; /* ConneXT has no sbrn register */
|
||||
else if (pdev->vendor == PCI_VENDOR_ID_HUAWEI
|
||||
&& pdev->device == 0xa239)
|
||||
; /* HUAWEI Kunpeng920 USB EHCI has no sbrn register */
|
||||
else
|
||||
pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
|
||||
|
||||
|
||||
@@ -585,6 +585,7 @@ static struct usb_serial_driver ch341_device = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ch341-uart",
|
||||
},
|
||||
.bulk_in_size = 512,
|
||||
.id_table = id_table,
|
||||
.num_ports = 1,
|
||||
.open = ch341_open,
|
||||
|
||||
@@ -214,6 +214,7 @@ static const struct usb_device_id id_table_combined[] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_AUTO_M3_OP_COM_V2_PID) },
|
||||
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
|
||||
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
|
||||
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
|
||||
|
||||
@@ -158,6 +158,9 @@
|
||||
/* Vardaan Enterprises Serial Interface VEUSB422R3 */
|
||||
#define FTDI_VARDAAN_PID 0xF070
|
||||
|
||||
/* Auto-M3 Ltd. - OP-COM USB V2 - OBD interface Adapter */
|
||||
#define FTDI_AUTO_M3_OP_COM_V2_PID 0x4f50
|
||||
|
||||
/*
|
||||
* Xsens Technologies BV products (http://www.xsens.com).
|
||||
*/
|
||||
|
||||
@@ -1185,6 +1185,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1055, 0xff), /* Telit FN980 (PCIe) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff), /* Telit FD980 */
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
||||
|
||||
@@ -1871,6 +1871,20 @@ void drop_collected_mounts(struct vfsmount *mnt)
|
||||
namespace_unlock();
|
||||
}
|
||||
|
||||
static bool has_locked_children(struct mount *mnt, struct dentry *dentry)
|
||||
{
|
||||
struct mount *child;
|
||||
|
||||
list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
|
||||
if (!is_subdir(child->mnt_mountpoint, dentry))
|
||||
continue;
|
||||
|
||||
if (child->mnt.mnt_flags & MNT_LOCKED)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* clone_private_mount - create a private clone of a path
|
||||
*
|
||||
@@ -1885,16 +1899,27 @@ struct vfsmount *clone_private_mount(struct path *path)
|
||||
struct mount *old_mnt = real_mount(path->mnt);
|
||||
struct mount *new_mnt;
|
||||
|
||||
if (IS_MNT_UNBINDABLE(old_mnt))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
down_read(&namespace_sem);
|
||||
if (IS_MNT_UNBINDABLE(old_mnt))
|
||||
goto invalid;
|
||||
|
||||
if (!check_mnt(old_mnt))
|
||||
goto invalid;
|
||||
|
||||
if (has_locked_children(old_mnt, path->dentry))
|
||||
goto invalid;
|
||||
|
||||
new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
|
||||
up_read(&namespace_sem);
|
||||
|
||||
if (IS_ERR(new_mnt))
|
||||
return ERR_CAST(new_mnt);
|
||||
|
||||
return &new_mnt->mnt;
|
||||
|
||||
invalid:
|
||||
up_read(&namespace_sem);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clone_private_mount);
|
||||
|
||||
@@ -2210,19 +2235,6 @@ static int do_change_type(struct path *path, int flag)
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool has_locked_children(struct mount *mnt, struct dentry *dentry)
|
||||
{
|
||||
struct mount *child;
|
||||
list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
|
||||
if (!is_subdir(child->mnt_mountpoint, dentry))
|
||||
continue;
|
||||
|
||||
if (child->mnt.mnt_flags & MNT_LOCKED)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* do loopback mount.
|
||||
*/
|
||||
|
||||
19
fs/pipe.c
19
fs/pipe.c
@@ -28,6 +28,21 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
* New pipe buffers will be restricted to this size while the user is exceeding
|
||||
* their pipe buffer quota. The general pipe use case needs at least two
|
||||
* buffers: one for data yet to be read, and one for new data. If this is less
|
||||
* than two, then a write to a non-empty pipe may block even if the pipe is not
|
||||
* full. This can occur with GNU make jobserver or similar uses of pipes as
|
||||
* semaphores: multiple processes may be waiting to write tokens back to the
|
||||
* pipe before reading tokens: https://lore.kernel.org/lkml/1628086770.5rn8p04n6j.none@localhost/.
|
||||
*
|
||||
* Users can reduce their pipe buffers with F_SETPIPE_SZ below this at their
|
||||
* own risk, namely: pipe writes to non-full pipes may block until the pipe is
|
||||
* emptied.
|
||||
*/
|
||||
#define PIPE_MIN_DEF_BUFFERS 2
|
||||
|
||||
/*
|
||||
* The max size that a non-root user is allowed to grow the pipe. Can
|
||||
* be set by root in /proc/sys/fs/pipe-max-size
|
||||
@@ -653,8 +668,8 @@ struct pipe_inode_info *alloc_pipe_info(void)
|
||||
user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
|
||||
|
||||
if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) {
|
||||
user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
|
||||
pipe_bufs = 1;
|
||||
user_bufs = account_pipe_buffers(user, pipe_bufs, PIPE_MIN_DEF_BUFFERS);
|
||||
pipe_bufs = PIPE_MIN_DEF_BUFFERS;
|
||||
}
|
||||
|
||||
if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user())
|
||||
|
||||
@@ -386,6 +386,24 @@ void pathrelse(struct treepath *search_path)
|
||||
search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
|
||||
}
|
||||
|
||||
static int has_valid_deh_location(struct buffer_head *bh, struct item_head *ih)
|
||||
{
|
||||
struct reiserfs_de_head *deh;
|
||||
int i;
|
||||
|
||||
deh = B_I_DEH(bh, ih);
|
||||
for (i = 0; i < ih_entry_count(ih); i++) {
|
||||
if (deh_location(&deh[i]) > ih_item_len(ih)) {
|
||||
reiserfs_warning(NULL, "reiserfs-5094",
|
||||
"directory entry location seems wrong %h",
|
||||
&deh[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int is_leaf(char *buf, int blocksize, struct buffer_head *bh)
|
||||
{
|
||||
struct block_head *blkh;
|
||||
@@ -453,11 +471,14 @@ static int is_leaf(char *buf, int blocksize, struct buffer_head *bh)
|
||||
"(second one): %h", ih);
|
||||
return 0;
|
||||
}
|
||||
if (is_direntry_le_ih(ih) && (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE))) {
|
||||
reiserfs_warning(NULL, "reiserfs-5093",
|
||||
"item entry count seems wrong %h",
|
||||
ih);
|
||||
return 0;
|
||||
if (is_direntry_le_ih(ih)) {
|
||||
if (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE)) {
|
||||
reiserfs_warning(NULL, "reiserfs-5093",
|
||||
"item entry count seems wrong %h",
|
||||
ih);
|
||||
return 0;
|
||||
}
|
||||
return has_valid_deh_location(bh, ih);
|
||||
}
|
||||
prev_location = ih_location(ih);
|
||||
}
|
||||
|
||||
@@ -2059,6 +2059,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
|
||||
unlock_new_inode(root_inode);
|
||||
}
|
||||
|
||||
if (!S_ISDIR(root_inode->i_mode) || !inode_get_bytes(root_inode) ||
|
||||
!root_inode->i_size) {
|
||||
SWARN(silent, s, "", "corrupt root inode, run fsck");
|
||||
iput(root_inode);
|
||||
errval = -EUCLEAN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
s->s_root = d_make_root(root_inode);
|
||||
if (!s->s_root)
|
||||
goto error;
|
||||
|
||||
@@ -210,6 +210,7 @@ struct otg_fsm {
|
||||
struct mutex lock;
|
||||
u8 *host_req_flag;
|
||||
struct delayed_work hnp_polling_work;
|
||||
bool hnp_work_inited;
|
||||
bool state_changed;
|
||||
};
|
||||
|
||||
|
||||
@@ -1028,6 +1028,7 @@ struct hci_dev *hci_alloc_dev(void);
|
||||
void hci_free_dev(struct hci_dev *hdev);
|
||||
int hci_register_dev(struct hci_dev *hdev);
|
||||
void hci_unregister_dev(struct hci_dev *hdev);
|
||||
void hci_cleanup_dev(struct hci_dev *hdev);
|
||||
int hci_suspend_dev(struct hci_dev *hdev);
|
||||
int hci_resume_dev(struct hci_dev *hdev);
|
||||
int hci_reset_dev(struct hci_dev *hdev);
|
||||
|
||||
@@ -3146,14 +3146,10 @@ EXPORT_SYMBOL(hci_register_dev);
|
||||
/* Unregister HCI device */
|
||||
void hci_unregister_dev(struct hci_dev *hdev)
|
||||
{
|
||||
int id;
|
||||
|
||||
BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
|
||||
|
||||
hci_dev_set_flag(hdev, HCI_UNREGISTER);
|
||||
|
||||
id = hdev->id;
|
||||
|
||||
write_lock(&hci_dev_list_lock);
|
||||
list_del(&hdev->list);
|
||||
write_unlock(&hci_dev_list_lock);
|
||||
@@ -3182,7 +3178,14 @@ void hci_unregister_dev(struct hci_dev *hdev)
|
||||
}
|
||||
|
||||
device_del(&hdev->dev);
|
||||
/* Actual cleanup is deferred until hci_cleanup_dev(). */
|
||||
hci_dev_put(hdev);
|
||||
}
|
||||
EXPORT_SYMBOL(hci_unregister_dev);
|
||||
|
||||
/* Cleanup HCI device */
|
||||
void hci_cleanup_dev(struct hci_dev *hdev)
|
||||
{
|
||||
debugfs_remove_recursive(hdev->debugfs);
|
||||
kfree_const(hdev->hw_info);
|
||||
kfree_const(hdev->fw_info);
|
||||
@@ -3204,11 +3207,8 @@ void hci_unregister_dev(struct hci_dev *hdev)
|
||||
hci_discovery_filter_clear(hdev);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
hci_dev_put(hdev);
|
||||
|
||||
ida_simple_remove(&hci_index_ida, id);
|
||||
ida_simple_remove(&hci_index_ida, hdev->id);
|
||||
}
|
||||
EXPORT_SYMBOL(hci_unregister_dev);
|
||||
|
||||
/* Suspend HCI device */
|
||||
int hci_suspend_dev(struct hci_dev *hdev)
|
||||
|
||||
@@ -59,6 +59,17 @@ struct hci_pinfo {
|
||||
char comm[TASK_COMM_LEN];
|
||||
};
|
||||
|
||||
static struct hci_dev *hci_hdev_from_sock(struct sock *sk)
|
||||
{
|
||||
struct hci_dev *hdev = hci_pi(sk)->hdev;
|
||||
|
||||
if (!hdev)
|
||||
return ERR_PTR(-EBADFD);
|
||||
if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
|
||||
return ERR_PTR(-EPIPE);
|
||||
return hdev;
|
||||
}
|
||||
|
||||
void hci_sock_set_flag(struct sock *sk, int nr)
|
||||
{
|
||||
set_bit(nr, &hci_pi(sk)->flags);
|
||||
@@ -747,19 +758,13 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event)
|
||||
if (event == HCI_DEV_UNREG) {
|
||||
struct sock *sk;
|
||||
|
||||
/* Detach sockets from device */
|
||||
/* Wake up sockets using this dead device */
|
||||
read_lock(&hci_sk_list.lock);
|
||||
sk_for_each(sk, &hci_sk_list.head) {
|
||||
lock_sock(sk);
|
||||
if (hci_pi(sk)->hdev == hdev) {
|
||||
hci_pi(sk)->hdev = NULL;
|
||||
sk->sk_err = EPIPE;
|
||||
sk->sk_state = BT_OPEN;
|
||||
sk->sk_state_change(sk);
|
||||
|
||||
hci_dev_put(hdev);
|
||||
}
|
||||
release_sock(sk);
|
||||
}
|
||||
read_unlock(&hci_sk_list.lock);
|
||||
}
|
||||
@@ -918,10 +923,10 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
|
||||
static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct hci_dev *hdev = hci_pi(sk)->hdev;
|
||||
struct hci_dev *hdev = hci_hdev_from_sock(sk);
|
||||
|
||||
if (!hdev)
|
||||
return -EBADFD;
|
||||
if (IS_ERR(hdev))
|
||||
return PTR_ERR(hdev);
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
|
||||
return -EBUSY;
|
||||
@@ -1075,6 +1080,18 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
/* Allow detaching from dead device and attaching to alive device, if
|
||||
* the caller wants to re-bind (instead of close) this socket in
|
||||
* response to hci_sock_dev_event(HCI_DEV_UNREG) notification.
|
||||
*/
|
||||
hdev = hci_pi(sk)->hdev;
|
||||
if (hdev && hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
|
||||
hci_pi(sk)->hdev = NULL;
|
||||
sk->sk_state = BT_OPEN;
|
||||
hci_dev_put(hdev);
|
||||
}
|
||||
hdev = NULL;
|
||||
|
||||
if (sk->sk_state == BT_BOUND) {
|
||||
err = -EALREADY;
|
||||
goto done;
|
||||
@@ -1351,9 +1368,9 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
hdev = hci_pi(sk)->hdev;
|
||||
if (!hdev) {
|
||||
err = -EBADFD;
|
||||
hdev = hci_hdev_from_sock(sk);
|
||||
if (IS_ERR(hdev)) {
|
||||
err = PTR_ERR(hdev);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1713,9 +1730,9 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
|
||||
goto done;
|
||||
}
|
||||
|
||||
hdev = hci_pi(sk)->hdev;
|
||||
if (!hdev) {
|
||||
err = -EBADFD;
|
||||
hdev = hci_hdev_from_sock(sk);
|
||||
if (IS_ERR(hdev)) {
|
||||
err = PTR_ERR(hdev);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
|
||||
static void bt_host_release(struct device *dev)
|
||||
{
|
||||
struct hci_dev *hdev = to_hci_dev(dev);
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
|
||||
hci_cleanup_dev(hdev);
|
||||
kfree(hdev);
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ Usage:
|
||||
$ cat /sys/kernel/debug/tracing/trace_pipe > ~/raw_trace_func
|
||||
Wait some times but not too much, the script is a bit slow.
|
||||
Break the pipe (Ctrl + Z)
|
||||
$ scripts/draw_functrace.py < raw_trace_func > draw_functrace
|
||||
$ scripts/tracing/draw_functrace.py < ~/raw_trace_func > draw_functrace
|
||||
Then you have your drawn trace in draw_functrace
|
||||
"""
|
||||
|
||||
@@ -103,10 +103,10 @@ def parseLine(line):
|
||||
line = line.strip()
|
||||
if line.startswith("#"):
|
||||
raise CommentLineException
|
||||
m = re.match("[^]]+?\\] +([0-9.]+): (\\w+) <-(\\w+)", line)
|
||||
m = re.match("[^]]+?\\] +([a-z.]+) +([0-9.]+): (\\w+) <-(\\w+)", line)
|
||||
if m is None:
|
||||
raise BrokenLineException
|
||||
return (m.group(1), m.group(2), m.group(3))
|
||||
return (m.group(2), m.group(3), m.group(4))
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -532,10 +532,11 @@ static int check_and_subscribe_port(struct snd_seq_client *client,
|
||||
return err;
|
||||
}
|
||||
|
||||
static void delete_and_unsubscribe_port(struct snd_seq_client *client,
|
||||
struct snd_seq_client_port *port,
|
||||
struct snd_seq_subscribers *subs,
|
||||
bool is_src, bool ack)
|
||||
/* called with grp->list_mutex held */
|
||||
static void __delete_and_unsubscribe_port(struct snd_seq_client *client,
|
||||
struct snd_seq_client_port *port,
|
||||
struct snd_seq_subscribers *subs,
|
||||
bool is_src, bool ack)
|
||||
{
|
||||
struct snd_seq_port_subs_info *grp;
|
||||
struct list_head *list;
|
||||
@@ -543,7 +544,6 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client,
|
||||
|
||||
grp = is_src ? &port->c_src : &port->c_dest;
|
||||
list = is_src ? &subs->src_list : &subs->dest_list;
|
||||
down_write(&grp->list_mutex);
|
||||
write_lock_irq(&grp->list_lock);
|
||||
empty = list_empty(list);
|
||||
if (!empty)
|
||||
@@ -553,6 +553,18 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client,
|
||||
|
||||
if (!empty)
|
||||
unsubscribe_port(client, port, grp, &subs->info, ack);
|
||||
}
|
||||
|
||||
static void delete_and_unsubscribe_port(struct snd_seq_client *client,
|
||||
struct snd_seq_client_port *port,
|
||||
struct snd_seq_subscribers *subs,
|
||||
bool is_src, bool ack)
|
||||
{
|
||||
struct snd_seq_port_subs_info *grp;
|
||||
|
||||
grp = is_src ? &port->c_src : &port->c_dest;
|
||||
down_write(&grp->list_mutex);
|
||||
__delete_and_unsubscribe_port(client, port, subs, is_src, ack);
|
||||
up_write(&grp->list_mutex);
|
||||
}
|
||||
|
||||
@@ -608,27 +620,30 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector,
|
||||
struct snd_seq_client_port *dest_port,
|
||||
struct snd_seq_port_subscribe *info)
|
||||
{
|
||||
struct snd_seq_port_subs_info *src = &src_port->c_src;
|
||||
struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
|
||||
struct snd_seq_subscribers *subs;
|
||||
int err = -ENOENT;
|
||||
|
||||
down_write(&src->list_mutex);
|
||||
/* always start from deleting the dest port for avoiding concurrent
|
||||
* deletions
|
||||
*/
|
||||
down_write(&dest->list_mutex);
|
||||
/* look for the connection */
|
||||
list_for_each_entry(subs, &src->list_head, src_list) {
|
||||
list_for_each_entry(subs, &dest->list_head, dest_list) {
|
||||
if (match_subs_info(info, &subs->info)) {
|
||||
atomic_dec(&subs->ref_count); /* mark as not ready */
|
||||
__delete_and_unsubscribe_port(dest_client, dest_port,
|
||||
subs, false,
|
||||
connector->number != dest_client->number);
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
up_write(&src->list_mutex);
|
||||
up_write(&dest->list_mutex);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
delete_and_unsubscribe_port(src_client, src_port, subs, true,
|
||||
connector->number != src_client->number);
|
||||
delete_and_unsubscribe_port(dest_client, dest_port, subs, false,
|
||||
connector->number != dest_client->number);
|
||||
kfree(subs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user