Merge cc16f7402a ("ipv6: Align behavior across nexthops during path selection") into android16-6.12-lts
Steps on the way to 6.12.24 Resolves merge conflicts in: tools/testing/selftests/futex/functional/futex_wait_wouldblock.c Change-Id: I1c4fca16617ff6fbec20c586a416ac00e5837931 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -23,6 +23,8 @@
|
|||||||
#include <linux/serial_core.h>
|
#include <linux/serial_core.h>
|
||||||
#include <linux/pgtable.h>
|
#include <linux/pgtable.h>
|
||||||
|
|
||||||
|
#include <xen/xen.h>
|
||||||
|
|
||||||
#include <asm/e820/api.h>
|
#include <asm/e820/api.h>
|
||||||
#include <asm/irqdomain.h>
|
#include <asm/irqdomain.h>
|
||||||
#include <asm/pci_x86.h>
|
#include <asm/pci_x86.h>
|
||||||
@@ -1730,6 +1732,15 @@ int __init acpi_mps_check(void)
|
|||||||
{
|
{
|
||||||
#if defined(CONFIG_X86_LOCAL_APIC) && !defined(CONFIG_X86_MPPARSE)
|
#if defined(CONFIG_X86_LOCAL_APIC) && !defined(CONFIG_X86_MPPARSE)
|
||||||
/* mptable code is not built-in*/
|
/* mptable code is not built-in*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Xen disables ACPI in PV DomU guests but it still emulates APIC and
|
||||||
|
* supports SMP. Returning early here ensures that APIC is not disabled
|
||||||
|
* unnecessarily and the guest is not limited to a single vCPU.
|
||||||
|
*/
|
||||||
|
if (xen_pv_domain() && !xen_initial_domain())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (acpi_disabled || acpi_noirq) {
|
if (acpi_disabled || acpi_noirq) {
|
||||||
pr_warn("MPS support code is not built-in, using acpi=off or acpi=noirq or pci=noacpi may have problem\n");
|
pr_warn("MPS support code is not built-in, using acpi=off or acpi=noirq or pci=noacpi may have problem\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -223,10 +223,16 @@ static int pxa_ata_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, cmd_res->start,
|
ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, cmd_res->start,
|
||||||
resource_size(cmd_res));
|
resource_size(cmd_res));
|
||||||
|
if (!ap->ioaddr.cmd_addr)
|
||||||
|
return -ENOMEM;
|
||||||
ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
|
ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
|
||||||
resource_size(ctl_res));
|
resource_size(ctl_res));
|
||||||
|
if (!ap->ioaddr.ctl_addr)
|
||||||
|
return -ENOMEM;
|
||||||
ap->ioaddr.bmdma_addr = devm_ioremap(&pdev->dev, dma_res->start,
|
ap->ioaddr.bmdma_addr = devm_ioremap(&pdev->dev, dma_res->start,
|
||||||
resource_size(dma_res));
|
resource_size(dma_res));
|
||||||
|
if (!ap->ioaddr.bmdma_addr)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adjust register offsets
|
* Adjust register offsets
|
||||||
|
|||||||
+10
-3
@@ -1117,9 +1117,14 @@ static int pdc20621_prog_dimm0(struct ata_host *host)
|
|||||||
mmio += PDC_CHIP0_OFS;
|
mmio += PDC_CHIP0_OFS;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(pdc_i2c_read_data); i++)
|
for (i = 0; i < ARRAY_SIZE(pdc_i2c_read_data); i++)
|
||||||
pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
|
if (!pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||||
pdc_i2c_read_data[i].reg,
|
pdc_i2c_read_data[i].reg,
|
||||||
&spd0[pdc_i2c_read_data[i].ofs]);
|
&spd0[pdc_i2c_read_data[i].ofs])) {
|
||||||
|
dev_err(host->dev,
|
||||||
|
"Failed in i2c read at index %d: device=%#x, reg=%#x\n",
|
||||||
|
i, PDC_DIMM0_SPD_DEV_ADDRESS, pdc_i2c_read_data[i].reg);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4);
|
data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4);
|
||||||
data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) |
|
data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) |
|
||||||
@@ -1284,6 +1289,8 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host)
|
|||||||
|
|
||||||
/* Programming DIMM0 Module Control Register (index_CID0:80h) */
|
/* Programming DIMM0 Module Control Register (index_CID0:80h) */
|
||||||
size = pdc20621_prog_dimm0(host);
|
size = pdc20621_prog_dimm0(host);
|
||||||
|
if (size < 0)
|
||||||
|
return size;
|
||||||
dev_dbg(host->dev, "Local DIMM Size = %dMB\n", size);
|
dev_dbg(host->dev, "Local DIMM Size = %dMB\n", size);
|
||||||
|
|
||||||
/* Programming DIMM Module Global Control Register (index_CID0:88h) */
|
/* Programming DIMM Module Global Control Register (index_CID0:88h) */
|
||||||
|
|||||||
+67
-23
@@ -681,22 +681,44 @@ static int ublk_max_cmd_buf_size(void)
|
|||||||
return __ublk_queue_cmd_buf_size(UBLK_MAX_QUEUE_DEPTH);
|
return __ublk_queue_cmd_buf_size(UBLK_MAX_QUEUE_DEPTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ublk_queue_can_use_recovery_reissue(
|
/*
|
||||||
struct ublk_queue *ubq)
|
* Should I/O outstanding to the ublk server when it exits be reissued?
|
||||||
|
* If not, outstanding I/O will get errors.
|
||||||
|
*/
|
||||||
|
static inline bool ublk_nosrv_should_reissue_outstanding(struct ublk_device *ub)
|
||||||
{
|
{
|
||||||
return (ubq->flags & UBLK_F_USER_RECOVERY) &&
|
return (ub->dev_info.flags & UBLK_F_USER_RECOVERY) &&
|
||||||
(ubq->flags & UBLK_F_USER_RECOVERY_REISSUE);
|
(ub->dev_info.flags & UBLK_F_USER_RECOVERY_REISSUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ublk_queue_can_use_recovery(
|
/*
|
||||||
struct ublk_queue *ubq)
|
* Should I/O issued while there is no ublk server queue? If not, I/O
|
||||||
|
* issued while there is no ublk server will get errors.
|
||||||
|
*/
|
||||||
|
static inline bool ublk_nosrv_dev_should_queue_io(struct ublk_device *ub)
|
||||||
|
{
|
||||||
|
return ub->dev_info.flags & UBLK_F_USER_RECOVERY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same as ublk_nosrv_dev_should_queue_io, but uses a queue-local copy
|
||||||
|
* of the device flags for smaller cache footprint - better for fast
|
||||||
|
* paths.
|
||||||
|
*/
|
||||||
|
static inline bool ublk_nosrv_should_queue_io(struct ublk_queue *ubq)
|
||||||
{
|
{
|
||||||
return ubq->flags & UBLK_F_USER_RECOVERY;
|
return ubq->flags & UBLK_F_USER_RECOVERY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ublk_can_use_recovery(struct ublk_device *ub)
|
/*
|
||||||
|
* Should ublk devices be stopped (i.e. no recovery possible) when the
|
||||||
|
* ublk server exits? If not, devices can be used again by a future
|
||||||
|
* incarnation of a ublk server via the start_recovery/end_recovery
|
||||||
|
* commands.
|
||||||
|
*/
|
||||||
|
static inline bool ublk_nosrv_should_stop_dev(struct ublk_device *ub)
|
||||||
{
|
{
|
||||||
return ub->dev_info.flags & UBLK_F_USER_RECOVERY;
|
return !(ub->dev_info.flags & UBLK_F_USER_RECOVERY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ublk_free_disk(struct gendisk *disk)
|
static void ublk_free_disk(struct gendisk *disk)
|
||||||
@@ -1059,6 +1081,25 @@ static void ublk_complete_rq(struct kref *ref)
|
|||||||
__ublk_complete_rq(req);
|
__ublk_complete_rq(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ublk_do_fail_rq(struct request *req)
|
||||||
|
{
|
||||||
|
struct ublk_queue *ubq = req->mq_hctx->driver_data;
|
||||||
|
|
||||||
|
if (ublk_nosrv_should_reissue_outstanding(ubq->dev))
|
||||||
|
blk_mq_requeue_request(req, false);
|
||||||
|
else
|
||||||
|
__ublk_complete_rq(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ublk_fail_rq_fn(struct kref *ref)
|
||||||
|
{
|
||||||
|
struct ublk_rq_data *data = container_of(ref, struct ublk_rq_data,
|
||||||
|
ref);
|
||||||
|
struct request *req = blk_mq_rq_from_pdu(data);
|
||||||
|
|
||||||
|
ublk_do_fail_rq(req);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since __ublk_rq_task_work always fails requests immediately during
|
* Since __ublk_rq_task_work always fails requests immediately during
|
||||||
* exiting, __ublk_fail_req() is only called from abort context during
|
* exiting, __ublk_fail_req() is only called from abort context during
|
||||||
@@ -1072,10 +1113,13 @@ static void __ublk_fail_req(struct ublk_queue *ubq, struct ublk_io *io,
|
|||||||
{
|
{
|
||||||
WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_ACTIVE);
|
WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_ACTIVE);
|
||||||
|
|
||||||
if (ublk_queue_can_use_recovery_reissue(ubq))
|
if (ublk_need_req_ref(ubq)) {
|
||||||
blk_mq_requeue_request(req, false);
|
struct ublk_rq_data *data = blk_mq_rq_to_pdu(req);
|
||||||
else
|
|
||||||
ublk_put_req_ref(ubq, req);
|
kref_put(&data->ref, ublk_fail_rq_fn);
|
||||||
|
} else {
|
||||||
|
ublk_do_fail_rq(req);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ubq_complete_io_cmd(struct ublk_io *io, int res,
|
static void ubq_complete_io_cmd(struct ublk_io *io, int res,
|
||||||
@@ -1100,7 +1144,7 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq,
|
|||||||
struct request *rq)
|
struct request *rq)
|
||||||
{
|
{
|
||||||
/* We cannot process this rq so just requeue it. */
|
/* We cannot process this rq so just requeue it. */
|
||||||
if (ublk_queue_can_use_recovery(ubq))
|
if (ublk_nosrv_dev_should_queue_io(ubq->dev))
|
||||||
blk_mq_requeue_request(rq, false);
|
blk_mq_requeue_request(rq, false);
|
||||||
else
|
else
|
||||||
blk_mq_end_request(rq, BLK_STS_IOERR);
|
blk_mq_end_request(rq, BLK_STS_IOERR);
|
||||||
@@ -1245,10 +1289,10 @@ static enum blk_eh_timer_return ublk_timeout(struct request *rq)
|
|||||||
struct ublk_device *ub = ubq->dev;
|
struct ublk_device *ub = ubq->dev;
|
||||||
|
|
||||||
if (ublk_abort_requests(ub, ubq)) {
|
if (ublk_abort_requests(ub, ubq)) {
|
||||||
if (ublk_can_use_recovery(ub))
|
if (ublk_nosrv_should_stop_dev(ub))
|
||||||
schedule_work(&ub->quiesce_work);
|
|
||||||
else
|
|
||||||
schedule_work(&ub->stop_work);
|
schedule_work(&ub->stop_work);
|
||||||
|
else
|
||||||
|
schedule_work(&ub->quiesce_work);
|
||||||
}
|
}
|
||||||
return BLK_EH_DONE;
|
return BLK_EH_DONE;
|
||||||
}
|
}
|
||||||
@@ -1277,7 +1321,7 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||||||
* Note: force_abort is guaranteed to be seen because it is set
|
* Note: force_abort is guaranteed to be seen because it is set
|
||||||
* before request queue is unqiuesced.
|
* before request queue is unqiuesced.
|
||||||
*/
|
*/
|
||||||
if (ublk_queue_can_use_recovery(ubq) && unlikely(ubq->force_abort))
|
if (ublk_nosrv_should_queue_io(ubq) && unlikely(ubq->force_abort))
|
||||||
return BLK_STS_IOERR;
|
return BLK_STS_IOERR;
|
||||||
|
|
||||||
if (unlikely(ubq->canceling)) {
|
if (unlikely(ubq->canceling)) {
|
||||||
@@ -1517,10 +1561,10 @@ static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd,
|
|||||||
ublk_cancel_cmd(ubq, io, issue_flags);
|
ublk_cancel_cmd(ubq, io, issue_flags);
|
||||||
|
|
||||||
if (need_schedule) {
|
if (need_schedule) {
|
||||||
if (ublk_can_use_recovery(ub))
|
if (ublk_nosrv_should_stop_dev(ub))
|
||||||
schedule_work(&ub->quiesce_work);
|
|
||||||
else
|
|
||||||
schedule_work(&ub->stop_work);
|
schedule_work(&ub->stop_work);
|
||||||
|
else
|
||||||
|
schedule_work(&ub->quiesce_work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1640,7 +1684,7 @@ static void ublk_stop_dev(struct ublk_device *ub)
|
|||||||
mutex_lock(&ub->mutex);
|
mutex_lock(&ub->mutex);
|
||||||
if (ub->dev_info.state == UBLK_S_DEV_DEAD)
|
if (ub->dev_info.state == UBLK_S_DEV_DEAD)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
if (ublk_can_use_recovery(ub)) {
|
if (ublk_nosrv_dev_should_queue_io(ub)) {
|
||||||
if (ub->dev_info.state == UBLK_S_DEV_LIVE)
|
if (ub->dev_info.state == UBLK_S_DEV_LIVE)
|
||||||
__ublk_quiesce_dev(ub);
|
__ublk_quiesce_dev(ub);
|
||||||
ublk_unquiesce_dev(ub);
|
ublk_unquiesce_dev(ub);
|
||||||
@@ -2738,7 +2782,7 @@ static int ublk_ctrl_start_recovery(struct ublk_device *ub,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
mutex_lock(&ub->mutex);
|
mutex_lock(&ub->mutex);
|
||||||
if (!ublk_can_use_recovery(ub))
|
if (ublk_nosrv_should_stop_dev(ub))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
if (!ub->nr_queues_ready)
|
if (!ub->nr_queues_ready)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@@ -2791,7 +2835,7 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
|
|||||||
__func__, ub->dev_info.nr_hw_queues, header->dev_id);
|
__func__, ub->dev_info.nr_hw_queues, header->dev_id);
|
||||||
|
|
||||||
mutex_lock(&ub->mutex);
|
mutex_lock(&ub->mutex);
|
||||||
if (!ublk_can_use_recovery(ub))
|
if (ublk_nosrv_should_stop_dev(ub))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
if (ub->dev_info.state != UBLK_S_DEV_QUIESCED) {
|
if (ub->dev_info.state != UBLK_S_DEV_QUIESCED) {
|
||||||
|
|||||||
@@ -193,6 +193,8 @@ static void of_gpio_try_fixup_polarity(const struct device_node *np,
|
|||||||
*/
|
*/
|
||||||
{ "himax,hx8357", "gpios-reset", false },
|
{ "himax,hx8357", "gpios-reset", false },
|
||||||
{ "himax,hx8369", "gpios-reset", false },
|
{ "himax,hx8369", "gpios-reset", false },
|
||||||
|
#endif
|
||||||
|
#if IS_ENABLED(CONFIG_MTD_NAND_JZ4780)
|
||||||
/*
|
/*
|
||||||
* The rb-gpios semantics was undocumented and qi,lb60 (along with
|
* The rb-gpios semantics was undocumented and qi,lb60 (along with
|
||||||
* the ingenic driver) got it wrong. The active state encodes the
|
* the ingenic driver) got it wrong. The active state encodes the
|
||||||
|
|||||||
@@ -117,21 +117,10 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
|
|||||||
GEN6_RC_CTL_RC6_ENABLE |
|
GEN6_RC_CTL_RC6_ENABLE |
|
||||||
GEN6_RC_CTL_EI_MODE(1);
|
GEN6_RC_CTL_EI_MODE(1);
|
||||||
|
|
||||||
/*
|
pg_enable =
|
||||||
* BSpec 52698 - Render powergating must be off.
|
GEN9_RENDER_PG_ENABLE |
|
||||||
* FIXME BSpec is outdated, disabling powergating for MTL is just
|
GEN9_MEDIA_PG_ENABLE |
|
||||||
* temporary wa and should be removed after fixing real cause
|
GEN11_MEDIA_SAMPLER_PG_ENABLE;
|
||||||
* of forcewake timeouts.
|
|
||||||
*/
|
|
||||||
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)))
|
|
||||||
pg_enable =
|
|
||||||
GEN9_MEDIA_PG_ENABLE |
|
|
||||||
GEN11_MEDIA_SAMPLER_PG_ENABLE;
|
|
||||||
else
|
|
||||||
pg_enable =
|
|
||||||
GEN9_RENDER_PG_ENABLE |
|
|
||||||
GEN9_MEDIA_PG_ENABLE |
|
|
||||||
GEN11_MEDIA_SAMPLER_PG_ENABLE;
|
|
||||||
|
|
||||||
if (GRAPHICS_VER(gt->i915) >= 12 && !IS_DG1(gt->i915)) {
|
if (GRAPHICS_VER(gt->i915) >= 12 && !IS_DG1(gt->i915)) {
|
||||||
for (i = 0; i < I915_MAX_VCS; i++)
|
for (i = 0; i < I915_MAX_VCS; i++)
|
||||||
|
|||||||
@@ -317,6 +317,11 @@ void intel_huc_init_early(struct intel_huc *huc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void intel_huc_fini_late(struct intel_huc *huc)
|
||||||
|
{
|
||||||
|
delayed_huc_load_fini(huc);
|
||||||
|
}
|
||||||
|
|
||||||
#define HUC_LOAD_MODE_STRING(x) (x ? "GSC" : "legacy")
|
#define HUC_LOAD_MODE_STRING(x) (x ? "GSC" : "legacy")
|
||||||
static int check_huc_loading_mode(struct intel_huc *huc)
|
static int check_huc_loading_mode(struct intel_huc *huc)
|
||||||
{
|
{
|
||||||
@@ -414,12 +419,6 @@ out:
|
|||||||
|
|
||||||
void intel_huc_fini(struct intel_huc *huc)
|
void intel_huc_fini(struct intel_huc *huc)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* the fence is initialized in init_early, so we need to clean it up
|
|
||||||
* even if HuC loading is off.
|
|
||||||
*/
|
|
||||||
delayed_huc_load_fini(huc);
|
|
||||||
|
|
||||||
if (huc->heci_pkt)
|
if (huc->heci_pkt)
|
||||||
i915_vma_unpin_and_release(&huc->heci_pkt, 0);
|
i915_vma_unpin_and_release(&huc->heci_pkt, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ struct intel_huc {
|
|||||||
|
|
||||||
int intel_huc_sanitize(struct intel_huc *huc);
|
int intel_huc_sanitize(struct intel_huc *huc);
|
||||||
void intel_huc_init_early(struct intel_huc *huc);
|
void intel_huc_init_early(struct intel_huc *huc);
|
||||||
|
void intel_huc_fini_late(struct intel_huc *huc);
|
||||||
int intel_huc_init(struct intel_huc *huc);
|
int intel_huc_init(struct intel_huc *huc);
|
||||||
void intel_huc_fini(struct intel_huc *huc);
|
void intel_huc_fini(struct intel_huc *huc);
|
||||||
void intel_huc_suspend(struct intel_huc *huc);
|
void intel_huc_suspend(struct intel_huc *huc);
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ void intel_uc_init_late(struct intel_uc *uc)
|
|||||||
|
|
||||||
void intel_uc_driver_late_release(struct intel_uc *uc)
|
void intel_uc_driver_late_release(struct intel_uc *uc)
|
||||||
{
|
{
|
||||||
|
intel_huc_fini_late(&uc->huc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,7 +23,9 @@
|
|||||||
|
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
|
|
||||||
|
#include "gt/intel_gt.h"
|
||||||
#include "gt/intel_gt_pm.h"
|
#include "gt/intel_gt_pm.h"
|
||||||
|
#include "gt/intel_gt_regs.h"
|
||||||
#include "gt/uc/intel_gsc_fw.h"
|
#include "gt/uc/intel_gsc_fw.h"
|
||||||
|
|
||||||
#include "i915_driver.h"
|
#include "i915_driver.h"
|
||||||
@@ -253,11 +255,27 @@ int i915_mock_selftests(void)
|
|||||||
int i915_live_selftests(struct pci_dev *pdev)
|
int i915_live_selftests(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *i915 = pdev_to_i915(pdev);
|
struct drm_i915_private *i915 = pdev_to_i915(pdev);
|
||||||
|
struct intel_uncore *uncore = &i915->uncore;
|
||||||
int err;
|
int err;
|
||||||
|
u32 pg_enable;
|
||||||
|
intel_wakeref_t wakeref;
|
||||||
|
|
||||||
if (!i915_selftest.live)
|
if (!i915_selftest.live)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME Disable render powergating, this is temporary wa and should be removed
|
||||||
|
* after fixing real cause of forcewake timeouts.
|
||||||
|
*/
|
||||||
|
with_intel_runtime_pm(uncore->rpm, wakeref) {
|
||||||
|
if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 00), IP_VER(12, 74))) {
|
||||||
|
pg_enable = intel_uncore_read(uncore, GEN9_PG_ENABLE);
|
||||||
|
if (pg_enable & GEN9_RENDER_PG_ENABLE)
|
||||||
|
intel_uncore_write_fw(uncore, GEN9_PG_ENABLE,
|
||||||
|
pg_enable & ~GEN9_RENDER_PG_ENABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__wait_gsc_proxy_completed(i915);
|
__wait_gsc_proxy_completed(i915);
|
||||||
__wait_gsc_huc_load_completed(i915);
|
__wait_gsc_huc_load_completed(i915);
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,9 @@ static void drm_test_pick_cmdline_res_1920_1080_60(struct kunit *test)
|
|||||||
expected_mode = drm_mode_find_dmt(priv->drm, 1920, 1080, 60, false);
|
expected_mode = drm_mode_find_dmt(priv->drm, 1920, 1080, 60, false);
|
||||||
KUNIT_ASSERT_NOT_NULL(test, expected_mode);
|
KUNIT_ASSERT_NOT_NULL(test, expected_mode);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, expected_mode);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
|
|
||||||
KUNIT_ASSERT_TRUE(test,
|
KUNIT_ASSERT_TRUE(test,
|
||||||
drm_mode_parse_command_line_for_connector(cmdline,
|
drm_mode_parse_command_line_for_connector(cmdline,
|
||||||
connector,
|
connector,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <kunit/test.h>
|
#include <kunit/test.h>
|
||||||
|
|
||||||
#include <drm/drm_connector.h>
|
#include <drm/drm_connector.h>
|
||||||
|
#include <drm/drm_kunit_helpers.h>
|
||||||
#include <drm/drm_modes.h>
|
#include <drm/drm_modes.h>
|
||||||
|
|
||||||
static const struct drm_connector no_connector = {};
|
static const struct drm_connector no_connector = {};
|
||||||
@@ -955,8 +956,15 @@ struct drm_cmdline_tv_option_test {
|
|||||||
static void drm_test_cmdline_tv_options(struct kunit *test)
|
static void drm_test_cmdline_tv_options(struct kunit *test)
|
||||||
{
|
{
|
||||||
const struct drm_cmdline_tv_option_test *params = test->param_value;
|
const struct drm_cmdline_tv_option_test *params = test->param_value;
|
||||||
const struct drm_display_mode *expected_mode = params->mode_fn(NULL);
|
struct drm_display_mode *expected_mode;
|
||||||
struct drm_cmdline_mode mode = { };
|
struct drm_cmdline_mode mode = { };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
expected_mode = params->mode_fn(NULL);
|
||||||
|
KUNIT_ASSERT_NOT_NULL(test, expected_mode);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, expected_mode);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
|
|
||||||
KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector(params->cmdline,
|
KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector(params->cmdline,
|
||||||
&no_connector, &mode));
|
&no_connector, &mode));
|
||||||
|
|||||||
@@ -319,6 +319,28 @@ static void kunit_action_drm_mode_destroy(void *ptr)
|
|||||||
drm_mode_destroy(NULL, mode);
|
drm_mode_destroy(NULL, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_kunit_add_mode_destroy_action() - Add a drm_destroy_mode kunit action
|
||||||
|
* @test: The test context object
|
||||||
|
* @mode: The drm_display_mode to destroy eventually
|
||||||
|
*
|
||||||
|
* Registers a kunit action that will destroy the drm_display_mode at
|
||||||
|
* the end of the test.
|
||||||
|
*
|
||||||
|
* If an error occurs, the drm_display_mode will be destroyed.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, an error code otherwise.
|
||||||
|
*/
|
||||||
|
int drm_kunit_add_mode_destroy_action(struct kunit *test,
|
||||||
|
struct drm_display_mode *mode)
|
||||||
|
{
|
||||||
|
return kunit_add_action_or_reset(test,
|
||||||
|
kunit_action_drm_mode_destroy,
|
||||||
|
mode);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(drm_kunit_add_mode_destroy_action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC for a KUnit test
|
* drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC for a KUnit test
|
||||||
* @test: The test context object
|
* @test: The test context object
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ static void drm_test_modes_analog_tv_ntsc_480i(struct kunit *test)
|
|||||||
{
|
{
|
||||||
struct drm_test_modes_priv *priv = test->priv;
|
struct drm_test_modes_priv *priv = test->priv;
|
||||||
struct drm_display_mode *mode;
|
struct drm_display_mode *mode;
|
||||||
|
int ret;
|
||||||
|
|
||||||
mode = drm_analog_tv_mode(priv->drm,
|
mode = drm_analog_tv_mode(priv->drm,
|
||||||
DRM_MODE_TV_MODE_NTSC,
|
DRM_MODE_TV_MODE_NTSC,
|
||||||
@@ -47,6 +48,9 @@ static void drm_test_modes_analog_tv_ntsc_480i(struct kunit *test)
|
|||||||
true);
|
true);
|
||||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, mode);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
|
|
||||||
KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 60);
|
KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 60);
|
||||||
KUNIT_EXPECT_EQ(test, mode->hdisplay, 720);
|
KUNIT_EXPECT_EQ(test, mode->hdisplay, 720);
|
||||||
|
|
||||||
@@ -70,6 +74,7 @@ static void drm_test_modes_analog_tv_ntsc_480i_inlined(struct kunit *test)
|
|||||||
{
|
{
|
||||||
struct drm_test_modes_priv *priv = test->priv;
|
struct drm_test_modes_priv *priv = test->priv;
|
||||||
struct drm_display_mode *expected, *mode;
|
struct drm_display_mode *expected, *mode;
|
||||||
|
int ret;
|
||||||
|
|
||||||
expected = drm_analog_tv_mode(priv->drm,
|
expected = drm_analog_tv_mode(priv->drm,
|
||||||
DRM_MODE_TV_MODE_NTSC,
|
DRM_MODE_TV_MODE_NTSC,
|
||||||
@@ -77,9 +82,15 @@ static void drm_test_modes_analog_tv_ntsc_480i_inlined(struct kunit *test)
|
|||||||
true);
|
true);
|
||||||
KUNIT_ASSERT_NOT_NULL(test, expected);
|
KUNIT_ASSERT_NOT_NULL(test, expected);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, expected);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
|
|
||||||
mode = drm_mode_analog_ntsc_480i(priv->drm);
|
mode = drm_mode_analog_ntsc_480i(priv->drm);
|
||||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, mode);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
|
|
||||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode));
|
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +98,7 @@ static void drm_test_modes_analog_tv_pal_576i(struct kunit *test)
|
|||||||
{
|
{
|
||||||
struct drm_test_modes_priv *priv = test->priv;
|
struct drm_test_modes_priv *priv = test->priv;
|
||||||
struct drm_display_mode *mode;
|
struct drm_display_mode *mode;
|
||||||
|
int ret;
|
||||||
|
|
||||||
mode = drm_analog_tv_mode(priv->drm,
|
mode = drm_analog_tv_mode(priv->drm,
|
||||||
DRM_MODE_TV_MODE_PAL,
|
DRM_MODE_TV_MODE_PAL,
|
||||||
@@ -94,6 +106,9 @@ static void drm_test_modes_analog_tv_pal_576i(struct kunit *test)
|
|||||||
true);
|
true);
|
||||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, mode);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
|
|
||||||
KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 50);
|
KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 50);
|
||||||
KUNIT_EXPECT_EQ(test, mode->hdisplay, 720);
|
KUNIT_EXPECT_EQ(test, mode->hdisplay, 720);
|
||||||
|
|
||||||
@@ -117,6 +132,7 @@ static void drm_test_modes_analog_tv_pal_576i_inlined(struct kunit *test)
|
|||||||
{
|
{
|
||||||
struct drm_test_modes_priv *priv = test->priv;
|
struct drm_test_modes_priv *priv = test->priv;
|
||||||
struct drm_display_mode *expected, *mode;
|
struct drm_display_mode *expected, *mode;
|
||||||
|
int ret;
|
||||||
|
|
||||||
expected = drm_analog_tv_mode(priv->drm,
|
expected = drm_analog_tv_mode(priv->drm,
|
||||||
DRM_MODE_TV_MODE_PAL,
|
DRM_MODE_TV_MODE_PAL,
|
||||||
@@ -124,9 +140,15 @@ static void drm_test_modes_analog_tv_pal_576i_inlined(struct kunit *test)
|
|||||||
true);
|
true);
|
||||||
KUNIT_ASSERT_NOT_NULL(test, expected);
|
KUNIT_ASSERT_NOT_NULL(test, expected);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, expected);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
|
|
||||||
mode = drm_mode_analog_pal_576i(priv->drm);
|
mode = drm_mode_analog_pal_576i(priv->drm);
|
||||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, mode);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
|
|
||||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode));
|
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
|
|||||||
struct drm_connector *connector = &priv->connector;
|
struct drm_connector *connector = &priv->connector;
|
||||||
struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
|
struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
|
||||||
struct drm_display_mode *mode;
|
struct drm_display_mode *mode;
|
||||||
const struct drm_display_mode *expected;
|
struct drm_display_mode *expected;
|
||||||
size_t len;
|
size_t len;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -134,6 +134,9 @@ drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
|
|||||||
|
|
||||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
|
KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
|
||||||
KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
|
KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, expected);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->num_expected_modes >= 2) {
|
if (params->num_expected_modes >= 2) {
|
||||||
@@ -145,6 +148,9 @@ drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
|
|||||||
|
|
||||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
|
KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
|
||||||
KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
|
KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
|
||||||
|
|
||||||
|
ret = drm_kunit_add_mode_destroy_action(test, expected);
|
||||||
|
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&priv->drm->mode_config.mutex);
|
mutex_unlock(&priv->drm->mode_config.mutex);
|
||||||
|
|||||||
@@ -32,14 +32,61 @@ bool xe_hw_engine_timeout_in_range(u64 timeout, u64 min, u64 max)
|
|||||||
return timeout >= min && timeout <= max;
|
return timeout >= min && timeout <= max;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kobj_xe_hw_engine_release(struct kobject *kobj)
|
static void xe_hw_engine_sysfs_kobj_release(struct kobject *kobj)
|
||||||
{
|
{
|
||||||
kfree(kobj);
|
kfree(kobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t xe_hw_engine_class_sysfs_attr_show(struct kobject *kobj,
|
||||||
|
struct attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct xe_device *xe = kobj_to_xe(kobj);
|
||||||
|
struct kobj_attribute *kattr;
|
||||||
|
ssize_t ret = -EIO;
|
||||||
|
|
||||||
|
kattr = container_of(attr, struct kobj_attribute, attr);
|
||||||
|
if (kattr->show) {
|
||||||
|
xe_pm_runtime_get(xe);
|
||||||
|
ret = kattr->show(kobj, kattr, buf);
|
||||||
|
xe_pm_runtime_put(xe);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t xe_hw_engine_class_sysfs_attr_store(struct kobject *kobj,
|
||||||
|
struct attribute *attr,
|
||||||
|
const char *buf,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
struct xe_device *xe = kobj_to_xe(kobj);
|
||||||
|
struct kobj_attribute *kattr;
|
||||||
|
ssize_t ret = -EIO;
|
||||||
|
|
||||||
|
kattr = container_of(attr, struct kobj_attribute, attr);
|
||||||
|
if (kattr->store) {
|
||||||
|
xe_pm_runtime_get(xe);
|
||||||
|
ret = kattr->store(kobj, kattr, buf, count);
|
||||||
|
xe_pm_runtime_put(xe);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sysfs_ops xe_hw_engine_class_sysfs_ops = {
|
||||||
|
.show = xe_hw_engine_class_sysfs_attr_show,
|
||||||
|
.store = xe_hw_engine_class_sysfs_attr_store,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct kobj_type kobj_xe_hw_engine_type = {
|
static const struct kobj_type kobj_xe_hw_engine_type = {
|
||||||
.release = kobj_xe_hw_engine_release,
|
.release = xe_hw_engine_sysfs_kobj_release,
|
||||||
.sysfs_ops = &kobj_sysfs_ops
|
.sysfs_ops = &xe_hw_engine_class_sysfs_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct kobj_type kobj_xe_hw_engine_type_def = {
|
||||||
|
.release = xe_hw_engine_sysfs_kobj_release,
|
||||||
|
.sysfs_ops = &kobj_sysfs_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t job_timeout_max_store(struct kobject *kobj,
|
static ssize_t job_timeout_max_store(struct kobject *kobj,
|
||||||
@@ -543,7 +590,7 @@ static int xe_add_hw_engine_class_defaults(struct xe_device *xe,
|
|||||||
if (!kobj)
|
if (!kobj)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
kobject_init(kobj, &kobj_xe_hw_engine_type);
|
kobject_init(kobj, &kobj_xe_hw_engine_type_def);
|
||||||
err = kobject_add(kobj, parent, "%s", ".defaults");
|
err = kobject_add(kobj, parent, "%s", ".defaults");
|
||||||
if (err)
|
if (err)
|
||||||
goto err_object;
|
goto err_object;
|
||||||
@@ -559,57 +606,6 @@ err_object:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xe_hw_engine_sysfs_kobj_release(struct kobject *kobj)
|
|
||||||
{
|
|
||||||
kfree(kobj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t xe_hw_engine_class_sysfs_attr_show(struct kobject *kobj,
|
|
||||||
struct attribute *attr,
|
|
||||||
char *buf)
|
|
||||||
{
|
|
||||||
struct xe_device *xe = kobj_to_xe(kobj);
|
|
||||||
struct kobj_attribute *kattr;
|
|
||||||
ssize_t ret = -EIO;
|
|
||||||
|
|
||||||
kattr = container_of(attr, struct kobj_attribute, attr);
|
|
||||||
if (kattr->show) {
|
|
||||||
xe_pm_runtime_get(xe);
|
|
||||||
ret = kattr->show(kobj, kattr, buf);
|
|
||||||
xe_pm_runtime_put(xe);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t xe_hw_engine_class_sysfs_attr_store(struct kobject *kobj,
|
|
||||||
struct attribute *attr,
|
|
||||||
const char *buf,
|
|
||||||
size_t count)
|
|
||||||
{
|
|
||||||
struct xe_device *xe = kobj_to_xe(kobj);
|
|
||||||
struct kobj_attribute *kattr;
|
|
||||||
ssize_t ret = -EIO;
|
|
||||||
|
|
||||||
kattr = container_of(attr, struct kobj_attribute, attr);
|
|
||||||
if (kattr->store) {
|
|
||||||
xe_pm_runtime_get(xe);
|
|
||||||
ret = kattr->store(kobj, kattr, buf, count);
|
|
||||||
xe_pm_runtime_put(xe);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct sysfs_ops xe_hw_engine_class_sysfs_ops = {
|
|
||||||
.show = xe_hw_engine_class_sysfs_attr_show,
|
|
||||||
.store = xe_hw_engine_class_sysfs_attr_store,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct kobj_type xe_hw_engine_sysfs_kobj_type = {
|
|
||||||
.release = xe_hw_engine_sysfs_kobj_release,
|
|
||||||
.sysfs_ops = &xe_hw_engine_class_sysfs_ops,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void hw_engine_class_sysfs_fini(void *arg)
|
static void hw_engine_class_sysfs_fini(void *arg)
|
||||||
{
|
{
|
||||||
@@ -640,7 +636,7 @@ int xe_hw_engine_class_sysfs_init(struct xe_gt *gt)
|
|||||||
if (!kobj)
|
if (!kobj)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
kobject_init(kobj, &xe_hw_engine_sysfs_kobj_type);
|
kobject_init(kobj, &kobj_xe_hw_engine_type);
|
||||||
|
|
||||||
err = kobject_add(kobj, gt->sysfs, "engines");
|
err = kobject_add(kobj, gt->sysfs, "engines");
|
||||||
if (err)
|
if (err)
|
||||||
|
|||||||
@@ -165,6 +165,11 @@ static void __otx2_qos_txschq_cfg(struct otx2_nic *pfvf,
|
|||||||
|
|
||||||
otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
|
otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
|
||||||
} else if (level == NIX_TXSCH_LVL_TL2) {
|
} else if (level == NIX_TXSCH_LVL_TL2) {
|
||||||
|
/* configure parent txschq */
|
||||||
|
cfg->reg[num_regs] = NIX_AF_TL2X_PARENT(node->schq);
|
||||||
|
cfg->regval[num_regs] = (u64)hw->tx_link << 16;
|
||||||
|
num_regs++;
|
||||||
|
|
||||||
/* configure link cfg */
|
/* configure link cfg */
|
||||||
if (level == pfvf->qos.link_cfg_lvl) {
|
if (level == pfvf->qos.link_cfg_lvl) {
|
||||||
cfg->reg[num_regs] = NIX_AF_TL3_TL2X_LINKX_CFG(node->schq, hw->tx_link);
|
cfg->reg[num_regs] = NIX_AF_TL3_TL2X_LINKX_CFG(node->schq, hw->tx_link);
|
||||||
|
|||||||
@@ -309,7 +309,8 @@ static bool wx_alloc_mapped_page(struct wx_ring *rx_ring,
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
page = page_pool_dev_alloc_pages(rx_ring->page_pool);
|
page = page_pool_dev_alloc_pages(rx_ring->page_pool);
|
||||||
WARN_ON(!page);
|
if (unlikely(!page))
|
||||||
|
return false;
|
||||||
dma = page_pool_get_dma_addr(page);
|
dma = page_pool_get_dma_addr(page);
|
||||||
|
|
||||||
bi->page_dma = dma;
|
bi->page_dma = dma;
|
||||||
|
|||||||
@@ -289,6 +289,46 @@ static bool phy_drv_wol_enabled(struct phy_device *phydev)
|
|||||||
return wol.wolopts != 0;
|
return wol.wolopts != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void phy_link_change(struct phy_device *phydev, bool up)
|
||||||
|
{
|
||||||
|
struct net_device *netdev = phydev->attached_dev;
|
||||||
|
|
||||||
|
if (up)
|
||||||
|
netif_carrier_on(netdev);
|
||||||
|
else
|
||||||
|
netif_carrier_off(netdev);
|
||||||
|
phydev->adjust_link(netdev);
|
||||||
|
if (phydev->mii_ts && phydev->mii_ts->link_state)
|
||||||
|
phydev->mii_ts->link_state(phydev->mii_ts, phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phy_uses_state_machine - test whether consumer driver uses PAL state machine
|
||||||
|
* @phydev: the target PHY device structure
|
||||||
|
*
|
||||||
|
* Ultimately, this aims to indirectly determine whether the PHY is attached
|
||||||
|
* to a consumer which uses the state machine by calling phy_start() and
|
||||||
|
* phy_stop().
|
||||||
|
*
|
||||||
|
* When the PHY driver consumer uses phylib, it must have previously called
|
||||||
|
* phy_connect_direct() or one of its derivatives, so that phy_prepare_link()
|
||||||
|
* has set up a hook for monitoring state changes.
|
||||||
|
*
|
||||||
|
* When the PHY driver is used by the MAC driver consumer through phylink (the
|
||||||
|
* only other provider of a phy_link_change() method), using the PHY state
|
||||||
|
* machine is not optional.
|
||||||
|
*
|
||||||
|
* Return: true if consumer calls phy_start() and phy_stop(), false otherwise.
|
||||||
|
*/
|
||||||
|
static bool phy_uses_state_machine(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
if (phydev->phy_link_change == phy_link_change)
|
||||||
|
return phydev->attached_dev && phydev->adjust_link;
|
||||||
|
|
||||||
|
/* phydev->phy_link_change is implicitly phylink_phy_change() */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
|
static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
struct device_driver *drv = phydev->mdio.dev.driver;
|
struct device_driver *drv = phydev->mdio.dev.driver;
|
||||||
@@ -355,7 +395,7 @@ static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
|
|||||||
* may call phy routines that try to grab the same lock, and that may
|
* may call phy routines that try to grab the same lock, and that may
|
||||||
* lead to a deadlock.
|
* lead to a deadlock.
|
||||||
*/
|
*/
|
||||||
if (phydev->attached_dev && phydev->adjust_link)
|
if (phy_uses_state_machine(phydev))
|
||||||
phy_stop_machine(phydev);
|
phy_stop_machine(phydev);
|
||||||
|
|
||||||
if (!mdio_bus_phy_may_suspend(phydev))
|
if (!mdio_bus_phy_may_suspend(phydev))
|
||||||
@@ -409,7 +449,7 @@ no_resume:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phydev->attached_dev && phydev->adjust_link)
|
if (phy_uses_state_machine(phydev))
|
||||||
phy_start_machine(phydev);
|
phy_start_machine(phydev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1101,19 +1141,6 @@ struct phy_device *phy_find_first(struct mii_bus *bus)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(phy_find_first);
|
EXPORT_SYMBOL(phy_find_first);
|
||||||
|
|
||||||
static void phy_link_change(struct phy_device *phydev, bool up)
|
|
||||||
{
|
|
||||||
struct net_device *netdev = phydev->attached_dev;
|
|
||||||
|
|
||||||
if (up)
|
|
||||||
netif_carrier_on(netdev);
|
|
||||||
else
|
|
||||||
netif_carrier_off(netdev);
|
|
||||||
phydev->adjust_link(netdev);
|
|
||||||
if (phydev->mii_ts && phydev->mii_ts->link_state)
|
|
||||||
phydev->mii_ts->link_state(phydev->mii_ts, phydev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* phy_prepare_link - prepares the PHY layer to monitor link status
|
* phy_prepare_link - prepares the PHY layer to monitor link status
|
||||||
* @phydev: target phy_device struct
|
* @phydev: target phy_device struct
|
||||||
|
|||||||
@@ -478,7 +478,7 @@ fcloop_t2h_xmt_ls_rsp(struct nvme_fc_local_port *localport,
|
|||||||
if (targetport) {
|
if (targetport) {
|
||||||
tport = targetport->private;
|
tport = targetport->private;
|
||||||
spin_lock(&tport->lock);
|
spin_lock(&tport->lock);
|
||||||
list_add_tail(&tport->ls_list, &tls_req->ls_list);
|
list_add_tail(&tls_req->ls_list, &tport->ls_list);
|
||||||
spin_unlock(&tport->lock);
|
spin_unlock(&tport->lock);
|
||||||
queue_work(nvmet_wq, &tport->ls_work);
|
queue_work(nvmet_wq, &tport->ls_work);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -702,18 +702,12 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server)
|
|||||||
cifs_free_hash(&server->secmech.md5);
|
cifs_free_hash(&server->secmech.md5);
|
||||||
cifs_free_hash(&server->secmech.sha512);
|
cifs_free_hash(&server->secmech.sha512);
|
||||||
|
|
||||||
if (!SERVER_IS_CHAN(server)) {
|
if (server->secmech.enc) {
|
||||||
if (server->secmech.enc) {
|
crypto_free_aead(server->secmech.enc);
|
||||||
crypto_free_aead(server->secmech.enc);
|
|
||||||
server->secmech.enc = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (server->secmech.dec) {
|
|
||||||
crypto_free_aead(server->secmech.dec);
|
|
||||||
server->secmech.dec = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
server->secmech.enc = NULL;
|
server->secmech.enc = NULL;
|
||||||
|
}
|
||||||
|
if (server->secmech.dec) {
|
||||||
|
crypto_free_aead(server->secmech.dec);
|
||||||
server->secmech.dec = NULL;
|
server->secmech.dec = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4576,9 +4576,9 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (unlikely(!server->secmech.dec))
|
rc = smb3_crypto_aead_allocate(server);
|
||||||
return -EIO;
|
if (unlikely(rc))
|
||||||
|
return rc;
|
||||||
tfm = server->secmech.dec;
|
tfm = server->secmech.dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1269,15 +1269,8 @@ SMB2_negotiate(const unsigned int xid,
|
|||||||
cifs_server_dbg(VFS, "Missing expected negotiate contexts\n");
|
cifs_server_dbg(VFS, "Missing expected negotiate contexts\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server->cipher_type && !rc) {
|
if (server->cipher_type && !rc)
|
||||||
if (!SERVER_IS_CHAN(server)) {
|
rc = smb3_crypto_aead_allocate(server);
|
||||||
rc = smb3_crypto_aead_allocate(server);
|
|
||||||
} else {
|
|
||||||
/* For channels, just reuse the primary server crypto secmech. */
|
|
||||||
server->secmech.enc = server->primary_server->secmech.enc;
|
|
||||||
server->secmech.dec = server->primary_server->secmech.dec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
neg_exit:
|
neg_exit:
|
||||||
free_rsp_buf(resp_buftype, rsp);
|
free_rsp_buf(resp_buftype, rsp);
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -120,6 +120,9 @@ drm_kunit_helper_create_crtc(struct kunit *test,
|
|||||||
const struct drm_crtc_funcs *funcs,
|
const struct drm_crtc_funcs *funcs,
|
||||||
const struct drm_crtc_helper_funcs *helper_funcs);
|
const struct drm_crtc_helper_funcs *helper_funcs);
|
||||||
|
|
||||||
|
int drm_kunit_add_mode_destroy_action(struct kunit *test,
|
||||||
|
struct drm_display_mode *mode);
|
||||||
|
|
||||||
struct drm_display_mode *
|
struct drm_display_mode *
|
||||||
drm_kunit_display_mode_from_cea_vic(struct kunit *test, struct drm_device *dev,
|
drm_kunit_display_mode_from_cea_vic(struct kunit *test, struct drm_device *dev,
|
||||||
u8 video_code);
|
u8 video_code);
|
||||||
|
|||||||
@@ -711,6 +711,7 @@ struct cgroup_subsys {
|
|||||||
void (*css_released)(struct cgroup_subsys_state *css);
|
void (*css_released)(struct cgroup_subsys_state *css);
|
||||||
void (*css_free)(struct cgroup_subsys_state *css);
|
void (*css_free)(struct cgroup_subsys_state *css);
|
||||||
void (*css_reset)(struct cgroup_subsys_state *css);
|
void (*css_reset)(struct cgroup_subsys_state *css);
|
||||||
|
void (*css_killed)(struct cgroup_subsys_state *css);
|
||||||
void (*css_rstat_flush)(struct cgroup_subsys_state *css, int cpu);
|
void (*css_rstat_flush)(struct cgroup_subsys_state *css, int cpu);
|
||||||
int (*css_extra_stat_show)(struct seq_file *seq,
|
int (*css_extra_stat_show)(struct seq_file *seq,
|
||||||
struct cgroup_subsys_state *css);
|
struct cgroup_subsys_state *css);
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ static inline u64 cgroup_id(const struct cgroup *cgrp)
|
|||||||
*/
|
*/
|
||||||
static inline bool css_is_dying(struct cgroup_subsys_state *css)
|
static inline bool css_is_dying(struct cgroup_subsys_state *css)
|
||||||
{
|
{
|
||||||
return !(css->flags & CSS_NO_REF) && percpu_ref_is_dying(&css->refcnt);
|
return css->flags & CSS_DYING;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cgroup_get(struct cgroup *cgrp)
|
static inline void cgroup_get(struct cgroup *cgrp)
|
||||||
|
|||||||
@@ -5946,6 +5946,12 @@ static void kill_css(struct cgroup_subsys_state *css)
|
|||||||
if (css->flags & CSS_DYING)
|
if (css->flags & CSS_DYING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call css_killed(), if defined, before setting the CSS_DYING flag
|
||||||
|
*/
|
||||||
|
if (css->ss->css_killed)
|
||||||
|
css->ss->css_killed(css);
|
||||||
|
|
||||||
css->flags |= CSS_DYING;
|
css->flags |= CSS_DYING;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+103
-73
@@ -85,9 +85,19 @@ static bool have_boot_isolcpus;
|
|||||||
static struct list_head remote_children;
|
static struct list_head remote_children;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A flag to force sched domain rebuild at the end of an operation while
|
* A flag to force sched domain rebuild at the end of an operation.
|
||||||
* inhibiting it in the intermediate stages when set. Currently it is only
|
* It can be set in
|
||||||
* set in hotplug code.
|
* - update_partition_sd_lb()
|
||||||
|
* - remote_partition_check()
|
||||||
|
* - update_cpumasks_hier()
|
||||||
|
* - cpuset_update_flag()
|
||||||
|
* - cpuset_hotplug_update_tasks()
|
||||||
|
* - cpuset_handle_hotplug()
|
||||||
|
*
|
||||||
|
* Protected by cpuset_mutex (with cpus_read_lock held) or cpus_write_lock.
|
||||||
|
*
|
||||||
|
* Note that update_relax_domain_level() in cpuset-v1.c can still call
|
||||||
|
* rebuild_sched_domains_locked() directly without using this flag.
|
||||||
*/
|
*/
|
||||||
static bool force_sd_rebuild;
|
static bool force_sd_rebuild;
|
||||||
|
|
||||||
@@ -284,6 +294,12 @@ static inline void dec_attach_in_progress(struct cpuset *cs)
|
|||||||
mutex_unlock(&cpuset_mutex);
|
mutex_unlock(&cpuset_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool cpuset_v2(void)
|
||||||
|
{
|
||||||
|
return !IS_ENABLED(CONFIG_CPUSETS_V1) ||
|
||||||
|
cgroup_subsys_on_dfl(cpuset_cgrp_subsys);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cgroup v2 behavior is used on the "cpus" and "mems" control files when
|
* Cgroup v2 behavior is used on the "cpus" and "mems" control files when
|
||||||
* on default hierarchy or when the cpuset_v2_mode flag is set by mounting
|
* on default hierarchy or when the cpuset_v2_mode flag is set by mounting
|
||||||
@@ -294,7 +310,7 @@ static inline void dec_attach_in_progress(struct cpuset *cs)
|
|||||||
*/
|
*/
|
||||||
static inline bool is_in_v2_mode(void)
|
static inline bool is_in_v2_mode(void)
|
||||||
{
|
{
|
||||||
return cgroup_subsys_on_dfl(cpuset_cgrp_subsys) ||
|
return cpuset_v2() ||
|
||||||
(cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE);
|
(cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,7 +745,7 @@ static int generate_sched_domains(cpumask_var_t **domains,
|
|||||||
int nslot; /* next empty doms[] struct cpumask slot */
|
int nslot; /* next empty doms[] struct cpumask slot */
|
||||||
struct cgroup_subsys_state *pos_css;
|
struct cgroup_subsys_state *pos_css;
|
||||||
bool root_load_balance = is_sched_load_balance(&top_cpuset);
|
bool root_load_balance = is_sched_load_balance(&top_cpuset);
|
||||||
bool cgrpv2 = cgroup_subsys_on_dfl(cpuset_cgrp_subsys);
|
bool cgrpv2 = cpuset_v2();
|
||||||
int nslot_update;
|
int nslot_update;
|
||||||
|
|
||||||
doms = NULL;
|
doms = NULL;
|
||||||
@@ -999,6 +1015,7 @@ void rebuild_sched_domains_locked(void)
|
|||||||
|
|
||||||
lockdep_assert_cpus_held();
|
lockdep_assert_cpus_held();
|
||||||
lockdep_assert_held(&cpuset_mutex);
|
lockdep_assert_held(&cpuset_mutex);
|
||||||
|
force_sd_rebuild = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have raced with CPU hotplug, return early to avoid
|
* If we have raced with CPU hotplug, return early to avoid
|
||||||
@@ -1186,8 +1203,8 @@ static void update_partition_sd_lb(struct cpuset *cs, int old_prs)
|
|||||||
clear_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
|
clear_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rebuild_domains && !force_sd_rebuild)
|
if (rebuild_domains)
|
||||||
rebuild_sched_domains_locked();
|
cpuset_force_rebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1209,7 +1226,7 @@ static void reset_partition_data(struct cpuset *cs)
|
|||||||
{
|
{
|
||||||
struct cpuset *parent = parent_cs(cs);
|
struct cpuset *parent = parent_cs(cs);
|
||||||
|
|
||||||
if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys))
|
if (!cpuset_v2())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lockdep_assert_held(&callback_lock);
|
lockdep_assert_held(&callback_lock);
|
||||||
@@ -1397,6 +1414,7 @@ static int remote_partition_enable(struct cpuset *cs, int new_prs,
|
|||||||
list_add(&cs->remote_sibling, &remote_children);
|
list_add(&cs->remote_sibling, &remote_children);
|
||||||
spin_unlock_irq(&callback_lock);
|
spin_unlock_irq(&callback_lock);
|
||||||
update_unbound_workqueue_cpumask(isolcpus_updated);
|
update_unbound_workqueue_cpumask(isolcpus_updated);
|
||||||
|
cs->prs_err = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Proprogate changes in top_cpuset's effective_cpus down the hierarchy.
|
* Proprogate changes in top_cpuset's effective_cpus down the hierarchy.
|
||||||
@@ -1427,9 +1445,11 @@ static void remote_partition_disable(struct cpuset *cs, struct tmpmasks *tmp)
|
|||||||
list_del_init(&cs->remote_sibling);
|
list_del_init(&cs->remote_sibling);
|
||||||
isolcpus_updated = partition_xcpus_del(cs->partition_root_state,
|
isolcpus_updated = partition_xcpus_del(cs->partition_root_state,
|
||||||
NULL, tmp->new_cpus);
|
NULL, tmp->new_cpus);
|
||||||
cs->partition_root_state = -cs->partition_root_state;
|
if (cs->prs_err)
|
||||||
if (!cs->prs_err)
|
cs->partition_root_state = -cs->partition_root_state;
|
||||||
cs->prs_err = PERR_INVCPUS;
|
else
|
||||||
|
cs->partition_root_state = PRS_MEMBER;
|
||||||
|
|
||||||
reset_partition_data(cs);
|
reset_partition_data(cs);
|
||||||
spin_unlock_irq(&callback_lock);
|
spin_unlock_irq(&callback_lock);
|
||||||
update_unbound_workqueue_cpumask(isolcpus_updated);
|
update_unbound_workqueue_cpumask(isolcpus_updated);
|
||||||
@@ -1462,8 +1482,10 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *newmask,
|
|||||||
|
|
||||||
WARN_ON_ONCE(!cpumask_subset(cs->effective_xcpus, subpartitions_cpus));
|
WARN_ON_ONCE(!cpumask_subset(cs->effective_xcpus, subpartitions_cpus));
|
||||||
|
|
||||||
if (cpumask_empty(newmask))
|
if (cpumask_empty(newmask)) {
|
||||||
|
cs->prs_err = PERR_CPUSEMPTY;
|
||||||
goto invalidate;
|
goto invalidate;
|
||||||
|
}
|
||||||
|
|
||||||
adding = cpumask_andnot(tmp->addmask, newmask, cs->effective_xcpus);
|
adding = cpumask_andnot(tmp->addmask, newmask, cs->effective_xcpus);
|
||||||
deleting = cpumask_andnot(tmp->delmask, cs->effective_xcpus, newmask);
|
deleting = cpumask_andnot(tmp->delmask, cs->effective_xcpus, newmask);
|
||||||
@@ -1473,10 +1495,15 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *newmask,
|
|||||||
* not allocated to other partitions and there are effective_cpus
|
* not allocated to other partitions and there are effective_cpus
|
||||||
* left in the top cpuset.
|
* left in the top cpuset.
|
||||||
*/
|
*/
|
||||||
if (adding && (!capable(CAP_SYS_ADMIN) ||
|
if (adding) {
|
||||||
cpumask_intersects(tmp->addmask, subpartitions_cpus) ||
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
cpumask_subset(top_cpuset.effective_cpus, tmp->addmask)))
|
cs->prs_err = PERR_ACCESS;
|
||||||
goto invalidate;
|
else if (cpumask_intersects(tmp->addmask, subpartitions_cpus) ||
|
||||||
|
cpumask_subset(top_cpuset.effective_cpus, tmp->addmask))
|
||||||
|
cs->prs_err = PERR_NOCPUS;
|
||||||
|
if (cs->prs_err)
|
||||||
|
goto invalidate;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irq(&callback_lock);
|
spin_lock_irq(&callback_lock);
|
||||||
if (adding)
|
if (adding)
|
||||||
@@ -1534,8 +1561,8 @@ static void remote_partition_check(struct cpuset *cs, struct cpumask *newmask,
|
|||||||
remote_partition_disable(child, tmp);
|
remote_partition_disable(child, tmp);
|
||||||
disable_cnt++;
|
disable_cnt++;
|
||||||
}
|
}
|
||||||
if (disable_cnt && !force_sd_rebuild)
|
if (disable_cnt)
|
||||||
rebuild_sched_domains_locked();
|
cpuset_force_rebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1592,7 +1619,7 @@ static bool prstate_housekeeping_conflict(int prstate, struct cpumask *new_cpus)
|
|||||||
* The partcmd_update command is used by update_cpumasks_hier() with newmask
|
* The partcmd_update command is used by update_cpumasks_hier() with newmask
|
||||||
* NULL and update_cpumask() with newmask set. The partcmd_invalidate is used
|
* NULL and update_cpumask() with newmask set. The partcmd_invalidate is used
|
||||||
* by update_cpumask() with NULL newmask. In both cases, the callers won't
|
* by update_cpumask() with NULL newmask. In both cases, the callers won't
|
||||||
* check for error and so partition_root_state and prs_error will be updated
|
* check for error and so partition_root_state and prs_err will be updated
|
||||||
* directly.
|
* directly.
|
||||||
*/
|
*/
|
||||||
static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
|
static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
|
||||||
@@ -1670,9 +1697,9 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
|
|||||||
if (nocpu)
|
if (nocpu)
|
||||||
return PERR_NOCPUS;
|
return PERR_NOCPUS;
|
||||||
|
|
||||||
cpumask_copy(tmp->delmask, xcpus);
|
deleting = cpumask_and(tmp->delmask, xcpus, parent->effective_xcpus);
|
||||||
deleting = true;
|
if (deleting)
|
||||||
subparts_delta++;
|
subparts_delta++;
|
||||||
new_prs = (cmd == partcmd_enable) ? PRS_ROOT : PRS_ISOLATED;
|
new_prs = (cmd == partcmd_enable) ? PRS_ROOT : PRS_ISOLATED;
|
||||||
} else if (cmd == partcmd_disable) {
|
} else if (cmd == partcmd_disable) {
|
||||||
/*
|
/*
|
||||||
@@ -1944,12 +1971,6 @@ static void compute_partition_effective_cpumask(struct cpuset *cs,
|
|||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* update_cpumasks_hier() flags
|
|
||||||
*/
|
|
||||||
#define HIER_CHECKALL 0x01 /* Check all cpusets with no skipping */
|
|
||||||
#define HIER_NO_SD_REBUILD 0x02 /* Don't rebuild sched domains */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* update_cpumasks_hier - Update effective cpumasks and tasks in the subtree
|
* update_cpumasks_hier - Update effective cpumasks and tasks in the subtree
|
||||||
* @cs: the cpuset to consider
|
* @cs: the cpuset to consider
|
||||||
@@ -1964,7 +1985,7 @@ static void compute_partition_effective_cpumask(struct cpuset *cs,
|
|||||||
* Called with cpuset_mutex held
|
* Called with cpuset_mutex held
|
||||||
*/
|
*/
|
||||||
static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp,
|
static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp,
|
||||||
int flags)
|
bool force)
|
||||||
{
|
{
|
||||||
struct cpuset *cp;
|
struct cpuset *cp;
|
||||||
struct cgroup_subsys_state *pos_css;
|
struct cgroup_subsys_state *pos_css;
|
||||||
@@ -2029,12 +2050,12 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp,
|
|||||||
* Skip the whole subtree if
|
* Skip the whole subtree if
|
||||||
* 1) the cpumask remains the same,
|
* 1) the cpumask remains the same,
|
||||||
* 2) has no partition root state,
|
* 2) has no partition root state,
|
||||||
* 3) HIER_CHECKALL flag not set, and
|
* 3) force flag not set, and
|
||||||
* 4) for v2 load balance state same as its parent.
|
* 4) for v2 load balance state same as its parent.
|
||||||
*/
|
*/
|
||||||
if (!cp->partition_root_state && !(flags & HIER_CHECKALL) &&
|
if (!cp->partition_root_state && !force &&
|
||||||
cpumask_equal(tmp->new_cpus, cp->effective_cpus) &&
|
cpumask_equal(tmp->new_cpus, cp->effective_cpus) &&
|
||||||
(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) ||
|
(!cpuset_v2() ||
|
||||||
(is_sched_load_balance(parent) == is_sched_load_balance(cp)))) {
|
(is_sched_load_balance(parent) == is_sched_load_balance(cp)))) {
|
||||||
pos_css = css_rightmost_descendant(pos_css);
|
pos_css = css_rightmost_descendant(pos_css);
|
||||||
continue;
|
continue;
|
||||||
@@ -2108,8 +2129,7 @@ get_css:
|
|||||||
* from parent if current cpuset isn't a valid partition root
|
* from parent if current cpuset isn't a valid partition root
|
||||||
* and their load balance states differ.
|
* and their load balance states differ.
|
||||||
*/
|
*/
|
||||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
if (cpuset_v2() && !is_partition_valid(cp) &&
|
||||||
!is_partition_valid(cp) &&
|
|
||||||
(is_sched_load_balance(parent) != is_sched_load_balance(cp))) {
|
(is_sched_load_balance(parent) != is_sched_load_balance(cp))) {
|
||||||
if (is_sched_load_balance(parent))
|
if (is_sched_load_balance(parent))
|
||||||
set_bit(CS_SCHED_LOAD_BALANCE, &cp->flags);
|
set_bit(CS_SCHED_LOAD_BALANCE, &cp->flags);
|
||||||
@@ -2125,8 +2145,7 @@ get_css:
|
|||||||
*/
|
*/
|
||||||
if (!cpumask_empty(cp->cpus_allowed) &&
|
if (!cpumask_empty(cp->cpus_allowed) &&
|
||||||
is_sched_load_balance(cp) &&
|
is_sched_load_balance(cp) &&
|
||||||
(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) ||
|
(!cpuset_v2() || is_partition_valid(cp)))
|
||||||
is_partition_valid(cp)))
|
|
||||||
need_rebuild_sched_domains = true;
|
need_rebuild_sched_domains = true;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
@@ -2134,9 +2153,8 @@ get_css:
|
|||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (need_rebuild_sched_domains && !(flags & HIER_NO_SD_REBUILD) &&
|
if (need_rebuild_sched_domains)
|
||||||
!force_sd_rebuild)
|
cpuset_force_rebuild();
|
||||||
rebuild_sched_domains_locked();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2163,9 +2181,7 @@ static void update_sibling_cpumasks(struct cpuset *parent, struct cpuset *cs,
|
|||||||
* directly.
|
* directly.
|
||||||
*
|
*
|
||||||
* The update_cpumasks_hier() function may sleep. So we have to
|
* The update_cpumasks_hier() function may sleep. So we have to
|
||||||
* release the RCU read lock before calling it. HIER_NO_SD_REBUILD
|
* release the RCU read lock before calling it.
|
||||||
* flag is used to suppress rebuild of sched domains as the callers
|
|
||||||
* will take care of that.
|
|
||||||
*/
|
*/
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
cpuset_for_each_child(sibling, pos_css, parent) {
|
cpuset_for_each_child(sibling, pos_css, parent) {
|
||||||
@@ -2181,7 +2197,7 @@ static void update_sibling_cpumasks(struct cpuset *parent, struct cpuset *cs,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
update_cpumasks_hier(sibling, tmp, HIER_NO_SD_REBUILD);
|
update_cpumasks_hier(sibling, tmp, false);
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
css_put(&sibling->css);
|
css_put(&sibling->css);
|
||||||
}
|
}
|
||||||
@@ -2201,7 +2217,7 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
|
|||||||
struct tmpmasks tmp;
|
struct tmpmasks tmp;
|
||||||
struct cpuset *parent = parent_cs(cs);
|
struct cpuset *parent = parent_cs(cs);
|
||||||
bool invalidate = false;
|
bool invalidate = false;
|
||||||
int hier_flags = 0;
|
bool force = false;
|
||||||
int old_prs = cs->partition_root_state;
|
int old_prs = cs->partition_root_state;
|
||||||
|
|
||||||
/* top_cpuset.cpus_allowed tracks cpu_online_mask; it's read-only */
|
/* top_cpuset.cpus_allowed tracks cpu_online_mask; it's read-only */
|
||||||
@@ -2262,12 +2278,11 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
|
|||||||
* Check all the descendants in update_cpumasks_hier() if
|
* Check all the descendants in update_cpumasks_hier() if
|
||||||
* effective_xcpus is to be changed.
|
* effective_xcpus is to be changed.
|
||||||
*/
|
*/
|
||||||
if (!cpumask_equal(cs->effective_xcpus, trialcs->effective_xcpus))
|
force = !cpumask_equal(cs->effective_xcpus, trialcs->effective_xcpus);
|
||||||
hier_flags = HIER_CHECKALL;
|
|
||||||
|
|
||||||
retval = validate_change(cs, trialcs);
|
retval = validate_change(cs, trialcs);
|
||||||
|
|
||||||
if ((retval == -EINVAL) && cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) {
|
if ((retval == -EINVAL) && cpuset_v2()) {
|
||||||
struct cgroup_subsys_state *css;
|
struct cgroup_subsys_state *css;
|
||||||
struct cpuset *cp;
|
struct cpuset *cp;
|
||||||
|
|
||||||
@@ -2331,7 +2346,7 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
|
|||||||
spin_unlock_irq(&callback_lock);
|
spin_unlock_irq(&callback_lock);
|
||||||
|
|
||||||
/* effective_cpus/effective_xcpus will be updated here */
|
/* effective_cpus/effective_xcpus will be updated here */
|
||||||
update_cpumasks_hier(cs, &tmp, hier_flags);
|
update_cpumasks_hier(cs, &tmp, force);
|
||||||
|
|
||||||
/* Update CS_SCHED_LOAD_BALANCE and/or sched_domains, if necessary */
|
/* Update CS_SCHED_LOAD_BALANCE and/or sched_domains, if necessary */
|
||||||
if (cs->partition_root_state)
|
if (cs->partition_root_state)
|
||||||
@@ -2356,7 +2371,7 @@ static int update_exclusive_cpumask(struct cpuset *cs, struct cpuset *trialcs,
|
|||||||
struct tmpmasks tmp;
|
struct tmpmasks tmp;
|
||||||
struct cpuset *parent = parent_cs(cs);
|
struct cpuset *parent = parent_cs(cs);
|
||||||
bool invalidate = false;
|
bool invalidate = false;
|
||||||
int hier_flags = 0;
|
bool force = false;
|
||||||
int old_prs = cs->partition_root_state;
|
int old_prs = cs->partition_root_state;
|
||||||
|
|
||||||
if (!*buf) {
|
if (!*buf) {
|
||||||
@@ -2379,8 +2394,7 @@ static int update_exclusive_cpumask(struct cpuset *cs, struct cpuset *trialcs,
|
|||||||
* Check all the descendants in update_cpumasks_hier() if
|
* Check all the descendants in update_cpumasks_hier() if
|
||||||
* effective_xcpus is to be changed.
|
* effective_xcpus is to be changed.
|
||||||
*/
|
*/
|
||||||
if (!cpumask_equal(cs->effective_xcpus, trialcs->effective_xcpus))
|
force = !cpumask_equal(cs->effective_xcpus, trialcs->effective_xcpus);
|
||||||
hier_flags = HIER_CHECKALL;
|
|
||||||
|
|
||||||
retval = validate_change(cs, trialcs);
|
retval = validate_change(cs, trialcs);
|
||||||
if (retval)
|
if (retval)
|
||||||
@@ -2433,8 +2447,8 @@ static int update_exclusive_cpumask(struct cpuset *cs, struct cpuset *trialcs,
|
|||||||
* of the subtree when it is a valid partition root or effective_xcpus
|
* of the subtree when it is a valid partition root or effective_xcpus
|
||||||
* is updated.
|
* is updated.
|
||||||
*/
|
*/
|
||||||
if (is_partition_valid(cs) || hier_flags)
|
if (is_partition_valid(cs) || force)
|
||||||
update_cpumasks_hier(cs, &tmp, hier_flags);
|
update_cpumasks_hier(cs, &tmp, force);
|
||||||
|
|
||||||
/* Update CS_SCHED_LOAD_BALANCE and/or sched_domains, if necessary */
|
/* Update CS_SCHED_LOAD_BALANCE and/or sched_domains, if necessary */
|
||||||
if (cs->partition_root_state)
|
if (cs->partition_root_state)
|
||||||
@@ -2759,9 +2773,12 @@ int cpuset_update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
|
|||||||
cs->flags = trialcs->flags;
|
cs->flags = trialcs->flags;
|
||||||
spin_unlock_irq(&callback_lock);
|
spin_unlock_irq(&callback_lock);
|
||||||
|
|
||||||
if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed &&
|
if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) {
|
||||||
!force_sd_rebuild)
|
if (cpuset_v2())
|
||||||
rebuild_sched_domains_locked();
|
cpuset_force_rebuild();
|
||||||
|
else
|
||||||
|
rebuild_sched_domains_locked();
|
||||||
|
}
|
||||||
|
|
||||||
if (spread_flag_changed)
|
if (spread_flag_changed)
|
||||||
cpuset1_update_tasks_flags(cs);
|
cpuset1_update_tasks_flags(cs);
|
||||||
@@ -2875,12 +2892,14 @@ out:
|
|||||||
update_unbound_workqueue_cpumask(new_xcpus_state);
|
update_unbound_workqueue_cpumask(new_xcpus_state);
|
||||||
|
|
||||||
/* Force update if switching back to member */
|
/* Force update if switching back to member */
|
||||||
update_cpumasks_hier(cs, &tmpmask, !new_prs ? HIER_CHECKALL : 0);
|
update_cpumasks_hier(cs, &tmpmask, !new_prs);
|
||||||
|
|
||||||
/* Update sched domains and load balance flag */
|
/* Update sched domains and load balance flag */
|
||||||
update_partition_sd_lb(cs, old_prs);
|
update_partition_sd_lb(cs, old_prs);
|
||||||
|
|
||||||
notify_partition_change(cs, old_prs);
|
notify_partition_change(cs, old_prs);
|
||||||
|
if (force_sd_rebuild)
|
||||||
|
rebuild_sched_domains_locked();
|
||||||
free_cpumasks(NULL, &tmpmask);
|
free_cpumasks(NULL, &tmpmask);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2941,8 +2960,7 @@ static int cpuset_can_attach(struct cgroup_taskset *tset)
|
|||||||
* migration permission derives from hierarchy ownership in
|
* migration permission derives from hierarchy ownership in
|
||||||
* cgroup_procs_write_permission()).
|
* cgroup_procs_write_permission()).
|
||||||
*/
|
*/
|
||||||
if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) ||
|
if (!cpuset_v2() || (cpus_updated || mems_updated)) {
|
||||||
(cpus_updated || mems_updated)) {
|
|
||||||
ret = security_task_setscheduler(task);
|
ret = security_task_setscheduler(task);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@@ -3056,8 +3074,7 @@ static void cpuset_attach(struct cgroup_taskset *tset)
|
|||||||
* in effective cpus and mems. In that case, we can optimize out
|
* in effective cpus and mems. In that case, we can optimize out
|
||||||
* by skipping the task iteration and update.
|
* by skipping the task iteration and update.
|
||||||
*/
|
*/
|
||||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
if (cpuset_v2() && !cpus_updated && !mems_updated) {
|
||||||
!cpus_updated && !mems_updated) {
|
|
||||||
cpuset_attach_nodemask_to = cs->effective_mems;
|
cpuset_attach_nodemask_to = cs->effective_mems;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -3151,6 +3168,8 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
|
|||||||
}
|
}
|
||||||
|
|
||||||
free_cpuset(trialcs);
|
free_cpuset(trialcs);
|
||||||
|
if (force_sd_rebuild)
|
||||||
|
rebuild_sched_domains_locked();
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&cpuset_mutex);
|
mutex_unlock(&cpuset_mutex);
|
||||||
cpus_read_unlock();
|
cpus_read_unlock();
|
||||||
@@ -3380,7 +3399,7 @@ cpuset_css_alloc(struct cgroup_subsys_state *parent_css)
|
|||||||
INIT_LIST_HEAD(&cs->remote_sibling);
|
INIT_LIST_HEAD(&cs->remote_sibling);
|
||||||
|
|
||||||
/* Set CS_MEMORY_MIGRATE for default hierarchy */
|
/* Set CS_MEMORY_MIGRATE for default hierarchy */
|
||||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys))
|
if (cpuset_v2())
|
||||||
__set_bit(CS_MEMORY_MIGRATE, &cs->flags);
|
__set_bit(CS_MEMORY_MIGRATE, &cs->flags);
|
||||||
|
|
||||||
return &cs->css;
|
return &cs->css;
|
||||||
@@ -3407,8 +3426,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
|
|||||||
/*
|
/*
|
||||||
* For v2, clear CS_SCHED_LOAD_BALANCE if parent is isolated
|
* For v2, clear CS_SCHED_LOAD_BALANCE if parent is isolated
|
||||||
*/
|
*/
|
||||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
if (cpuset_v2() && !is_sched_load_balance(parent))
|
||||||
!is_sched_load_balance(parent))
|
|
||||||
clear_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
|
clear_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
|
||||||
|
|
||||||
cpuset_inc();
|
cpuset_inc();
|
||||||
@@ -3475,11 +3493,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
|
|||||||
cpus_read_lock();
|
cpus_read_lock();
|
||||||
mutex_lock(&cpuset_mutex);
|
mutex_lock(&cpuset_mutex);
|
||||||
|
|
||||||
if (is_partition_valid(cs))
|
if (!cpuset_v2() && is_sched_load_balance(cs))
|
||||||
update_prstate(cs, 0);
|
|
||||||
|
|
||||||
if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
|
||||||
is_sched_load_balance(cs))
|
|
||||||
cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
|
cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
|
||||||
|
|
||||||
cpuset_dec();
|
cpuset_dec();
|
||||||
@@ -3489,6 +3503,22 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
|
|||||||
cpus_read_unlock();
|
cpus_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cpuset_css_killed(struct cgroup_subsys_state *css)
|
||||||
|
{
|
||||||
|
struct cpuset *cs = css_cs(css);
|
||||||
|
|
||||||
|
cpus_read_lock();
|
||||||
|
mutex_lock(&cpuset_mutex);
|
||||||
|
|
||||||
|
/* Reset valid partition back to member */
|
||||||
|
if (is_partition_valid(cs))
|
||||||
|
update_prstate(cs, PRS_MEMBER);
|
||||||
|
|
||||||
|
mutex_unlock(&cpuset_mutex);
|
||||||
|
cpus_read_unlock();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void cpuset_css_free(struct cgroup_subsys_state *css)
|
static void cpuset_css_free(struct cgroup_subsys_state *css)
|
||||||
{
|
{
|
||||||
struct cpuset *cs = css_cs(css);
|
struct cpuset *cs = css_cs(css);
|
||||||
@@ -3610,6 +3640,7 @@ struct cgroup_subsys cpuset_cgrp_subsys = {
|
|||||||
.css_alloc = cpuset_css_alloc,
|
.css_alloc = cpuset_css_alloc,
|
||||||
.css_online = cpuset_css_online,
|
.css_online = cpuset_css_online,
|
||||||
.css_offline = cpuset_css_offline,
|
.css_offline = cpuset_css_offline,
|
||||||
|
.css_killed = cpuset_css_killed,
|
||||||
.css_free = cpuset_css_free,
|
.css_free = cpuset_css_free,
|
||||||
.can_attach = cpuset_can_attach,
|
.can_attach = cpuset_can_attach,
|
||||||
.cancel_attach = cpuset_cancel_attach,
|
.cancel_attach = cpuset_cancel_attach,
|
||||||
@@ -3740,6 +3771,7 @@ retry:
|
|||||||
|
|
||||||
if (remote && cpumask_empty(&new_cpus) &&
|
if (remote && cpumask_empty(&new_cpus) &&
|
||||||
partition_is_populated(cs, NULL)) {
|
partition_is_populated(cs, NULL)) {
|
||||||
|
cs->prs_err = PERR_HOTPLUG;
|
||||||
remote_partition_disable(cs, tmp);
|
remote_partition_disable(cs, tmp);
|
||||||
compute_effective_cpumask(&new_cpus, cs, parent);
|
compute_effective_cpumask(&new_cpus, cs, parent);
|
||||||
remote = false;
|
remote = false;
|
||||||
@@ -3893,11 +3925,9 @@ static void cpuset_handle_hotplug(void)
|
|||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rebuild sched domains if cpus_allowed has changed */
|
/* rebuild sched domains if necessary */
|
||||||
if (force_sd_rebuild) {
|
if (force_sd_rebuild)
|
||||||
force_sd_rebuild = false;
|
|
||||||
rebuild_sched_domains_cpuslocked();
|
rebuild_sched_domains_cpuslocked();
|
||||||
}
|
|
||||||
|
|
||||||
free_cpumasks(NULL, ptmp);
|
free_cpumasks(NULL, ptmp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info)
|
|||||||
ret = ops->prepare_data(req_info, reply_data, info);
|
ret = ops->prepare_data(req_info, reply_data, info);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_cleanup;
|
goto err_dev;
|
||||||
ret = ops->reply_size(req_info, reply_data);
|
ret = ops->reply_size(req_info, reply_data);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_cleanup;
|
goto err_cleanup;
|
||||||
@@ -548,7 +548,7 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
|
|||||||
ret = ctx->ops->prepare_data(ctx->req_info, ctx->reply_data, info);
|
ret = ctx->ops->prepare_data(ctx->req_info, ctx->reply_data, info);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out_cancel;
|
||||||
ret = ethnl_fill_reply_header(skb, dev, ctx->ops->hdr_attr);
|
ret = ethnl_fill_reply_header(skb, dev, ctx->ops->hdr_attr);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -557,6 +557,7 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
|
|||||||
out:
|
out:
|
||||||
if (ctx->ops->cleanup_data)
|
if (ctx->ops->cleanup_data)
|
||||||
ctx->ops->cleanup_data(ctx->reply_data);
|
ctx->ops->cleanup_data(ctx->reply_data);
|
||||||
|
out_cancel:
|
||||||
ctx->reply_data->dev = NULL;
|
ctx->reply_data->dev = NULL;
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
genlmsg_cancel(skb, ehdr);
|
genlmsg_cancel(skb, ehdr);
|
||||||
@@ -760,7 +761,7 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd,
|
|||||||
ethnl_init_reply_data(reply_data, ops, dev);
|
ethnl_init_reply_data(reply_data, ops, dev);
|
||||||
ret = ops->prepare_data(req_info, reply_data, &info);
|
ret = ops->prepare_data(req_info, reply_data, &info);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_cleanup;
|
goto err_rep;
|
||||||
ret = ops->reply_size(req_info, reply_data);
|
ret = ops->reply_size(req_info, reply_data);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_cleanup;
|
goto err_cleanup;
|
||||||
@@ -795,6 +796,7 @@ err_skb:
|
|||||||
err_cleanup:
|
err_cleanup:
|
||||||
if (ops->cleanup_data)
|
if (ops->cleanup_data)
|
||||||
ops->cleanup_data(reply_data);
|
ops->cleanup_data(reply_data);
|
||||||
|
err_rep:
|
||||||
kfree(reply_data);
|
kfree(reply_data);
|
||||||
kfree(req_info);
|
kfree(req_info);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+4
-4
@@ -470,10 +470,10 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
hash = fl6->mp_hash;
|
hash = fl6->mp_hash;
|
||||||
if (hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound) &&
|
if (hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound)) {
|
||||||
rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
|
if (rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
|
||||||
strict) >= 0) {
|
strict) >= 0)
|
||||||
match = first;
|
match = first;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+45
-21
@@ -2051,6 +2051,7 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
|
|||||||
struct tcmsg *tcm;
|
struct tcmsg *tcm;
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
unsigned char *b = skb_tail_pointer(skb);
|
unsigned char *b = skb_tail_pointer(skb);
|
||||||
|
int ret = -EMSGSIZE;
|
||||||
|
|
||||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
|
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
|
||||||
if (!nlh)
|
if (!nlh)
|
||||||
@@ -2095,11 +2096,45 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
|
|||||||
|
|
||||||
return skb->len;
|
return skb->len;
|
||||||
|
|
||||||
|
cls_op_not_supp:
|
||||||
|
ret = -EOPNOTSUPP;
|
||||||
out_nlmsg_trim:
|
out_nlmsg_trim:
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
cls_op_not_supp:
|
|
||||||
nlmsg_trim(skb, b);
|
nlmsg_trim(skb, b);
|
||||||
return -1;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct sk_buff *tfilter_notify_prep(struct net *net,
|
||||||
|
struct sk_buff *oskb,
|
||||||
|
struct nlmsghdr *n,
|
||||||
|
struct tcf_proto *tp,
|
||||||
|
struct tcf_block *block,
|
||||||
|
struct Qdisc *q, u32 parent,
|
||||||
|
void *fh, int event,
|
||||||
|
u32 portid, bool rtnl_held,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
unsigned int size = oskb ? max(NLMSG_GOODSIZE, oskb->len) : NLMSG_GOODSIZE;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
skb = alloc_skb(size, GFP_KERNEL);
|
||||||
|
if (!skb)
|
||||||
|
return ERR_PTR(-ENOBUFS);
|
||||||
|
|
||||||
|
ret = tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
|
||||||
|
n->nlmsg_seq, n->nlmsg_flags, event, false,
|
||||||
|
rtnl_held, extack);
|
||||||
|
if (ret <= 0) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
if (ret == -EMSGSIZE) {
|
||||||
|
size += NLMSG_GOODSIZE;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tfilter_notify(struct net *net, struct sk_buff *oskb,
|
static int tfilter_notify(struct net *net, struct sk_buff *oskb,
|
||||||
@@ -2115,16 +2150,10 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
|
|||||||
if (!unicast && !rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC))
|
if (!unicast && !rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
|
skb = tfilter_notify_prep(net, oskb, n, tp, block, q, parent, fh, event,
|
||||||
if (!skb)
|
portid, rtnl_held, extack);
|
||||||
return -ENOBUFS;
|
if (IS_ERR(skb))
|
||||||
|
return PTR_ERR(skb);
|
||||||
if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
|
|
||||||
n->nlmsg_seq, n->nlmsg_flags, event,
|
|
||||||
false, rtnl_held, extack) <= 0) {
|
|
||||||
kfree_skb(skb);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unicast)
|
if (unicast)
|
||||||
err = rtnl_unicast(skb, net, portid);
|
err = rtnl_unicast(skb, net, portid);
|
||||||
@@ -2147,16 +2176,11 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
|
|||||||
if (!rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC))
|
if (!rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC))
|
||||||
return tp->ops->delete(tp, fh, last, rtnl_held, extack);
|
return tp->ops->delete(tp, fh, last, rtnl_held, extack);
|
||||||
|
|
||||||
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
|
skb = tfilter_notify_prep(net, oskb, n, tp, block, q, parent, fh,
|
||||||
if (!skb)
|
RTM_DELTFILTER, portid, rtnl_held, extack);
|
||||||
return -ENOBUFS;
|
if (IS_ERR(skb)) {
|
||||||
|
|
||||||
if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
|
|
||||||
n->nlmsg_seq, n->nlmsg_flags, RTM_DELTFILTER,
|
|
||||||
false, rtnl_held, extack) <= 0) {
|
|
||||||
NL_SET_ERR_MSG(extack, "Failed to build del event notification");
|
NL_SET_ERR_MSG(extack, "Failed to build del event notification");
|
||||||
kfree_skb(skb);
|
return PTR_ERR(skb);
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tp->ops->delete(tp, fh, last, rtnl_held, extack);
|
err = tp->ops->delete(tp, fh, last, rtnl_held, extack);
|
||||||
|
|||||||
@@ -65,10 +65,7 @@ static struct sk_buff *codel_qdisc_dequeue(struct Qdisc *sch)
|
|||||||
&q->stats, qdisc_pkt_len, codel_get_enqueue_time,
|
&q->stats, qdisc_pkt_len, codel_get_enqueue_time,
|
||||||
drop_func, dequeue_func);
|
drop_func, dequeue_func);
|
||||||
|
|
||||||
/* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
|
if (q->stats.drop_count) {
|
||||||
* or HTB crashes. Defer it for next round.
|
|
||||||
*/
|
|
||||||
if (q->stats.drop_count && sch->q.qlen) {
|
|
||||||
qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
|
qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
|
||||||
q->stats.drop_count = 0;
|
q->stats.drop_count = 0;
|
||||||
q->stats.drop_len = 0;
|
q->stats.drop_len = 0;
|
||||||
|
|||||||
@@ -314,10 +314,8 @@ begin:
|
|||||||
}
|
}
|
||||||
qdisc_bstats_update(sch, skb);
|
qdisc_bstats_update(sch, skb);
|
||||||
flow->deficit -= qdisc_pkt_len(skb);
|
flow->deficit -= qdisc_pkt_len(skb);
|
||||||
/* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
|
|
||||||
* or HTB crashes. Defer it for next round.
|
if (q->cstats.drop_count) {
|
||||||
*/
|
|
||||||
if (q->cstats.drop_count && sch->q.qlen) {
|
|
||||||
qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
|
qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
|
||||||
q->cstats.drop_len);
|
q->cstats.drop_len);
|
||||||
q->cstats.drop_count = 0;
|
q->cstats.drop_count = 0;
|
||||||
|
|||||||
+50
-16
@@ -631,6 +631,15 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
|
|||||||
struct red_parms *p = NULL;
|
struct red_parms *p = NULL;
|
||||||
struct sk_buff *to_free = NULL;
|
struct sk_buff *to_free = NULL;
|
||||||
struct sk_buff *tail = NULL;
|
struct sk_buff *tail = NULL;
|
||||||
|
unsigned int maxflows;
|
||||||
|
unsigned int quantum;
|
||||||
|
unsigned int divisor;
|
||||||
|
int perturb_period;
|
||||||
|
u8 headdrop;
|
||||||
|
u8 maxdepth;
|
||||||
|
int limit;
|
||||||
|
u8 flags;
|
||||||
|
|
||||||
|
|
||||||
if (opt->nla_len < nla_attr_size(sizeof(*ctl)))
|
if (opt->nla_len < nla_attr_size(sizeof(*ctl)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -652,39 +661,64 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
|
|||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
if (ctl->limit == 1) {
|
|
||||||
NL_SET_ERR_MSG_MOD(extack, "invalid limit");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
sch_tree_lock(sch);
|
sch_tree_lock(sch);
|
||||||
|
|
||||||
|
limit = q->limit;
|
||||||
|
divisor = q->divisor;
|
||||||
|
headdrop = q->headdrop;
|
||||||
|
maxdepth = q->maxdepth;
|
||||||
|
maxflows = q->maxflows;
|
||||||
|
perturb_period = q->perturb_period;
|
||||||
|
quantum = q->quantum;
|
||||||
|
flags = q->flags;
|
||||||
|
|
||||||
|
/* update and validate configuration */
|
||||||
if (ctl->quantum)
|
if (ctl->quantum)
|
||||||
q->quantum = ctl->quantum;
|
quantum = ctl->quantum;
|
||||||
WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ);
|
perturb_period = ctl->perturb_period * HZ;
|
||||||
if (ctl->flows)
|
if (ctl->flows)
|
||||||
q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
|
maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
|
||||||
if (ctl->divisor) {
|
if (ctl->divisor) {
|
||||||
q->divisor = ctl->divisor;
|
divisor = ctl->divisor;
|
||||||
q->maxflows = min_t(u32, q->maxflows, q->divisor);
|
maxflows = min_t(u32, maxflows, divisor);
|
||||||
}
|
}
|
||||||
if (ctl_v1) {
|
if (ctl_v1) {
|
||||||
if (ctl_v1->depth)
|
if (ctl_v1->depth)
|
||||||
q->maxdepth = min_t(u32, ctl_v1->depth, SFQ_MAX_DEPTH);
|
maxdepth = min_t(u32, ctl_v1->depth, SFQ_MAX_DEPTH);
|
||||||
if (p) {
|
if (p) {
|
||||||
swap(q->red_parms, p);
|
red_set_parms(p,
|
||||||
red_set_parms(q->red_parms,
|
|
||||||
ctl_v1->qth_min, ctl_v1->qth_max,
|
ctl_v1->qth_min, ctl_v1->qth_max,
|
||||||
ctl_v1->Wlog,
|
ctl_v1->Wlog,
|
||||||
ctl_v1->Plog, ctl_v1->Scell_log,
|
ctl_v1->Plog, ctl_v1->Scell_log,
|
||||||
NULL,
|
NULL,
|
||||||
ctl_v1->max_P);
|
ctl_v1->max_P);
|
||||||
}
|
}
|
||||||
q->flags = ctl_v1->flags;
|
flags = ctl_v1->flags;
|
||||||
q->headdrop = ctl_v1->headdrop;
|
headdrop = ctl_v1->headdrop;
|
||||||
}
|
}
|
||||||
if (ctl->limit) {
|
if (ctl->limit) {
|
||||||
q->limit = min_t(u32, ctl->limit, q->maxdepth * q->maxflows);
|
limit = min_t(u32, ctl->limit, maxdepth * maxflows);
|
||||||
q->maxflows = min_t(u32, q->maxflows, q->limit);
|
maxflows = min_t(u32, maxflows, limit);
|
||||||
}
|
}
|
||||||
|
if (limit == 1) {
|
||||||
|
sch_tree_unlock(sch);
|
||||||
|
kfree(p);
|
||||||
|
NL_SET_ERR_MSG_MOD(extack, "invalid limit");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* commit configuration */
|
||||||
|
q->limit = limit;
|
||||||
|
q->divisor = divisor;
|
||||||
|
q->headdrop = headdrop;
|
||||||
|
q->maxdepth = maxdepth;
|
||||||
|
q->maxflows = maxflows;
|
||||||
|
WRITE_ONCE(q->perturb_period, perturb_period);
|
||||||
|
q->quantum = quantum;
|
||||||
|
q->flags = flags;
|
||||||
|
if (p)
|
||||||
|
swap(q->red_parms, p);
|
||||||
|
|
||||||
qlen = sch->q.qlen;
|
qlen = sch->q.qlen;
|
||||||
while (sch->q.qlen > q->limit) {
|
while (sch->q.qlen > q->limit) {
|
||||||
|
|||||||
@@ -1046,6 +1046,7 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
|
|||||||
if (unlikely(l->backlog[imp].len >= l->backlog[imp].limit)) {
|
if (unlikely(l->backlog[imp].len >= l->backlog[imp].limit)) {
|
||||||
if (imp == TIPC_SYSTEM_IMPORTANCE) {
|
if (imp == TIPC_SYSTEM_IMPORTANCE) {
|
||||||
pr_warn("%s<%s>, link overflow", link_rst_msg, l->name);
|
pr_warn("%s<%s>, link overflow", link_rst_msg, l->name);
|
||||||
|
__skb_queue_purge(list);
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
rc = link_schedule_user(l, hdr);
|
rc = link_schedule_user(l, hdr);
|
||||||
|
|||||||
@@ -809,6 +809,11 @@ static int tls_setsockopt(struct sock *sk, int level, int optname,
|
|||||||
return do_tls_setsockopt(sk, optname, optval, optlen);
|
return do_tls_setsockopt(sk, optname, optval, optlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tls_disconnect(struct sock *sk, int flags)
|
||||||
|
{
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
struct tls_context *tls_ctx_create(struct sock *sk)
|
struct tls_context *tls_ctx_create(struct sock *sk)
|
||||||
{
|
{
|
||||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||||
@@ -904,6 +909,7 @@ static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG],
|
|||||||
prot[TLS_BASE][TLS_BASE] = *base;
|
prot[TLS_BASE][TLS_BASE] = *base;
|
||||||
prot[TLS_BASE][TLS_BASE].setsockopt = tls_setsockopt;
|
prot[TLS_BASE][TLS_BASE].setsockopt = tls_setsockopt;
|
||||||
prot[TLS_BASE][TLS_BASE].getsockopt = tls_getsockopt;
|
prot[TLS_BASE][TLS_BASE].getsockopt = tls_getsockopt;
|
||||||
|
prot[TLS_BASE][TLS_BASE].disconnect = tls_disconnect;
|
||||||
prot[TLS_BASE][TLS_BASE].close = tls_sk_proto_close;
|
prot[TLS_BASE][TLS_BASE].close = tls_sk_proto_close;
|
||||||
|
|
||||||
prot[TLS_SW][TLS_BASE] = prot[TLS_BASE][TLS_BASE];
|
prot[TLS_SW][TLS_BASE] = prot[TLS_BASE][TLS_BASE];
|
||||||
|
|||||||
@@ -214,6 +214,15 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_acpi_adr_device rt1316_2_group2_adr[] = {
|
||||||
|
{
|
||||||
|
.adr = 0x000232025D131601ull,
|
||||||
|
.num_endpoints = 1,
|
||||||
|
.endpoints = &spk_r_endpoint,
|
||||||
|
.name_prefix = "rt1316-2"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = {
|
static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = {
|
||||||
{
|
{
|
||||||
.adr = 0x000130025D131601ull,
|
.adr = 0x000130025D131601ull,
|
||||||
@@ -547,6 +556,20 @@ static const struct snd_soc_acpi_link_adr adl_chromebook_base[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link02[] = {
|
||||||
|
{
|
||||||
|
.mask = BIT(0),
|
||||||
|
.num_adr = ARRAY_SIZE(rt1316_0_group2_adr),
|
||||||
|
.adr_d = rt1316_0_group2_adr,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mask = BIT(2),
|
||||||
|
.num_adr = ARRAY_SIZE(rt1316_2_group2_adr),
|
||||||
|
.adr_d = rt1316_2_group2_adr,
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
static const struct snd_soc_acpi_codecs adl_max98357a_amp = {
|
static const struct snd_soc_acpi_codecs adl_max98357a_amp = {
|
||||||
.num_codecs = 1,
|
.num_codecs = 1,
|
||||||
.codecs = {"MX98357A"}
|
.codecs = {"MX98357A"}
|
||||||
@@ -749,6 +772,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
|
|||||||
.drv_name = "sof_sdw",
|
.drv_name = "sof_sdw",
|
||||||
.sof_tplg_filename = "sof-adl-sdw-max98373-rt5682.tplg",
|
.sof_tplg_filename = "sof-adl-sdw-max98373-rt5682.tplg",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.link_mask = BIT(0) | BIT(2),
|
||||||
|
.links = adl_sdw_rt1316_link02,
|
||||||
|
.drv_name = "sof_sdw",
|
||||||
|
.sof_tplg_filename = "sof-adl-rt1316-l02.tplg",
|
||||||
|
},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_sdw_machines);
|
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_sdw_machines);
|
||||||
|
|||||||
@@ -3990,6 +3990,11 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
|
|||||||
WARN_INSN(insn, "RET before UNTRAIN");
|
WARN_INSN(insn, "RET before UNTRAIN");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case INSN_CONTEXT_SWITCH:
|
||||||
|
if (insn_func(insn))
|
||||||
|
break;
|
||||||
|
return 0;
|
||||||
|
|
||||||
case INSN_NOP:
|
case INSN_NOP:
|
||||||
if (insn->retpoline_safe)
|
if (insn->retpoline_safe)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user