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/pgtable.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
|
||||
#include <asm/e820/api.h>
|
||||
#include <asm/irqdomain.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)
|
||||
/* 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) {
|
||||
pr_warn("MPS support code is not built-in, using acpi=off or acpi=noirq or pci=noacpi may have problem\n");
|
||||
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,
|
||||
resource_size(cmd_res));
|
||||
if (!ap->ioaddr.cmd_addr)
|
||||
return -ENOMEM;
|
||||
ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
|
||||
resource_size(ctl_res));
|
||||
if (!ap->ioaddr.ctl_addr)
|
||||
return -ENOMEM;
|
||||
ap->ioaddr.bmdma_addr = devm_ioremap(&pdev->dev, dma_res->start,
|
||||
resource_size(dma_res));
|
||||
if (!ap->ioaddr.bmdma_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Adjust register offsets
|
||||
|
||||
@@ -1117,9 +1117,14 @@ static int pdc20621_prog_dimm0(struct ata_host *host)
|
||||
mmio += PDC_CHIP0_OFS;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pdc_i2c_read_data); i++)
|
||||
pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
pdc_i2c_read_data[i].reg,
|
||||
&spd0[pdc_i2c_read_data[i].ofs]);
|
||||
if (!pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
|
||||
pdc_i2c_read_data[i].reg,
|
||||
&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[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) */
|
||||
size = pdc20621_prog_dimm0(host);
|
||||
if (size < 0)
|
||||
return size;
|
||||
dev_dbg(host->dev, "Local DIMM Size = %dMB\n", size);
|
||||
|
||||
/* Programming DIMM Module Global Control Register (index_CID0:88h) */
|
||||
|
||||
@@ -681,22 +681,44 @@ static int ublk_max_cmd_buf_size(void)
|
||||
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) &&
|
||||
(ubq->flags & UBLK_F_USER_RECOVERY_REISSUE);
|
||||
return (ub->dev_info.flags & UBLK_F_USER_RECOVERY) &&
|
||||
(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;
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -1059,6 +1081,25 @@ static void ublk_complete_rq(struct kref *ref)
|
||||
__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
|
||||
* 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);
|
||||
|
||||
if (ublk_queue_can_use_recovery_reissue(ubq))
|
||||
blk_mq_requeue_request(req, false);
|
||||
else
|
||||
ublk_put_req_ref(ubq, req);
|
||||
if (ublk_need_req_ref(ubq)) {
|
||||
struct ublk_rq_data *data = blk_mq_rq_to_pdu(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,
|
||||
@@ -1100,7 +1144,7 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq,
|
||||
struct request *rq)
|
||||
{
|
||||
/* 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);
|
||||
else
|
||||
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;
|
||||
|
||||
if (ublk_abort_requests(ub, ubq)) {
|
||||
if (ublk_can_use_recovery(ub))
|
||||
schedule_work(&ub->quiesce_work);
|
||||
else
|
||||
if (ublk_nosrv_should_stop_dev(ub))
|
||||
schedule_work(&ub->stop_work);
|
||||
else
|
||||
schedule_work(&ub->quiesce_work);
|
||||
}
|
||||
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
|
||||
* 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;
|
||||
|
||||
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);
|
||||
|
||||
if (need_schedule) {
|
||||
if (ublk_can_use_recovery(ub))
|
||||
schedule_work(&ub->quiesce_work);
|
||||
else
|
||||
if (ublk_nosrv_should_stop_dev(ub))
|
||||
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);
|
||||
if (ub->dev_info.state == UBLK_S_DEV_DEAD)
|
||||
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)
|
||||
__ublk_quiesce_dev(ub);
|
||||
ublk_unquiesce_dev(ub);
|
||||
@@ -2738,7 +2782,7 @@ static int ublk_ctrl_start_recovery(struct ublk_device *ub,
|
||||
int i;
|
||||
|
||||
mutex_lock(&ub->mutex);
|
||||
if (!ublk_can_use_recovery(ub))
|
||||
if (ublk_nosrv_should_stop_dev(ub))
|
||||
goto out_unlock;
|
||||
if (!ub->nr_queues_ready)
|
||||
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);
|
||||
|
||||
mutex_lock(&ub->mutex);
|
||||
if (!ublk_can_use_recovery(ub))
|
||||
if (ublk_nosrv_should_stop_dev(ub))
|
||||
goto out_unlock;
|
||||
|
||||
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,hx8369", "gpios-reset", false },
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_MTD_NAND_JZ4780)
|
||||
/*
|
||||
* The rb-gpios semantics was undocumented and qi,lb60 (along with
|
||||
* 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_EI_MODE(1);
|
||||
|
||||
/*
|
||||
* BSpec 52698 - Render powergating must be off.
|
||||
* FIXME BSpec is outdated, disabling powergating for MTL is just
|
||||
* temporary wa and should be removed after fixing real cause
|
||||
* 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;
|
||||
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)) {
|
||||
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")
|
||||
static int check_huc_loading_mode(struct intel_huc *huc)
|
||||
{
|
||||
@@ -414,12 +419,6 @@ out:
|
||||
|
||||
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)
|
||||
i915_vma_unpin_and_release(&huc->heci_pkt, 0);
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ struct intel_huc {
|
||||
|
||||
int intel_huc_sanitize(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);
|
||||
void intel_huc_fini(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)
|
||||
{
|
||||
intel_huc_fini_late(&uc->huc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
|
||||
#include <linux/random.h>
|
||||
|
||||
#include "gt/intel_gt.h"
|
||||
#include "gt/intel_gt_pm.h"
|
||||
#include "gt/intel_gt_regs.h"
|
||||
#include "gt/uc/intel_gsc_fw.h"
|
||||
|
||||
#include "i915_driver.h"
|
||||
@@ -253,11 +255,27 @@ int i915_mock_selftests(void)
|
||||
int i915_live_selftests(struct pci_dev *pdev)
|
||||
{
|
||||
struct drm_i915_private *i915 = pdev_to_i915(pdev);
|
||||
struct intel_uncore *uncore = &i915->uncore;
|
||||
int err;
|
||||
u32 pg_enable;
|
||||
intel_wakeref_t wakeref;
|
||||
|
||||
if (!i915_selftest.live)
|
||||
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_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);
|
||||
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,
|
||||
drm_mode_parse_command_line_for_connector(cmdline,
|
||||
connector,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <kunit/test.h>
|
||||
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_kunit_helpers.h>
|
||||
#include <drm/drm_modes.h>
|
||||
|
||||
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)
|
||||
{
|
||||
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 = { };
|
||||
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,
|
||||
&no_connector, &mode));
|
||||
|
||||
@@ -319,6 +319,28 @@ static void kunit_action_drm_mode_destroy(void *ptr)
|
||||
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
|
||||
* @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_display_mode *mode;
|
||||
int ret;
|
||||
|
||||
mode = drm_analog_tv_mode(priv->drm,
|
||||
DRM_MODE_TV_MODE_NTSC,
|
||||
@@ -47,6 +48,9 @@ static void drm_test_modes_analog_tv_ntsc_480i(struct kunit *test)
|
||||
true);
|
||||
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, 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_display_mode *expected, *mode;
|
||||
int ret;
|
||||
|
||||
expected = drm_analog_tv_mode(priv->drm,
|
||||
DRM_MODE_TV_MODE_NTSC,
|
||||
@@ -77,9 +82,15 @@ static void drm_test_modes_analog_tv_ntsc_480i_inlined(struct kunit *test)
|
||||
true);
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -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_display_mode *mode;
|
||||
int ret;
|
||||
|
||||
mode = drm_analog_tv_mode(priv->drm,
|
||||
DRM_MODE_TV_MODE_PAL,
|
||||
@@ -94,6 +106,9 @@ static void drm_test_modes_analog_tv_pal_576i(struct kunit *test)
|
||||
true);
|
||||
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, 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_display_mode *expected, *mode;
|
||||
int ret;
|
||||
|
||||
expected = drm_analog_tv_mode(priv->drm,
|
||||
DRM_MODE_TV_MODE_PAL,
|
||||
@@ -124,9 +140,15 @@ static void drm_test_modes_analog_tv_pal_576i_inlined(struct kunit *test)
|
||||
true);
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
|
||||
struct drm_connector *connector = &priv->connector;
|
||||
struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
|
||||
struct drm_display_mode *mode;
|
||||
const struct drm_display_mode *expected;
|
||||
struct drm_display_mode *expected;
|
||||
size_t len;
|
||||
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, 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) {
|
||||
@@ -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_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);
|
||||
|
||||
@@ -32,14 +32,61 @@ bool xe_hw_engine_timeout_in_range(u64 timeout, u64 min, u64 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);
|
||||
}
|
||||
|
||||
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 = {
|
||||
.release = kobj_xe_hw_engine_release,
|
||||
.sysfs_ops = &kobj_sysfs_ops
|
||||
.release = xe_hw_engine_sysfs_kobj_release,
|
||||
.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,
|
||||
@@ -543,7 +590,7 @@ static int xe_add_hw_engine_class_defaults(struct xe_device *xe,
|
||||
if (!kobj)
|
||||
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");
|
||||
if (err)
|
||||
goto err_object;
|
||||
@@ -559,57 +606,6 @@ err_object:
|
||||
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)
|
||||
{
|
||||
@@ -640,7 +636,7 @@ int xe_hw_engine_class_sysfs_init(struct xe_gt *gt)
|
||||
if (!kobj)
|
||||
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");
|
||||
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);
|
||||
} 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 */
|
||||
if (level == pfvf->qos.link_cfg_lvl) {
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
bi->page_dma = dma;
|
||||
|
||||
@@ -289,6 +289,46 @@ static bool phy_drv_wol_enabled(struct phy_device *phydev)
|
||||
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)
|
||||
{
|
||||
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
|
||||
* lead to a deadlock.
|
||||
*/
|
||||
if (phydev->attached_dev && phydev->adjust_link)
|
||||
if (phy_uses_state_machine(phydev))
|
||||
phy_stop_machine(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);
|
||||
|
||||
return 0;
|
||||
@@ -1101,19 +1141,6 @@ struct phy_device *phy_find_first(struct mii_bus *bus)
|
||||
}
|
||||
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
|
||||
* @phydev: target phy_device struct
|
||||
|
||||
@@ -478,7 +478,7 @@ fcloop_t2h_xmt_ls_rsp(struct nvme_fc_local_port *localport,
|
||||
if (targetport) {
|
||||
tport = targetport->private;
|
||||
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);
|
||||
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.sha512);
|
||||
|
||||
if (!SERVER_IS_CHAN(server)) {
|
||||
if (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 {
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4576,9 +4576,9 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
if (unlikely(!server->secmech.dec))
|
||||
return -EIO;
|
||||
|
||||
rc = smb3_crypto_aead_allocate(server);
|
||||
if (unlikely(rc))
|
||||
return rc;
|
||||
tfm = server->secmech.dec;
|
||||
}
|
||||
|
||||
|
||||
@@ -1269,15 +1269,8 @@ SMB2_negotiate(const unsigned int xid,
|
||||
cifs_server_dbg(VFS, "Missing expected negotiate contexts\n");
|
||||
}
|
||||
|
||||
if (server->cipher_type && !rc) {
|
||||
if (!SERVER_IS_CHAN(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;
|
||||
}
|
||||
}
|
||||
if (server->cipher_type && !rc)
|
||||
rc = smb3_crypto_aead_allocate(server);
|
||||
neg_exit:
|
||||
free_rsp_buf(resp_buftype, rsp);
|
||||
return rc;
|
||||
|
||||
@@ -120,6 +120,9 @@ drm_kunit_helper_create_crtc(struct kunit *test,
|
||||
const struct drm_crtc_funcs *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 *
|
||||
drm_kunit_display_mode_from_cea_vic(struct kunit *test, struct drm_device *dev,
|
||||
u8 video_code);
|
||||
|
||||
@@ -711,6 +711,7 @@ struct cgroup_subsys {
|
||||
void (*css_released)(struct cgroup_subsys_state *css);
|
||||
void (*css_free)(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);
|
||||
int (*css_extra_stat_show)(struct seq_file *seq,
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -5946,6 +5946,12 @@ static void kill_css(struct cgroup_subsys_state *css)
|
||||
if (css->flags & CSS_DYING)
|
||||
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;
|
||||
|
||||
/*
|
||||
|
||||
@@ -85,9 +85,19 @@ static bool have_boot_isolcpus;
|
||||
static struct list_head remote_children;
|
||||
|
||||
/*
|
||||
* A flag to force sched domain rebuild at the end of an operation while
|
||||
* inhibiting it in the intermediate stages when set. Currently it is only
|
||||
* set in hotplug code.
|
||||
* A flag to force sched domain rebuild at the end of an operation.
|
||||
* It can be set in
|
||||
* - 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;
|
||||
|
||||
@@ -284,6 +294,12 @@ static inline void dec_attach_in_progress(struct cpuset *cs)
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
return cgroup_subsys_on_dfl(cpuset_cgrp_subsys) ||
|
||||
return cpuset_v2() ||
|
||||
(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 */
|
||||
struct cgroup_subsys_state *pos_css;
|
||||
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;
|
||||
|
||||
doms = NULL;
|
||||
@@ -999,6 +1015,7 @@ void rebuild_sched_domains_locked(void)
|
||||
|
||||
lockdep_assert_cpus_held();
|
||||
lockdep_assert_held(&cpuset_mutex);
|
||||
force_sd_rebuild = false;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
if (rebuild_domains && !force_sd_rebuild)
|
||||
rebuild_sched_domains_locked();
|
||||
if (rebuild_domains)
|
||||
cpuset_force_rebuild();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1209,7 +1226,7 @@ static void reset_partition_data(struct cpuset *cs)
|
||||
{
|
||||
struct cpuset *parent = parent_cs(cs);
|
||||
|
||||
if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys))
|
||||
if (!cpuset_v2())
|
||||
return;
|
||||
|
||||
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);
|
||||
spin_unlock_irq(&callback_lock);
|
||||
update_unbound_workqueue_cpumask(isolcpus_updated);
|
||||
cs->prs_err = 0;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
isolcpus_updated = partition_xcpus_del(cs->partition_root_state,
|
||||
NULL, tmp->new_cpus);
|
||||
cs->partition_root_state = -cs->partition_root_state;
|
||||
if (!cs->prs_err)
|
||||
cs->prs_err = PERR_INVCPUS;
|
||||
if (cs->prs_err)
|
||||
cs->partition_root_state = -cs->partition_root_state;
|
||||
else
|
||||
cs->partition_root_state = PRS_MEMBER;
|
||||
|
||||
reset_partition_data(cs);
|
||||
spin_unlock_irq(&callback_lock);
|
||||
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));
|
||||
|
||||
if (cpumask_empty(newmask))
|
||||
if (cpumask_empty(newmask)) {
|
||||
cs->prs_err = PERR_CPUSEMPTY;
|
||||
goto invalidate;
|
||||
}
|
||||
|
||||
adding = cpumask_andnot(tmp->addmask, newmask, cs->effective_xcpus);
|
||||
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
|
||||
* left in the top cpuset.
|
||||
*/
|
||||
if (adding && (!capable(CAP_SYS_ADMIN) ||
|
||||
cpumask_intersects(tmp->addmask, subpartitions_cpus) ||
|
||||
cpumask_subset(top_cpuset.effective_cpus, tmp->addmask)))
|
||||
goto invalidate;
|
||||
if (adding) {
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
cs->prs_err = PERR_ACCESS;
|
||||
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);
|
||||
if (adding)
|
||||
@@ -1534,8 +1561,8 @@ static void remote_partition_check(struct cpuset *cs, struct cpumask *newmask,
|
||||
remote_partition_disable(child, tmp);
|
||||
disable_cnt++;
|
||||
}
|
||||
if (disable_cnt && !force_sd_rebuild)
|
||||
rebuild_sched_domains_locked();
|
||||
if (disable_cnt)
|
||||
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
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
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)
|
||||
return PERR_NOCPUS;
|
||||
|
||||
cpumask_copy(tmp->delmask, xcpus);
|
||||
deleting = true;
|
||||
subparts_delta++;
|
||||
deleting = cpumask_and(tmp->delmask, xcpus, parent->effective_xcpus);
|
||||
if (deleting)
|
||||
subparts_delta++;
|
||||
new_prs = (cmd == partcmd_enable) ? PRS_ROOT : PRS_ISOLATED;
|
||||
} else if (cmd == partcmd_disable) {
|
||||
/*
|
||||
@@ -1944,12 +1971,6 @@ static void compute_partition_effective_cpumask(struct cpuset *cs,
|
||||
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
|
||||
* @cs: the cpuset to consider
|
||||
@@ -1964,7 +1985,7 @@ static void compute_partition_effective_cpumask(struct cpuset *cs,
|
||||
* Called with cpuset_mutex held
|
||||
*/
|
||||
static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp,
|
||||
int flags)
|
||||
bool force)
|
||||
{
|
||||
struct cpuset *cp;
|
||||
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
|
||||
* 1) the cpumask remains the same,
|
||||
* 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.
|
||||
*/
|
||||
if (!cp->partition_root_state && !(flags & HIER_CHECKALL) &&
|
||||
if (!cp->partition_root_state && !force &&
|
||||
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)))) {
|
||||
pos_css = css_rightmost_descendant(pos_css);
|
||||
continue;
|
||||
@@ -2108,8 +2129,7 @@ get_css:
|
||||
* from parent if current cpuset isn't a valid partition root
|
||||
* and their load balance states differ.
|
||||
*/
|
||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
!is_partition_valid(cp) &&
|
||||
if (cpuset_v2() && !is_partition_valid(cp) &&
|
||||
(is_sched_load_balance(parent) != is_sched_load_balance(cp))) {
|
||||
if (is_sched_load_balance(parent))
|
||||
set_bit(CS_SCHED_LOAD_BALANCE, &cp->flags);
|
||||
@@ -2125,8 +2145,7 @@ get_css:
|
||||
*/
|
||||
if (!cpumask_empty(cp->cpus_allowed) &&
|
||||
is_sched_load_balance(cp) &&
|
||||
(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) ||
|
||||
is_partition_valid(cp)))
|
||||
(!cpuset_v2() || is_partition_valid(cp)))
|
||||
need_rebuild_sched_domains = true;
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -2134,9 +2153,8 @@ get_css:
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (need_rebuild_sched_domains && !(flags & HIER_NO_SD_REBUILD) &&
|
||||
!force_sd_rebuild)
|
||||
rebuild_sched_domains_locked();
|
||||
if (need_rebuild_sched_domains)
|
||||
cpuset_force_rebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2163,9 +2181,7 @@ static void update_sibling_cpumasks(struct cpuset *parent, struct cpuset *cs,
|
||||
* directly.
|
||||
*
|
||||
* The update_cpumasks_hier() function may sleep. So we have to
|
||||
* release the RCU read lock before calling it. HIER_NO_SD_REBUILD
|
||||
* flag is used to suppress rebuild of sched domains as the callers
|
||||
* will take care of that.
|
||||
* release the RCU read lock before calling it.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
cpuset_for_each_child(sibling, pos_css, parent) {
|
||||
@@ -2181,7 +2197,7 @@ static void update_sibling_cpumasks(struct cpuset *parent, struct cpuset *cs,
|
||||
continue;
|
||||
|
||||
rcu_read_unlock();
|
||||
update_cpumasks_hier(sibling, tmp, HIER_NO_SD_REBUILD);
|
||||
update_cpumasks_hier(sibling, tmp, false);
|
||||
rcu_read_lock();
|
||||
css_put(&sibling->css);
|
||||
}
|
||||
@@ -2201,7 +2217,7 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
|
||||
struct tmpmasks tmp;
|
||||
struct cpuset *parent = parent_cs(cs);
|
||||
bool invalidate = false;
|
||||
int hier_flags = 0;
|
||||
bool force = false;
|
||||
int old_prs = cs->partition_root_state;
|
||||
|
||||
/* 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
|
||||
* effective_xcpus is to be changed.
|
||||
*/
|
||||
if (!cpumask_equal(cs->effective_xcpus, trialcs->effective_xcpus))
|
||||
hier_flags = HIER_CHECKALL;
|
||||
force = !cpumask_equal(cs->effective_xcpus, trialcs->effective_xcpus);
|
||||
|
||||
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 cpuset *cp;
|
||||
|
||||
@@ -2331,7 +2346,7 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
|
||||
spin_unlock_irq(&callback_lock);
|
||||
|
||||
/* 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 */
|
||||
if (cs->partition_root_state)
|
||||
@@ -2356,7 +2371,7 @@ static int update_exclusive_cpumask(struct cpuset *cs, struct cpuset *trialcs,
|
||||
struct tmpmasks tmp;
|
||||
struct cpuset *parent = parent_cs(cs);
|
||||
bool invalidate = false;
|
||||
int hier_flags = 0;
|
||||
bool force = false;
|
||||
int old_prs = cs->partition_root_state;
|
||||
|
||||
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
|
||||
* effective_xcpus is to be changed.
|
||||
*/
|
||||
if (!cpumask_equal(cs->effective_xcpus, trialcs->effective_xcpus))
|
||||
hier_flags = HIER_CHECKALL;
|
||||
force = !cpumask_equal(cs->effective_xcpus, trialcs->effective_xcpus);
|
||||
|
||||
retval = validate_change(cs, trialcs);
|
||||
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
|
||||
* is updated.
|
||||
*/
|
||||
if (is_partition_valid(cs) || hier_flags)
|
||||
update_cpumasks_hier(cs, &tmp, hier_flags);
|
||||
if (is_partition_valid(cs) || force)
|
||||
update_cpumasks_hier(cs, &tmp, force);
|
||||
|
||||
/* Update CS_SCHED_LOAD_BALANCE and/or sched_domains, if necessary */
|
||||
if (cs->partition_root_state)
|
||||
@@ -2759,9 +2773,12 @@ int cpuset_update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
|
||||
cs->flags = trialcs->flags;
|
||||
spin_unlock_irq(&callback_lock);
|
||||
|
||||
if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed &&
|
||||
!force_sd_rebuild)
|
||||
rebuild_sched_domains_locked();
|
||||
if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) {
|
||||
if (cpuset_v2())
|
||||
cpuset_force_rebuild();
|
||||
else
|
||||
rebuild_sched_domains_locked();
|
||||
}
|
||||
|
||||
if (spread_flag_changed)
|
||||
cpuset1_update_tasks_flags(cs);
|
||||
@@ -2875,12 +2892,14 @@ out:
|
||||
update_unbound_workqueue_cpumask(new_xcpus_state);
|
||||
|
||||
/* 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_partition_sd_lb(cs, old_prs);
|
||||
|
||||
notify_partition_change(cs, old_prs);
|
||||
if (force_sd_rebuild)
|
||||
rebuild_sched_domains_locked();
|
||||
free_cpumasks(NULL, &tmpmask);
|
||||
return 0;
|
||||
}
|
||||
@@ -2941,8 +2960,7 @@ static int cpuset_can_attach(struct cgroup_taskset *tset)
|
||||
* migration permission derives from hierarchy ownership in
|
||||
* cgroup_procs_write_permission()).
|
||||
*/
|
||||
if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) ||
|
||||
(cpus_updated || mems_updated)) {
|
||||
if (!cpuset_v2() || (cpus_updated || mems_updated)) {
|
||||
ret = security_task_setscheduler(task);
|
||||
if (ret)
|
||||
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
|
||||
* by skipping the task iteration and update.
|
||||
*/
|
||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
!cpus_updated && !mems_updated) {
|
||||
if (cpuset_v2() && !cpus_updated && !mems_updated) {
|
||||
cpuset_attach_nodemask_to = cs->effective_mems;
|
||||
goto out;
|
||||
}
|
||||
@@ -3151,6 +3168,8 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
|
||||
}
|
||||
|
||||
free_cpuset(trialcs);
|
||||
if (force_sd_rebuild)
|
||||
rebuild_sched_domains_locked();
|
||||
out_unlock:
|
||||
mutex_unlock(&cpuset_mutex);
|
||||
cpus_read_unlock();
|
||||
@@ -3380,7 +3399,7 @@ cpuset_css_alloc(struct cgroup_subsys_state *parent_css)
|
||||
INIT_LIST_HEAD(&cs->remote_sibling);
|
||||
|
||||
/* 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);
|
||||
|
||||
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
|
||||
*/
|
||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
!is_sched_load_balance(parent))
|
||||
if (cpuset_v2() && !is_sched_load_balance(parent))
|
||||
clear_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
|
||||
|
||||
cpuset_inc();
|
||||
@@ -3475,11 +3493,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
|
||||
cpus_read_lock();
|
||||
mutex_lock(&cpuset_mutex);
|
||||
|
||||
if (is_partition_valid(cs))
|
||||
update_prstate(cs, 0);
|
||||
|
||||
if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
is_sched_load_balance(cs))
|
||||
if (!cpuset_v2() && is_sched_load_balance(cs))
|
||||
cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
|
||||
|
||||
cpuset_dec();
|
||||
@@ -3489,6 +3503,22 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
|
||||
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)
|
||||
{
|
||||
struct cpuset *cs = css_cs(css);
|
||||
@@ -3610,6 +3640,7 @@ struct cgroup_subsys cpuset_cgrp_subsys = {
|
||||
.css_alloc = cpuset_css_alloc,
|
||||
.css_online = cpuset_css_online,
|
||||
.css_offline = cpuset_css_offline,
|
||||
.css_killed = cpuset_css_killed,
|
||||
.css_free = cpuset_css_free,
|
||||
.can_attach = cpuset_can_attach,
|
||||
.cancel_attach = cpuset_cancel_attach,
|
||||
@@ -3740,6 +3771,7 @@ retry:
|
||||
|
||||
if (remote && cpumask_empty(&new_cpus) &&
|
||||
partition_is_populated(cs, NULL)) {
|
||||
cs->prs_err = PERR_HOTPLUG;
|
||||
remote_partition_disable(cs, tmp);
|
||||
compute_effective_cpumask(&new_cpus, cs, parent);
|
||||
remote = false;
|
||||
@@ -3893,11 +3925,9 @@ static void cpuset_handle_hotplug(void)
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/* rebuild sched domains if cpus_allowed has changed */
|
||||
if (force_sd_rebuild) {
|
||||
force_sd_rebuild = false;
|
||||
/* rebuild sched domains if necessary */
|
||||
if (force_sd_rebuild)
|
||||
rebuild_sched_domains_cpuslocked();
|
||||
}
|
||||
|
||||
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);
|
||||
rtnl_unlock();
|
||||
if (ret < 0)
|
||||
goto err_cleanup;
|
||||
goto err_dev;
|
||||
ret = ops->reply_size(req_info, reply_data);
|
||||
if (ret < 0)
|
||||
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);
|
||||
rtnl_unlock();
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
goto out_cancel;
|
||||
ret = ethnl_fill_reply_header(skb, dev, ctx->ops->hdr_attr);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@@ -557,6 +557,7 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
|
||||
out:
|
||||
if (ctx->ops->cleanup_data)
|
||||
ctx->ops->cleanup_data(ctx->reply_data);
|
||||
out_cancel:
|
||||
ctx->reply_data->dev = NULL;
|
||||
if (ret < 0)
|
||||
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);
|
||||
ret = ops->prepare_data(req_info, reply_data, &info);
|
||||
if (ret < 0)
|
||||
goto err_cleanup;
|
||||
goto err_rep;
|
||||
ret = ops->reply_size(req_info, reply_data);
|
||||
if (ret < 0)
|
||||
goto err_cleanup;
|
||||
@@ -795,6 +796,7 @@ err_skb:
|
||||
err_cleanup:
|
||||
if (ops->cleanup_data)
|
||||
ops->cleanup_data(reply_data);
|
||||
err_rep:
|
||||
kfree(reply_data);
|
||||
kfree(req_info);
|
||||
return;
|
||||
|
||||
@@ -470,10 +470,10 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
|
||||
goto out;
|
||||
|
||||
hash = fl6->mp_hash;
|
||||
if (hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound) &&
|
||||
rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
|
||||
strict) >= 0) {
|
||||
match = first;
|
||||
if (hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound)) {
|
||||
if (rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
|
||||
strict) >= 0)
|
||||
match = first;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -2051,6 +2051,7 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
|
||||
struct tcmsg *tcm;
|
||||
struct nlmsghdr *nlh;
|
||||
unsigned char *b = skb_tail_pointer(skb);
|
||||
int ret = -EMSGSIZE;
|
||||
|
||||
nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
|
||||
if (!nlh)
|
||||
@@ -2095,11 +2096,45 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
|
||||
|
||||
return skb->len;
|
||||
|
||||
cls_op_not_supp:
|
||||
ret = -EOPNOTSUPP;
|
||||
out_nlmsg_trim:
|
||||
nla_put_failure:
|
||||
cls_op_not_supp:
|
||||
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,
|
||||
@@ -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))
|
||||
return 0;
|
||||
|
||||
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOBUFS;
|
||||
|
||||
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;
|
||||
}
|
||||
skb = tfilter_notify_prep(net, oskb, n, tp, block, q, parent, fh, event,
|
||||
portid, rtnl_held, extack);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
if (unicast)
|
||||
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))
|
||||
return tp->ops->delete(tp, fh, last, rtnl_held, extack);
|
||||
|
||||
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOBUFS;
|
||||
|
||||
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) {
|
||||
skb = tfilter_notify_prep(net, oskb, n, tp, block, q, parent, fh,
|
||||
RTM_DELTFILTER, portid, rtnl_held, extack);
|
||||
if (IS_ERR(skb)) {
|
||||
NL_SET_ERR_MSG(extack, "Failed to build del event notification");
|
||||
kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
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,
|
||||
drop_func, dequeue_func);
|
||||
|
||||
/* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
|
||||
* or HTB crashes. Defer it for next round.
|
||||
*/
|
||||
if (q->stats.drop_count && sch->q.qlen) {
|
||||
if (q->stats.drop_count) {
|
||||
qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
|
||||
q->stats.drop_count = 0;
|
||||
q->stats.drop_len = 0;
|
||||
|
||||
@@ -314,10 +314,8 @@ begin:
|
||||
}
|
||||
qdisc_bstats_update(sch, 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 && sch->q.qlen) {
|
||||
|
||||
if (q->cstats.drop_count) {
|
||||
qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
|
||||
q->cstats.drop_len);
|
||||
q->cstats.drop_count = 0;
|
||||
|
||||
@@ -631,6 +631,15 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
struct red_parms *p = NULL;
|
||||
struct sk_buff *to_free = 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)))
|
||||
return -EINVAL;
|
||||
@@ -652,39 +661,64 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (ctl->limit == 1) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "invalid limit");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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)
|
||||
q->quantum = ctl->quantum;
|
||||
WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ);
|
||||
quantum = ctl->quantum;
|
||||
perturb_period = ctl->perturb_period * HZ;
|
||||
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) {
|
||||
q->divisor = ctl->divisor;
|
||||
q->maxflows = min_t(u32, q->maxflows, q->divisor);
|
||||
divisor = ctl->divisor;
|
||||
maxflows = min_t(u32, maxflows, divisor);
|
||||
}
|
||||
if (ctl_v1) {
|
||||
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) {
|
||||
swap(q->red_parms, p);
|
||||
red_set_parms(q->red_parms,
|
||||
red_set_parms(p,
|
||||
ctl_v1->qth_min, ctl_v1->qth_max,
|
||||
ctl_v1->Wlog,
|
||||
ctl_v1->Plog, ctl_v1->Scell_log,
|
||||
NULL,
|
||||
ctl_v1->max_P);
|
||||
}
|
||||
q->flags = ctl_v1->flags;
|
||||
q->headdrop = ctl_v1->headdrop;
|
||||
flags = ctl_v1->flags;
|
||||
headdrop = ctl_v1->headdrop;
|
||||
}
|
||||
if (ctl->limit) {
|
||||
q->limit = min_t(u32, ctl->limit, q->maxdepth * q->maxflows);
|
||||
q->maxflows = min_t(u32, q->maxflows, q->limit);
|
||||
limit = min_t(u32, ctl->limit, maxdepth * maxflows);
|
||||
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;
|
||||
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 (imp == TIPC_SYSTEM_IMPORTANCE) {
|
||||
pr_warn("%s<%s>, link overflow", link_rst_msg, l->name);
|
||||
__skb_queue_purge(list);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
static int tls_disconnect(struct sock *sk, int flags)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
struct tls_context *tls_ctx_create(struct sock *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].setsockopt = tls_setsockopt;
|
||||
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_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[] = {
|
||||
{
|
||||
.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 = {
|
||||
.num_codecs = 1,
|
||||
.codecs = {"MX98357A"}
|
||||
@@ -749,6 +772,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
|
||||
.drv_name = "sof_sdw",
|
||||
.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);
|
||||
|
||||
@@ -3990,6 +3990,11 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
|
||||
WARN_INSN(insn, "RET before UNTRAIN");
|
||||
return 1;
|
||||
|
||||
case INSN_CONTEXT_SWITCH:
|
||||
if (insn_func(insn))
|
||||
break;
|
||||
return 0;
|
||||
|
||||
case INSN_NOP:
|
||||
if (insn->retpoline_safe)
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user