From owner-svn-src-head@freebsd.org Wed Dec 5 13:46:40 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D0E9513140C8; Wed, 5 Dec 2018 13:46:40 +0000 (UTC) (envelope-from slavash@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 76CC972B46; Wed, 5 Dec 2018 13:46:40 +0000 (UTC) (envelope-from slavash@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 58CE015299; Wed, 5 Dec 2018 13:46:40 +0000 (UTC) (envelope-from slavash@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wB5DkecE081856; Wed, 5 Dec 2018 13:46:40 GMT (envelope-from slavash@FreeBSD.org) Received: (from slavash@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wB5DkdqM081852; Wed, 5 Dec 2018 13:46:39 GMT (envelope-from slavash@FreeBSD.org) Message-Id: <201812051346.wB5DkdqM081852@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: slavash set sender to slavash@FreeBSD.org using -f From: Slava Shwartsman Date: Wed, 5 Dec 2018 13:46:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r341566 - in head/sys/dev/mlx5: . mlx5_core X-SVN-Group: head X-SVN-Commit-Author: slavash X-SVN-Commit-Paths: in head/sys/dev/mlx5: . mlx5_core X-SVN-Commit-Revision: 341566 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 76CC972B46 X-Spamd-Result: default: False [-0.55 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-0.50)[-0.498,0]; NEURAL_SPAM_LONG(0.01)[0.010,0]; NEURAL_HAM_SHORT(-0.06)[-0.063,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Dec 2018 13:46:41 -0000 Author: slavash Date: Wed Dec 5 13:46:39 2018 New Revision: 341566 URL: https://svnweb.freebsd.org/changeset/base/341566 Log: mlx5: Fixes to allow command polling mode to exist alongside event mode. A command is either polling or event driven and the mode cannot change during execution of a command. Make sure the event handler only handle commands which are not polled. This is done by checking the command mode in the command handler before completing commands. Submitted by: hselasky@ Approved by: hselasky (mentor) MFC after: 1 week Sponsored by: Mellanox Technologies Modified: head/sys/dev/mlx5/driver.h head/sys/dev/mlx5/mlx5_core/mlx5_cmd.c head/sys/dev/mlx5/mlx5_core/mlx5_eq.c head/sys/dev/mlx5/mlx5_core/mlx5_health.c Modified: head/sys/dev/mlx5/driver.h ============================================================================== --- head/sys/dev/mlx5/driver.h Wed Dec 5 13:46:09 2018 (r341565) +++ head/sys/dev/mlx5/driver.h Wed Dec 5 13:46:39 2018 (r341566) @@ -327,6 +327,11 @@ struct mlx5_traffic_counter { u64 octets; }; +enum mlx5_cmd_mode { + MLX5_CMD_MODE_POLLING, + MLX5_CMD_MODE_EVENTS +}; + struct mlx5_cmd_stats { u64 sum; u64 n; @@ -370,8 +375,9 @@ struct mlx5_cmd { struct workqueue_struct *wq; struct semaphore sem; struct semaphore pages_sem; - int mode; - struct mlx5_cmd_work_ent *ent_arr[MLX5_MAX_COMMANDS]; + enum mlx5_cmd_mode mode; + struct mlx5_cmd_work_ent * volatile ent_arr[MLX5_MAX_COMMANDS]; + volatile enum mlx5_cmd_mode ent_mode[MLX5_MAX_COMMANDS]; struct mlx5_cmd_debug dbg; struct cmd_msg_cache cache; int checksum_disabled; @@ -984,7 +990,7 @@ void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type); void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type); struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn); -void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vector); +void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vector, enum mlx5_cmd_mode mode); void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type); int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx, int nent, u64 mask, const char *name, struct mlx5_uar *uar); Modified: head/sys/dev/mlx5/mlx5_core/mlx5_cmd.c ============================================================================== --- head/sys/dev/mlx5/mlx5_core/mlx5_cmd.c Wed Dec 5 13:46:09 2018 (r341565) +++ head/sys/dev/mlx5/mlx5_core/mlx5_cmd.c Wed Dec 5 13:46:39 2018 (r341566) @@ -50,11 +50,6 @@ enum { }; enum { - CMD_MODE_POLLING, - CMD_MODE_EVENTS -}; - -enum { NUM_LONG_LISTS = 2, NUM_MED_LISTS = 64, LONG_LIST_SIZE = (2ULL * 1024 * 1024 * 1024 / PAGE_SIZE) * 8 + 16 + @@ -160,6 +155,8 @@ static int alloc_ent(struct mlx5_cmd_work_ent *ent) ent->busy = 1; ent->idx = ret; clear_bit(ent->idx, &cmd->bitmask); + cmd->ent_mode[ent->idx] = + ent->polling ? MLX5_CMD_MODE_POLLING : MLX5_CMD_MODE_EVENTS; cmd->ent_arr[ent->idx] = ent; } spin_unlock_irqrestore(&cmd->alloc_lock, flags); @@ -172,6 +169,8 @@ static void free_ent(struct mlx5_cmd *cmd, int idx) unsigned long flags; spin_lock_irqsave(&cmd->alloc_lock, flags); + cmd->ent_arr[idx] = NULL; /* safety clear */ + cmd->ent_mode[idx] = MLX5_CMD_MODE_POLLING; /* reset mode */ set_bit(idx, &cmd->bitmask); spin_unlock_irqrestore(&cmd->alloc_lock, flags); } @@ -786,7 +785,7 @@ static void cb_timeout_handler(struct work_struct *wor mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n", mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); - mlx5_cmd_comp_handler(dev, 1UL << ent->idx); + mlx5_cmd_comp_handler(dev, 1UL << ent->idx, MLX5_CMD_MODE_EVENTS); } static void complete_command(struct mlx5_cmd_work_ent *ent) @@ -897,11 +896,12 @@ static void cmd_work_handler(struct work_struct *work) mlx5_fwp_flush(cmd->cmd_page); iowrite32be(1 << ent->idx, &dev->iseg->cmd_dbell); mmiowb(); - /* if not in polling don't use ent after this point*/ - if (cmd->mode == CMD_MODE_POLLING || poll_cmd) { + + /* if not in polling don't use ent after this point */ + if (poll_cmd) { poll_timeout(ent); /* make sure we read the descriptor after ownership is SW */ - mlx5_cmd_comp_handler(dev, 1U << ent->idx); + mlx5_cmd_comp_handler(dev, 1U << ent->idx, MLX5_CMD_MODE_POLLING); } } @@ -938,15 +938,13 @@ static const char *deliv_status_to_str(u8 status) static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent) { int timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC); - struct mlx5_cmd *cmd = &dev->cmd; int err; - if (cmd->mode == CMD_MODE_POLLING || ent->polling) { + if (ent->polling) { wait_for_completion(&ent->done); - err = ent->ret; } else if (!wait_for_completion_timeout(&ent->done, timeout)) { ent->ret = -ETIMEDOUT; - mlx5_cmd_comp_handler(dev, 1UL << ent->idx); + mlx5_cmd_comp_handler(dev, 1UL << ent->idx, MLX5_CMD_MODE_EVENTS); } err = ent->ret; @@ -988,7 +986,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, if (IS_ERR(ent)) return PTR_ERR(ent); - ent->polling = force_polling; + ent->polling = force_polling || (cmd->mode == MLX5_CMD_MODE_POLLING); if (!callback) init_completion(&ent->done); @@ -1158,12 +1156,12 @@ static void mlx5_cmd_change_mod(struct mlx5_core_dev * void mlx5_cmd_use_events(struct mlx5_core_dev *dev) { - mlx5_cmd_change_mod(dev, CMD_MODE_EVENTS); + mlx5_cmd_change_mod(dev, MLX5_CMD_MODE_EVENTS); } void mlx5_cmd_use_polling(struct mlx5_core_dev *dev) { - mlx5_cmd_change_mod(dev, CMD_MODE_POLLING); + mlx5_cmd_change_mod(dev, MLX5_CMD_MODE_POLLING); } static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg) @@ -1179,7 +1177,8 @@ static void free_msg(struct mlx5_core_dev *dev, struct } } -void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vector_flags) +void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vector_flags, + enum mlx5_cmd_mode cmd_mode) { struct mlx5_cmd *cmd = &dev->cmd; struct mlx5_cmd_work_ent *ent; @@ -1193,7 +1192,13 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, while (vector != 0) { i = ffs(vector) - 1; vector &= ~(1U << i); + /* check command mode */ + if (cmd->ent_mode[i] != cmd_mode) + continue; ent = cmd->ent_arr[i]; + /* check if command was already handled */ + if (ent == NULL) + continue; if (ent->callback) cancel_delayed_work(&ent->cb_timeout_work); ent->ts2 = ktime_get_ns(); @@ -1545,7 +1550,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev) mlx5_core_dbg(dev, "descriptor at dma 0x%llx\n", (unsigned long long)(cmd->dma)); - cmd->mode = CMD_MODE_POLLING; + cmd->mode = MLX5_CMD_MODE_POLLING; err = create_msg_cache(dev); if (err) { Modified: head/sys/dev/mlx5/mlx5_core/mlx5_eq.c ============================================================================== --- head/sys/dev/mlx5/mlx5_core/mlx5_eq.c Wed Dec 5 13:46:09 2018 (r341565) +++ head/sys/dev/mlx5/mlx5_core/mlx5_eq.c Wed Dec 5 13:46:39 2018 (r341566) @@ -254,8 +254,10 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, stru break; case MLX5_EVENT_TYPE_CMD: - if (dev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR) - mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector)); + if (dev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR) { + mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector), + MLX5_CMD_MODE_EVENTS); + } break; case MLX5_EVENT_TYPE_PORT_CHANGE: Modified: head/sys/dev/mlx5/mlx5_core/mlx5_health.c ============================================================================== --- head/sys/dev/mlx5/mlx5_core/mlx5_health.c Wed Dec 5 13:46:09 2018 (r341565) +++ head/sys/dev/mlx5/mlx5_core/mlx5_health.c Wed Dec 5 13:46:39 2018 (r341566) @@ -141,7 +141,7 @@ static void mlx5_trigger_cmd_completions(struct mlx5_c spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags); mlx5_core_dbg(dev, "vector 0x%jx\n", (uintmax_t)vector); - mlx5_cmd_comp_handler(dev, vector); + mlx5_cmd_comp_handler(dev, vector, MLX5_CMD_MODE_EVENTS); return; no_trig: