lkml.org 
[lkml]   [2021]   [Aug]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    SubjectRe: Linux 4.19.201
    Date
    diff --git a/Makefile b/Makefile
    index a4ea351c4e5d..80954901733d 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -1,7 +1,7 @@
    # SPDX-License-Identifier: GPL-2.0
    VERSION = 4
    PATCHLEVEL = 19
    -SUBLEVEL = 200
    +SUBLEVEL = 201
    EXTRAVERSION =
    NAME = "People's Front"

    diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
    index 2e0d38cafdd4..885d910bfd9d 100644
    --- a/arch/powerpc/platforms/pseries/setup.c
    +++ b/arch/powerpc/platforms/pseries/setup.c
    @@ -76,7 +76,7 @@
    #include "../../../../drivers/pci/pci.h"

    DEFINE_STATIC_KEY_FALSE(shared_processor);
    -EXPORT_SYMBOL_GPL(shared_processor);
    +EXPORT_SYMBOL(shared_processor);

    int CMO_PrPSP = -1;
    int CMO_SecPSP = -1;
    diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
    index 6e81788a30c1..0eaca7a130c9 100644
    --- a/arch/x86/include/asm/proto.h
    +++ b/arch/x86/include/asm/proto.h
    @@ -4,6 +4,8 @@

    #include <asm/ldt.h>

    +struct task_struct;
    +
    /* misc architecture specific prototypes */

    void syscall_init(void);
    diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
    index bac2ec9b4443..9944b9c7ceee 100644
    --- a/arch/x86/kvm/ioapic.c
    +++ b/arch/x86/kvm/ioapic.c
    @@ -96,7 +96,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
    static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
    {
    ioapic->rtc_status.pending_eoi = 0;
    - bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID);
    + bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID + 1);
    }

    static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
    diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h
    index ea1a4e0297da..283f1f489bca 100644
    --- a/arch/x86/kvm/ioapic.h
    +++ b/arch/x86/kvm/ioapic.h
    @@ -43,13 +43,13 @@ struct kvm_vcpu;

    struct dest_map {
    /* vcpu bitmap where IRQ has been sent */
    - DECLARE_BITMAP(map, KVM_MAX_VCPU_ID);
    + DECLARE_BITMAP(map, KVM_MAX_VCPU_ID + 1);

    /*
    * Vector sent to a given vcpu, only valid when
    * the vcpu's bit in map is set
    */
    - u8 vectors[KVM_MAX_VCPU_ID];
    + u8 vectors[KVM_MAX_VCPU_ID + 1];
    };


    diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
    index ddaf46239e39..472175e37055 100644
    --- a/drivers/net/can/spi/hi311x.c
    +++ b/drivers/net/can/spi/hi311x.c
    @@ -236,7 +236,7 @@ static int hi3110_spi_trans(struct spi_device *spi, int len)
    return ret;
    }

    -static u8 hi3110_cmd(struct spi_device *spi, u8 command)
    +static int hi3110_cmd(struct spi_device *spi, u8 command)
    {
    struct hi3110_priv *priv = spi_get_drvdata(spi);

    diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
    index 16b96f978aae..3957b746107f 100644
    --- a/drivers/net/can/usb/ems_usb.c
    +++ b/drivers/net/can/usb/ems_usb.c
    @@ -267,6 +267,8 @@ struct ems_usb {
    unsigned int free_slots; /* remember number of available slots */

    struct ems_cpc_msg active_params; /* active controller parameters */
    + void *rxbuf[MAX_RX_URBS];
    + dma_addr_t rxbuf_dma[MAX_RX_URBS];
    };

    static void ems_usb_read_interrupt_callback(struct urb *urb)
    @@ -599,6 +601,7 @@ static int ems_usb_start(struct ems_usb *dev)
    for (i = 0; i < MAX_RX_URBS; i++) {
    struct urb *urb = NULL;
    u8 *buf = NULL;
    + dma_addr_t buf_dma;

    /* create a URB, and a buffer for it */
    urb = usb_alloc_urb(0, GFP_KERNEL);
    @@ -608,7 +611,7 @@ static int ems_usb_start(struct ems_usb *dev)
    }

    buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
    - &urb->transfer_dma);
    + &buf_dma);
    if (!buf) {
    netdev_err(netdev, "No memory left for USB buffer\n");
    usb_free_urb(urb);
    @@ -616,6 +619,8 @@ static int ems_usb_start(struct ems_usb *dev)
    break;
    }

    + urb->transfer_dma = buf_dma;
    +
    usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2),
    buf, RX_BUFFER_SIZE,
    ems_usb_read_bulk_callback, dev);
    @@ -631,6 +636,9 @@ static int ems_usb_start(struct ems_usb *dev)
    break;
    }

    + dev->rxbuf[i] = buf;
    + dev->rxbuf_dma[i] = buf_dma;
    +
    /* Drop reference, USB core will take care of freeing it */
    usb_free_urb(urb);
    }
    @@ -696,6 +704,10 @@ static void unlink_all_urbs(struct ems_usb *dev)

    usb_kill_anchored_urbs(&dev->rx_submitted);

    + for (i = 0; i < MAX_RX_URBS; ++i)
    + usb_free_coherent(dev->udev, RX_BUFFER_SIZE,
    + dev->rxbuf[i], dev->rxbuf_dma[i]);
    +
    usb_kill_anchored_urbs(&dev->tx_submitted);
    atomic_set(&dev->active_tx_urbs, 0);

    diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
    index 5820fd5b69b5..e95358269525 100644
    --- a/drivers/net/can/usb/esd_usb2.c
    +++ b/drivers/net/can/usb/esd_usb2.c
    @@ -207,6 +207,8 @@ struct esd_usb2 {
    int net_count;
    u32 version;
    int rxinitdone;
    + void *rxbuf[MAX_RX_URBS];
    + dma_addr_t rxbuf_dma[MAX_RX_URBS];
    };

    struct esd_usb2_net_priv {
    @@ -556,6 +558,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)
    for (i = 0; i < MAX_RX_URBS; i++) {
    struct urb *urb = NULL;
    u8 *buf = NULL;
    + dma_addr_t buf_dma;

    /* create a URB, and a buffer for it */
    urb = usb_alloc_urb(0, GFP_KERNEL);
    @@ -565,7 +568,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)
    }

    buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
    - &urb->transfer_dma);
    + &buf_dma);
    if (!buf) {
    dev_warn(dev->udev->dev.parent,
    "No memory left for USB buffer\n");
    @@ -573,6 +576,8 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)
    goto freeurb;
    }

    + urb->transfer_dma = buf_dma;
    +
    usb_fill_bulk_urb(urb, dev->udev,
    usb_rcvbulkpipe(dev->udev, 1),
    buf, RX_BUFFER_SIZE,
    @@ -585,8 +590,12 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)
    usb_unanchor_urb(urb);
    usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
    urb->transfer_dma);
    + goto freeurb;
    }

    + dev->rxbuf[i] = buf;
    + dev->rxbuf_dma[i] = buf_dma;
    +
    freeurb:
    /* Drop reference, USB core will take care of freeing it */
    usb_free_urb(urb);
    @@ -674,6 +683,11 @@ static void unlink_all_urbs(struct esd_usb2 *dev)
    int i, j;

    usb_kill_anchored_urbs(&dev->rx_submitted);
    +
    + for (i = 0; i < MAX_RX_URBS; ++i)
    + usb_free_coherent(dev->udev, RX_BUFFER_SIZE,
    + dev->rxbuf[i], dev->rxbuf_dma[i]);
    +
    for (i = 0; i < dev->net_count; i++) {
    priv = dev->nets[i];
    if (priv) {
    diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
    index 3215ba69a9e7..097d4a673b05 100644
    --- a/drivers/net/can/usb/mcba_usb.c
    +++ b/drivers/net/can/usb/mcba_usb.c
    @@ -664,6 +664,8 @@ static int mcba_usb_start(struct mcba_priv *priv)
    break;
    }

    + urb->transfer_dma = buf_dma;
    +
    usb_fill_bulk_urb(urb, priv->udev,
    usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN),
    buf, MCBA_USB_RX_BUFF_SIZE,
    diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
    index 3e4416473607..df99354ec12a 100644
    --- a/drivers/net/can/usb/usb_8dev.c
    +++ b/drivers/net/can/usb/usb_8dev.c
    @@ -148,7 +148,8 @@ struct usb_8dev_priv {
    u8 *cmd_msg_buffer;

    struct mutex usb_8dev_cmd_lock;
    -
    + void *rxbuf[MAX_RX_URBS];
    + dma_addr_t rxbuf_dma[MAX_RX_URBS];
    };

    /* tx frame */
    @@ -744,6 +745,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)
    for (i = 0; i < MAX_RX_URBS; i++) {
    struct urb *urb = NULL;
    u8 *buf;
    + dma_addr_t buf_dma;

    /* create a URB, and a buffer for it */
    urb = usb_alloc_urb(0, GFP_KERNEL);
    @@ -753,7 +755,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)
    }

    buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL,
    - &urb->transfer_dma);
    + &buf_dma);
    if (!buf) {
    netdev_err(netdev, "No memory left for USB buffer\n");
    usb_free_urb(urb);
    @@ -761,6 +763,8 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)
    break;
    }

    + urb->transfer_dma = buf_dma;
    +
    usb_fill_bulk_urb(urb, priv->udev,
    usb_rcvbulkpipe(priv->udev,
    USB_8DEV_ENDP_DATA_RX),
    @@ -778,6 +782,9 @@ static int usb_8dev_start(struct usb_8dev_priv *priv)
    break;
    }

    + priv->rxbuf[i] = buf;
    + priv->rxbuf_dma[i] = buf_dma;
    +
    /* Drop reference, USB core will take care of freeing it */
    usb_free_urb(urb);
    }
    @@ -847,6 +854,10 @@ static void unlink_all_urbs(struct usb_8dev_priv *priv)

    usb_kill_anchored_urbs(&priv->rx_submitted);

    + for (i = 0; i < MAX_RX_URBS; ++i)
    + usb_free_coherent(priv->udev, RX_BUFFER_SIZE,
    + priv->rxbuf[i], priv->rxbuf_dma[i]);
    +
    usb_kill_anchored_urbs(&priv->tx_submitted);
    atomic_set(&priv->active_tx_urbs, 0);

    diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c
    index 70cb2d689c2c..79bdd2a79dbd 100644
    --- a/drivers/net/ethernet/dec/tulip/winbond-840.c
    +++ b/drivers/net/ethernet/dec/tulip/winbond-840.c
    @@ -367,7 +367,7 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)
    int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
    void __iomem *ioaddr;

    - i = pci_enable_device(pdev);
    + i = pcim_enable_device(pdev);
    if (i) return i;

    pci_set_master(pdev);
    @@ -389,7 +389,7 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)

    ioaddr = pci_iomap(pdev, TULIP_BAR, netdev_res_size);
    if (!ioaddr)
    - goto err_out_free_res;
    + goto err_out_netdev;

    for (i = 0; i < 3; i++)
    ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(eeprom_read(ioaddr, i));
    @@ -468,8 +468,6 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)

    err_out_cleardev:
    pci_iounmap(pdev, ioaddr);
    -err_out_free_res:
    - pci_release_regions(pdev);
    err_out_netdev:
    free_netdev (dev);
    return -ENODEV;
    @@ -1535,7 +1533,6 @@ static void w840_remove1(struct pci_dev *pdev)
    if (dev) {
    struct netdev_private *np = netdev_priv(dev);
    unregister_netdev(dev);
    - pci_release_regions(pdev);
    pci_iounmap(pdev, np->base_addr);
    free_netdev(dev);
    }
    diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
    index 4c7c1998f358..5242d3dfeb22 100644
    --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
    +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
    @@ -674,7 +674,7 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
    default:
    /* if we got here and link is up something bad is afoot */
    netdev_info(netdev,
    - "WARNING: Link is up but PHY type 0x%x is not recognized.\n",
    + "WARNING: Link is up but PHY type 0x%x is not recognized, or incorrect cable is in use\n",
    hw_link_info->phy_type);
    }

    diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
    index 1b101b526ed3..246734be5177 100644
    --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
    +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
    @@ -4310,11 +4310,10 @@ int i40e_control_wait_tx_q(int seid, struct i40e_pf *pf, int pf_q,
    }

    /**
    - * i40e_vsi_control_tx - Start or stop a VSI's rings
    + * i40e_vsi_enable_tx - Start a VSI's rings
    * @vsi: the VSI being configured
    - * @enable: start or stop the rings
    **/
    -static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
    +static int i40e_vsi_enable_tx(struct i40e_vsi *vsi)
    {
    struct i40e_pf *pf = vsi->back;
    int i, pf_q, ret = 0;
    @@ -4323,7 +4322,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
    for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
    ret = i40e_control_wait_tx_q(vsi->seid, pf,
    pf_q,
    - false /*is xdp*/, enable);
    + false /*is xdp*/, true);
    if (ret)
    break;

    @@ -4332,7 +4331,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)

    ret = i40e_control_wait_tx_q(vsi->seid, pf,
    pf_q + vsi->alloc_queue_pairs,
    - true /*is xdp*/, enable);
    + true /*is xdp*/, true);
    if (ret)
    break;
    }
    @@ -4430,32 +4429,25 @@ int i40e_control_wait_rx_q(struct i40e_pf *pf, int pf_q, bool enable)
    }

    /**
    - * i40e_vsi_control_rx - Start or stop a VSI's rings
    + * i40e_vsi_enable_rx - Start a VSI's rings
    * @vsi: the VSI being configured
    - * @enable: start or stop the rings
    **/
    -static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
    +static int i40e_vsi_enable_rx(struct i40e_vsi *vsi)
    {
    struct i40e_pf *pf = vsi->back;
    int i, pf_q, ret = 0;

    pf_q = vsi->base_queue;
    for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
    - ret = i40e_control_wait_rx_q(pf, pf_q, enable);
    + ret = i40e_control_wait_rx_q(pf, pf_q, true);
    if (ret) {
    dev_info(&pf->pdev->dev,
    - "VSI seid %d Rx ring %d %sable timeout\n",
    - vsi->seid, pf_q, (enable ? "en" : "dis"));
    + "VSI seid %d Rx ring %d enable timeout\n",
    + vsi->seid, pf_q);
    break;
    }
    }

    - /* Due to HW errata, on Rx disable only, the register can indicate done
    - * before it really is. Needs 50ms to be sure
    - */
    - if (!enable)
    - mdelay(50);
    -
    return ret;
    }

    @@ -4468,29 +4460,47 @@ int i40e_vsi_start_rings(struct i40e_vsi *vsi)
    int ret = 0;

    /* do rx first for enable and last for disable */
    - ret = i40e_vsi_control_rx(vsi, true);
    + ret = i40e_vsi_enable_rx(vsi);
    if (ret)
    return ret;
    - ret = i40e_vsi_control_tx(vsi, true);
    + ret = i40e_vsi_enable_tx(vsi);

    return ret;
    }

    +#define I40E_DISABLE_TX_GAP_MSEC 50
    +
    /**
    * i40e_vsi_stop_rings - Stop a VSI's rings
    * @vsi: the VSI being configured
    **/
    void i40e_vsi_stop_rings(struct i40e_vsi *vsi)
    {
    + struct i40e_pf *pf = vsi->back;
    + int pf_q, err, q_end;
    +
    /* When port TX is suspended, don't wait */
    if (test_bit(__I40E_PORT_SUSPENDED, vsi->back->state))
    return i40e_vsi_stop_rings_no_wait(vsi);

    - /* do rx first for enable and last for disable
    - * Ignore return value, we need to shutdown whatever we can
    - */
    - i40e_vsi_control_tx(vsi, false);
    - i40e_vsi_control_rx(vsi, false);
    + q_end = vsi->base_queue + vsi->num_queue_pairs;
    + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++)
    + i40e_pre_tx_queue_cfg(&pf->hw, (u32)pf_q, false);
    +
    + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) {
    + err = i40e_control_wait_rx_q(pf, pf_q, false);
    + if (err)
    + dev_info(&pf->pdev->dev,
    + "VSI seid %d Rx ring %d dissable timeout\n",
    + vsi->seid, pf_q);
    + }
    +
    + msleep(I40E_DISABLE_TX_GAP_MSEC);
    + pf_q = vsi->base_queue;
    + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++)
    + wr32(&pf->hw, I40E_QTX_ENA(pf_q), 0);
    +
    + i40e_vsi_wait_queues_disabled(vsi);
    }

    /**
    @@ -6752,6 +6762,8 @@ static int i40e_validate_mqprio_qopt(struct i40e_vsi *vsi,
    }
    if (vsi->num_queue_pairs <
    (mqprio_qopt->qopt.offset[i] + mqprio_qopt->qopt.count[i])) {
    + dev_err(&vsi->back->pdev->dev,
    + "Failed to create traffic channel, insufficient number of queues.\n");
    return -EINVAL;
    }
    if (sum_max_rate > i40e_get_link_speed(vsi)) {
    diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
    index a0affcb090a0..d9707d47f1e7 100644
    --- a/drivers/net/ethernet/mellanox/mlx4/main.c
    +++ b/drivers/net/ethernet/mellanox/mlx4/main.c
    @@ -3515,6 +3515,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,

    if (!SRIOV_VALID_STATE(dev->flags)) {
    mlx4_err(dev, "Invalid SRIOV state\n");
    + err = -EINVAL;
    goto err_close;
    }
    }
    diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
    index a38a0c86705a..774f0a619a6d 100644
    --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
    +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
    @@ -904,17 +904,19 @@ static int connect_fwd_rules(struct mlx5_core_dev *dev,
    static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table *ft,
    struct fs_prio *prio)
    {
    - struct mlx5_flow_table *next_ft;
    + struct mlx5_flow_table *next_ft, *first_ft;
    int err = 0;

    /* Connect_prev_fts and update_root_ft_create are mutually exclusive */

    - if (list_empty(&prio->node.children)) {
    + first_ft = list_first_entry_or_null(&prio->node.children,
    + struct mlx5_flow_table, node.list);
    + if (!first_ft || first_ft->level > ft->level) {
    err = connect_prev_fts(dev, ft, prio);
    if (err)
    return err;

    - next_ft = find_next_chained_ft(prio);
    + next_ft = first_ft ? first_ft : find_next_chained_ft(prio);
    err = connect_fwd_rules(dev, ft, next_ft);
    if (err)
    return err;
    @@ -1945,7 +1947,7 @@ static int disconnect_flow_table(struct mlx5_flow_table *ft)
    node.list) == ft))
    return 0;

    - next_ft = find_next_chained_ft(prio);
    + next_ft = find_next_ft(ft);
    err = connect_fwd_rules(dev, next_ft, ft);
    if (err)
    return err;
    diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
    index 823873030a21..e1bd9eacee17 100644
    --- a/drivers/net/ethernet/sis/sis900.c
    +++ b/drivers/net/ethernet/sis/sis900.c
    @@ -441,7 +441,7 @@ static int sis900_probe(struct pci_dev *pci_dev,
    #endif

    /* setup various bits in PCI command register */
    - ret = pci_enable_device(pci_dev);
    + ret = pcim_enable_device(pci_dev);
    if(ret) return ret;

    i = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
    @@ -467,7 +467,7 @@ static int sis900_probe(struct pci_dev *pci_dev,
    ioaddr = pci_iomap(pci_dev, 0, 0);
    if (!ioaddr) {
    ret = -ENOMEM;
    - goto err_out_cleardev;
    + goto err_out;
    }

    sis_priv = netdev_priv(net_dev);
    @@ -575,8 +575,6 @@ static int sis900_probe(struct pci_dev *pci_dev,
    sis_priv->tx_ring_dma);
    err_out_unmap:
    pci_iounmap(pci_dev, ioaddr);
    -err_out_cleardev:
    - pci_release_regions(pci_dev);
    err_out:
    free_netdev(net_dev);
    return ret;
    @@ -2421,7 +2419,6 @@ static void sis900_remove(struct pci_dev *pci_dev)
    sis_priv->tx_ring_dma);
    pci_iounmap(pci_dev, sis_priv->ioaddr);
    free_netdev(net_dev);
    - pci_release_regions(pci_dev);
    }

    #ifdef CONFIG_PM
    diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
    index 5894edf79d65..605c4d15b88c 100644
    --- a/drivers/net/ethernet/sun/niu.c
    +++ b/drivers/net/ethernet/sun/niu.c
    @@ -8192,8 +8192,9 @@ static int niu_pci_vpd_fetch(struct niu *np, u32 start)
    err = niu_pci_vpd_scan_props(np, here, end);
    if (err < 0)
    return err;
    + /* ret == 1 is not an error */
    if (err == 1)
    - return -EINVAL;
    + return 0;
    }
    return 0;
    }
    diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
    index 5e8b40630286..1a8fe5bacb19 100644
    --- a/drivers/net/virtio_net.c
    +++ b/drivers/net/virtio_net.c
    @@ -413,9 +413,13 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
    offset += hdr_padded_len;
    p += hdr_padded_len;

    - copy = len;
    - if (copy > skb_tailroom(skb))
    - copy = skb_tailroom(skb);
    + /* Copy all frame if it fits skb->head, otherwise
    + * we let virtio_net_hdr_to_skb() and GRO pull headers as needed.
    + */
    + if (len <= skb_tailroom(skb))
    + copy = len;
    + else
    + copy = ETH_HLEN + metasize;
    skb_put_data(skb, p, copy);

    if (metasize) {
    diff --git a/drivers/nfc/nfcsim.c b/drivers/nfc/nfcsim.c
    index 33449820e754..533e3aa6275c 100644
    --- a/drivers/nfc/nfcsim.c
    +++ b/drivers/nfc/nfcsim.c
    @@ -201,8 +201,7 @@ static void nfcsim_recv_wq(struct work_struct *work)

    if (!IS_ERR(skb))
    dev_kfree_skb(skb);
    -
    - skb = ERR_PTR(-ENODEV);
    + return;
    }

    dev->cb(dev->nfc_digital_dev, dev->arg, skb);
    diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
    index 662711200eeb..5a19f5ee7038 100644
    --- a/fs/btrfs/volumes.c
    +++ b/fs/btrfs/volumes.c
    @@ -995,6 +995,7 @@ void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices, int step)
    if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
    list_del_init(&device->dev_alloc_list);
    clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
    + fs_devices->rw_devices--;
    }
    list_del_init(&device->dev_list);
    fs_devices->num_devices--;
    diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
    index 94df697e2638..6ca4dc57f70b 100644
    --- a/fs/ocfs2/file.c
    +++ b/fs/ocfs2/file.c
    @@ -1537,6 +1537,45 @@ static void ocfs2_truncate_cluster_pages(struct inode *inode, u64 byte_start,
    }
    }

    +/*
    + * zero out partial blocks of one cluster.
    + *
    + * start: file offset where zero starts, will be made upper block aligned.
    + * len: it will be trimmed to the end of current cluster if "start + len"
    + * is bigger than it.
    + */
    +static int ocfs2_zeroout_partial_cluster(struct inode *inode,
    + u64 start, u64 len)
    +{
    + int ret;
    + u64 start_block, end_block, nr_blocks;
    + u64 p_block, offset;
    + u32 cluster, p_cluster, nr_clusters;
    + struct super_block *sb = inode->i_sb;
    + u64 end = ocfs2_align_bytes_to_clusters(sb, start);
    +
    + if (start + len < end)
    + end = start + len;
    +
    + start_block = ocfs2_blocks_for_bytes(sb, start);
    + end_block = ocfs2_blocks_for_bytes(sb, end);
    + nr_blocks = end_block - start_block;
    + if (!nr_blocks)
    + return 0;
    +
    + cluster = ocfs2_bytes_to_clusters(sb, start);
    + ret = ocfs2_get_clusters(inode, cluster, &p_cluster,
    + &nr_clusters, NULL);
    + if (ret)
    + return ret;
    + if (!p_cluster)
    + return 0;
    +
    + offset = start_block - ocfs2_clusters_to_blocks(sb, cluster);
    + p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset;
    + return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS);
    +}
    +
    static int ocfs2_zero_partial_clusters(struct inode *inode,
    u64 start, u64 len)
    {
    @@ -1546,6 +1585,7 @@ static int ocfs2_zero_partial_clusters(struct inode *inode,
    struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
    unsigned int csize = osb->s_clustersize;
    handle_t *handle;
    + loff_t isize = i_size_read(inode);

    /*
    * The "start" and "end" values are NOT necessarily part of
    @@ -1566,6 +1606,26 @@ static int ocfs2_zero_partial_clusters(struct inode *inode,
    if ((start & (csize - 1)) == 0 && (end & (csize - 1)) == 0)
    goto out;

    + /* No page cache for EOF blocks, issue zero out to disk. */
    + if (end > isize) {
    + /*
    + * zeroout eof blocks in last cluster starting from
    + * "isize" even "start" > "isize" because it is
    + * complicated to zeroout just at "start" as "start"
    + * may be not aligned with block size, buffer write
    + * would be required to do that, but out of eof buffer
    + * write is not supported.
    + */
    + ret = ocfs2_zeroout_partial_cluster(inode, isize,
    + end - isize);
    + if (ret) {
    + mlog_errno(ret);
    + goto out;
    + }
    + if (start >= isize)
    + goto out;
    + end = isize;
    + }
    handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
    if (IS_ERR(handle)) {
    ret = PTR_ERR(handle);
    @@ -1863,45 +1923,6 @@ int ocfs2_remove_inode_range(struct inode *inode,
    return ret;
    }

    -/*
    - * zero out partial blocks of one cluster.
    - *
    - * start: file offset where zero starts, will be made upper block aligned.
    - * len: it will be trimmed to the end of current cluster if "start + len"
    - * is bigger than it.
    - */
    -static int ocfs2_zeroout_partial_cluster(struct inode *inode,
    - u64 start, u64 len)
    -{
    - int ret;
    - u64 start_block, end_block, nr_blocks;
    - u64 p_block, offset;
    - u32 cluster, p_cluster, nr_clusters;
    - struct super_block *sb = inode->i_sb;
    - u64 end = ocfs2_align_bytes_to_clusters(sb, start);
    -
    - if (start + len < end)
    - end = start + len;
    -
    - start_block = ocfs2_blocks_for_bytes(sb, start);
    - end_block = ocfs2_blocks_for_bytes(sb, end);
    - nr_blocks = end_block - start_block;
    - if (!nr_blocks)
    - return 0;
    -
    - cluster = ocfs2_bytes_to_clusters(sb, start);
    - ret = ocfs2_get_clusters(inode, cluster, &p_cluster,
    - &nr_clusters, NULL);
    - if (ret)
    - return ret;
    - if (!p_cluster)
    - return 0;
    -
    - offset = start_block - ocfs2_clusters_to_blocks(sb, cluster);
    - p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset;
    - return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS);
    -}
    -
    /*
    * Parts of this function taken from xfs_change_file_space()
    */
    @@ -1943,7 +1964,6 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
    goto out_inode_unlock;
    }

    - orig_isize = i_size_read(inode);
    switch (sr->l_whence) {
    case 0: /*SEEK_SET*/
    break;
    @@ -1951,7 +1971,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
    sr->l_start += f_pos;
    break;
    case 2: /*SEEK_END*/
    - sr->l_start += orig_isize;
    + sr->l_start += i_size_read(inode);
    break;
    default:
    ret = -EINVAL;
    @@ -2006,6 +2026,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
    ret = -EINVAL;
    }

    + orig_isize = i_size_read(inode);
    /* zeroout eof blocks in the cluster. */
    if (!ret && change_size && orig_isize < size) {
    ret = ocfs2_zeroout_partial_cluster(inode, orig_isize,
    diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
    index 06176ef2a842..5f2e6451ece5 100644
    --- a/include/linux/skbuff.h
    +++ b/include/linux/skbuff.h
    @@ -2788,6 +2788,15 @@ static inline void skb_propagate_pfmemalloc(struct page *page,
    skb->pfmemalloc = true;
    }

    +/**
    + * skb_frag_off() - Returns the offset of a skb fragment
    + * @frag: the paged fragment
    + */
    +static inline unsigned int skb_frag_off(const skb_frag_t *frag)
    +{
    + return frag->page_offset;
    +}
    +
    /**
    * skb_frag_page - retrieve the page referred to by a paged fragment
    * @frag: the paged fragment
    diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
    index a1829139ff4a..8f48264f5dab 100644
    --- a/include/linux/virtio_net.h
    +++ b/include/linux/virtio_net.h
    @@ -65,14 +65,18 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
    skb_reset_mac_header(skb);

    if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
    - u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
    - u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
    + u32 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
    + u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
    + u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16));
    +
    + if (!pskb_may_pull(skb, needed))
    + return -EINVAL;

    if (!skb_partial_csum_set(skb, start, off))
    return -EINVAL;

    p_off = skb_transport_offset(skb) + thlen;
    - if (p_off > skb_headlen(skb))
    + if (!pskb_may_pull(skb, p_off))
    return -EINVAL;
    } else {
    /* gso packets without NEEDS_CSUM do not set transport_offset.
    @@ -102,14 +106,14 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
    }

    p_off = keys.control.thoff + thlen;
    - if (p_off > skb_headlen(skb) ||
    + if (!pskb_may_pull(skb, p_off) ||
    keys.basic.ip_proto != ip_proto)
    return -EINVAL;

    skb_set_transport_header(skb, keys.control.thoff);
    } else if (gso_type) {
    p_off = thlen;
    - if (p_off > skb_headlen(skb))
    + if (!pskb_may_pull(skb, p_off))
    return -EINVAL;
    }
    }
    diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h
    index c0f0a13ed818..49aa79c7b278 100644
    --- a/include/net/llc_pdu.h
    +++ b/include/net/llc_pdu.h
    @@ -15,9 +15,11 @@
    #include <linux/if_ether.h>

    /* Lengths of frame formats */
    -#define LLC_PDU_LEN_I 4 /* header and 2 control bytes */
    -#define LLC_PDU_LEN_S 4
    -#define LLC_PDU_LEN_U 3 /* header and 1 control byte */
    +#define LLC_PDU_LEN_I 4 /* header and 2 control bytes */
    +#define LLC_PDU_LEN_S 4
    +#define LLC_PDU_LEN_U 3 /* header and 1 control byte */
    +/* header and 1 control byte and XID info */
    +#define LLC_PDU_LEN_U_XID (LLC_PDU_LEN_U + sizeof(struct llc_xid_info))
    /* Known SAP addresses */
    #define LLC_GLOBAL_SAP 0xFF
    #define LLC_NULL_SAP 0x00 /* not network-layer visible */
    @@ -50,9 +52,10 @@
    #define LLC_PDU_TYPE_U_MASK 0x03 /* 8-bit control field */
    #define LLC_PDU_TYPE_MASK 0x03

    -#define LLC_PDU_TYPE_I 0 /* first bit */
    -#define LLC_PDU_TYPE_S 1 /* first two bits */
    -#define LLC_PDU_TYPE_U 3 /* first two bits */
    +#define LLC_PDU_TYPE_I 0 /* first bit */
    +#define LLC_PDU_TYPE_S 1 /* first two bits */
    +#define LLC_PDU_TYPE_U 3 /* first two bits */
    +#define LLC_PDU_TYPE_U_XID 4 /* private type for detecting XID commands */

    #define LLC_PDU_TYPE_IS_I(pdu) \
    ((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 1 : 0)
    @@ -230,9 +233,18 @@ static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
    static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,
    u8 ssap, u8 dsap, u8 cr)
    {
    - const int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
    + int hlen = 4; /* default value for I and S types */
    struct llc_pdu_un *pdu;

    + switch (type) {
    + case LLC_PDU_TYPE_U:
    + hlen = 3;
    + break;
    + case LLC_PDU_TYPE_U_XID:
    + hlen = 6;
    + break;
    + }
    +
    skb_push(skb, hlen);
    skb_reset_network_header(skb);
    pdu = llc_pdu_un_hdr(skb);
    @@ -374,7 +386,10 @@ static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
    xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */
    xid_info->type = svcs_supported;
    xid_info->rw = rx_window << 1; /* size of receive window */
    - skb_put(skb, sizeof(struct llc_xid_info));
    +
    + /* no need to push/put since llc_pdu_header_init() has already
    + * pushed 3 + 3 bytes
    + */
    }

    /**
    diff --git a/net/can/raw.c b/net/can/raw.c
    index 296a11a922e0..d0fb5a57c66d 100644
    --- a/net/can/raw.c
    +++ b/net/can/raw.c
    @@ -549,10 +549,18 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
    return -EFAULT;
    }

    + rtnl_lock();
    lock_sock(sk);

    - if (ro->bound && ro->ifindex)
    + if (ro->bound && ro->ifindex) {
    dev = dev_get_by_index(sock_net(sk), ro->ifindex);
    + if (!dev) {
    + if (count > 1)
    + kfree(filter);
    + err = -ENODEV;
    + goto out_fil;
    + }
    + }

    if (ro->bound) {
    /* (try to) register the new filters */
    @@ -591,6 +599,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
    dev_put(dev);

    release_sock(sk);
    + rtnl_unlock();

    break;

    @@ -603,10 +612,16 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,

    err_mask &= CAN_ERR_MASK;

    + rtnl_lock();
    lock_sock(sk);

    - if (ro->bound && ro->ifindex)
    + if (ro->bound && ro->ifindex) {
    dev = dev_get_by_index(sock_net(sk), ro->ifindex);
    + if (!dev) {
    + err = -ENODEV;
    + goto out_err;
    + }
    + }

    /* remove current error mask */
    if (ro->bound) {
    @@ -630,6 +645,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
    dev_put(dev);

    release_sock(sk);
    + rtnl_unlock();

    break;

    diff --git a/net/core/dev.c b/net/core/dev.c
    index 722ae0b57f3f..a6798117bb1a 100644
    --- a/net/core/dev.c
    +++ b/net/core/dev.c
    @@ -5400,7 +5400,8 @@ static void skb_gro_reset_offset(struct sk_buff *skb)

    if (skb_mac_header(skb) == skb_tail_pointer(skb) &&
    pinfo->nr_frags &&
    - !PageHighMem(skb_frag_page(frag0))) {
    + !PageHighMem(skb_frag_page(frag0)) &&
    + (!NET_IP_ALIGN || !(skb_frag_off(frag0) & 3))) {
    NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
    NAPI_GRO_CB(skb)->frag0_len = min_t(unsigned int,
    skb_frag_size(frag0),
    diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
    index bcba579e292f..89a3dc7d5d40 100644
    --- a/net/llc/af_llc.c
    +++ b/net/llc/af_llc.c
    @@ -98,8 +98,16 @@ static inline u8 llc_ui_header_len(struct sock *sk, struct sockaddr_llc *addr)
    {
    u8 rc = LLC_PDU_LEN_U;

    - if (addr->sllc_test || addr->sllc_xid)
    + if (addr->sllc_test)
    rc = LLC_PDU_LEN_U;
    + else if (addr->sllc_xid)
    + /* We need to expand header to sizeof(struct llc_xid_info)
    + * since llc_pdu_init_as_xid_cmd() sets 4,5,6 bytes of LLC header
    + * as XID PDU. In llc_ui_sendmsg() we reserved header size and then
    + * filled all other space with user data. If we won't reserve this
    + * bytes, llc_pdu_init_as_xid_cmd() will overwrite user data
    + */
    + rc = LLC_PDU_LEN_U_XID;
    else if (sk->sk_type == SOCK_STREAM)
    rc = LLC_PDU_LEN_I;
    return rc;
    diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
    index 7ae4cc684d3a..9fa3342c7a82 100644
    --- a/net/llc/llc_s_ac.c
    +++ b/net/llc/llc_s_ac.c
    @@ -79,7 +79,7 @@ int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
    struct llc_sap_state_ev *ev = llc_sap_ev(skb);
    int rc;

    - llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
    + llc_pdu_header_init(skb, LLC_PDU_TYPE_U_XID, ev->saddr.lsap,
    ev->daddr.lsap, LLC_PDU_CMD);
    llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
    rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
    diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
    index 1dceda3c0e75..c5590d36b775 100644
    --- a/net/netfilter/nf_conntrack_core.c
    +++ b/net/netfilter/nf_conntrack_core.c
    @@ -630,8 +630,13 @@ bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)
    return false;

    tstamp = nf_conn_tstamp_find(ct);
    - if (tstamp && tstamp->stop == 0)
    + if (tstamp) {
    + s32 timeout = ct->timeout - nfct_time_stamp;
    +
    tstamp->stop = ktime_get_real_ns();
    + if (timeout < 0)
    + tstamp->stop -= jiffies_to_nsecs(-timeout);
    + }

    if (nf_conntrack_event_report(IPCT_DESTROY, ct,
    portid, report) < 0) {
    diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
    index 3e82a7d0df2a..2c3d7ff6f58a 100644
    --- a/net/netfilter/nft_nat.c
    +++ b/net/netfilter/nft_nat.c
    @@ -153,7 +153,9 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
    alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip6);
    break;
    default:
    - return -EAFNOSUPPORT;
    + if (tb[NFTA_NAT_REG_ADDR_MIN])
    + return -EAFNOSUPPORT;
    + break;
    }
    priv->family = family;

    diff --git a/net/sctp/input.c b/net/sctp/input.c
    index 203aaefd8d04..23c4f14bec25 100644
    --- a/net/sctp/input.c
    +++ b/net/sctp/input.c
    @@ -1132,7 +1132,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
    if (unlikely(!af))
    return NULL;

    - if (af->from_addr_param(&paddr, param, peer_port, 0))
    + if (!af->from_addr_param(&paddr, param, peer_port, 0))
    return NULL;

    return __sctp_lookup_association(net, laddr, &paddr, transportp);
    diff --git a/net/tipc/socket.c b/net/tipc/socket.c
    index 3c41fb8edc5f..6aead6deaa6c 100644
    --- a/net/tipc/socket.c
    +++ b/net/tipc/socket.c
    @@ -2440,7 +2440,7 @@ static int tipc_listen(struct socket *sock, int len)
    static int tipc_wait_for_accept(struct socket *sock, long timeo)
    {
    struct sock *sk = sock->sk;
    - DEFINE_WAIT(wait);
    + DEFINE_WAIT_FUNC(wait, woken_wake_function);
    int err;

    /* True wake-one mechanism for incoming connections: only
    @@ -2449,12 +2449,12 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo)
    * anymore, the common case will execute the loop only once.
    */
    for (;;) {
    - prepare_to_wait_exclusive(sk_sleep(sk), &wait,
    - TASK_INTERRUPTIBLE);
    if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
    + add_wait_queue(sk_sleep(sk), &wait);
    release_sock(sk);
    - timeo = schedule_timeout(timeo);
    + timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
    lock_sock(sk);
    + remove_wait_queue(sk_sleep(sk), &wait);
    }
    err = 0;
    if (!skb_queue_empty(&sk->sk_receive_queue))
    @@ -2466,7 +2466,6 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo)
    if (signal_pending(current))
    break;
    }
    - finish_wait(sk_sleep(sk), &wait);
    return err;
    }

    diff --git a/net/wireless/scan.c b/net/wireless/scan.c
    index 67b2747ad9ef..d871349036a5 100644
    --- a/net/wireless/scan.c
    +++ b/net/wireless/scan.c
    @@ -1029,16 +1029,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
    * be grouped with this beacon for updates ...
    */
    if (!cfg80211_combine_bsses(rdev, new)) {
    - kfree(new);
    + bss_ref_put(rdev, new);
    goto drop;
    }
    }

    if (rdev->bss_entries >= bss_entries_limit &&
    !cfg80211_bss_expire_oldest(rdev)) {
    - if (!list_empty(&new->hidden_list))
    - list_del(&new->hidden_list);
    - kfree(new);
    + bss_ref_put(rdev, new);
    goto drop;
    }

    diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
    index 603086692290..769d11575a7b 100644
    --- a/tools/perf/util/map.c
    +++ b/tools/perf/util/map.c
    @@ -209,8 +209,6 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
    if (!(prot & PROT_EXEC))
    dso__set_loaded(dso);
    }
    -
    - nsinfo__put(dso->nsinfo);
    dso->nsinfo = nsi;
    dso__put(dso);
    }
    \
     
     \ /
      Last update: 2021-08-04 14:24    [W:5.956 / U:0.220 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site