diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst
index 8e60877f0e4c7d5a7a102f5cca97841f7e3f4282..70cec9b2f90248de57549df14732a03165a8e413 100644
--- a/Doc/library/asyncio-future.rst
+++ b/Doc/library/asyncio-future.rst
@@ -197,11 +197,6 @@ Future Object
       .. versionchanged:: 3.9
          Added the *msg* parameter.
 
-      .. deprecated-removed:: 3.11 3.14
-         *msg* parameter is ambiguous when multiple :meth:`cancel`
-         are called with different cancellation messages.
-         The argument will be removed.
-
    .. method:: exception()
 
       Return the exception that was set on this Future.
@@ -282,8 +277,3 @@ the Future has a result::
 
    - :meth:`asyncio.Future.cancel` accepts an optional ``msg`` argument,
      but :func:`concurrent.futures.cancel` does not.
-
-     .. deprecated-removed:: 3.11 3.14
-        *msg* parameter is ambiguous when multiple :meth:`cancel`
-        are called with different cancellation messages.
-        The argument will be removed.
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index eb4230105232aa20c2f5fbc31d171a1ea834f80d..f795f25525938f40feb75a97fffcf613b58f4a7a 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -1137,10 +1137,8 @@ Task Object
       .. versionchanged:: 3.9
          Added the *msg* parameter.
 
-      .. deprecated-removed:: 3.11 3.14
-         *msg* parameter is ambiguous when multiple :meth:`cancel`
-         are called with different cancellation messages.
-         The argument will be removed.
+      .. versionchanged:: 3.11
+         The ``msg`` parameter is propagated from cancelled task to its awaiter.
 
       .. _asyncio_example_task_cancel:
 
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 4bd9629e9eb62b6326e3db4ce7f9059a2c02f430..be2458acb955ec4c9c9d1e2a38bbb7cb8590fbfa 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -8,7 +8,6 @@
 import contextvars
 import logging
 import sys
-import warnings
 from types import GenericAlias
 
 from . import base_futures
@@ -151,11 +150,6 @@ def cancel(self, msg=None):
         change the future's state to cancelled, schedule the callbacks and
         return True.
         """
-        if msg is not None:
-            warnings.warn("Passing 'msg' argument to Future.cancel() "
-                          "is deprecated since Python 3.11, and "
-                          "scheduled for removal in Python 3.14.",
-                          DeprecationWarning, stacklevel=2)
         self.__log_traceback = False
         if self._state != _PENDING:
             return False
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index e48da0f200882951d841759369aadb94a9a86d7a..3e07ce5294c8dd0b99594d539a32f42b205cabdb 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -207,11 +207,6 @@ def cancel(self, msg=None):
 
         This also increases the task's count of cancellation requests.
         """
-        if msg is not None:
-            warnings.warn("Passing 'msg' argument to Task.cancel() "
-                          "is deprecated since Python 3.11, and "
-                          "scheduled for removal in Python 3.14.",
-                          DeprecationWarning, stacklevel=2)
         self._log_traceback = False
         if self.done():
             return False
diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py
index f4a46ec90a16fe7e30be27ce203a32cd32c3d93e..d71af8c13b14a1a125520dcce350f59362196650 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -228,22 +228,14 @@ def test_future_cancel_message_getter(self):
         self.assertTrue(hasattr(f, '_cancel_message'))
         self.assertEqual(f._cancel_message, None)
 
-        with self.assertWarnsRegex(
-            DeprecationWarning,
-            "Passing 'msg' argument"
-        ):
-            f.cancel('my message')
+        f.cancel('my message')
         with self.assertRaises(asyncio.CancelledError):
             self.loop.run_until_complete(f)
         self.assertEqual(f._cancel_message, 'my message')
 
     def test_future_cancel_message_setter(self):
         f = self._new_future(loop=self.loop)
-        with self.assertWarnsRegex(
-            DeprecationWarning,
-            "Passing 'msg' argument"
-        ):
-            f.cancel('my message')
+        f.cancel('my message')
         f._cancel_message = 'my new message'
         self.assertEqual(f._cancel_message, 'my new message')
 
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index 1cc20609bebc4d76d402acd397fdaf5fed9f1ec7..7585768073e6ab0937d0d35e233505dd5c0db4b7 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -113,11 +113,7 @@ async def coro():
         self.assertTrue(hasattr(t, '_cancel_message'))
         self.assertEqual(t._cancel_message, None)
 
-        with self.assertWarnsRegex(
-            DeprecationWarning,
-            "Passing 'msg' argument"
-        ):
-            t.cancel('my message')
+        t.cancel('my message')
         self.assertEqual(t._cancel_message, 'my message')
 
         with self.assertRaises(asyncio.CancelledError) as cm:
@@ -129,11 +125,7 @@ def test_task_cancel_message_setter(self):
         async def coro():
             pass
         t = self.new_task(self.loop, coro())
-        with self.assertWarnsRegex(
-            DeprecationWarning,
-            "Passing 'msg' argument"
-        ):
-            t.cancel('my message')
+        t.cancel('my message')
         t._cancel_message = 'my new message'
         self.assertEqual(t._cancel_message, 'my new message')
 
@@ -710,14 +702,7 @@ async def sleep():
                 async def coro():
                     task = self.new_task(loop, sleep())
                     await asyncio.sleep(0)
-                    if cancel_args not in ((), (None,)):
-                        with self.assertWarnsRegex(
-                                DeprecationWarning,
-                                "Passing 'msg' argument"
-                        ):
-                            task.cancel(*cancel_args)
-                    else:
-                        task.cancel(*cancel_args)
+                    task.cancel(*cancel_args)
                     done, pending = await asyncio.wait([task])
                     task.result()
 
@@ -751,14 +736,7 @@ async def sleep():
                 async def coro():
                     task = self.new_task(loop, sleep())
                     await asyncio.sleep(0)
-                    if cancel_args not in ((), (None,)):
-                        with self.assertWarnsRegex(
-                                DeprecationWarning,
-                                "Passing 'msg' argument"
-                        ):
-                            task.cancel(*cancel_args)
-                    else:
-                        task.cancel(*cancel_args)
+                    task.cancel(*cancel_args)
                     done, pending = await asyncio.wait([task])
                     task.exception()
 
@@ -781,17 +759,10 @@ async def sleep():
             fut.set_result(None)
             await asyncio.sleep(10)
 
-        def cancel(task, msg):
-            with self.assertWarnsRegex(
-                    DeprecationWarning,
-                    "Passing 'msg' argument"
-            ):
-                task.cancel(msg)
-
         async def coro():
             inner_task = self.new_task(loop, sleep())
             await fut
-            loop.call_soon(cancel, inner_task, 'msg')
+            loop.call_soon(inner_task.cancel, 'msg')
             try:
                 await inner_task
             except asyncio.CancelledError as ex:
@@ -817,11 +788,7 @@ async def sleep():
         async def coro():
             task = self.new_task(loop, sleep())
             # We deliberately leave out the sleep here.
-            with self.assertWarnsRegex(
-                    DeprecationWarning,
-                    "Passing 'msg' argument"
-            ):
-                task.cancel('my message')
+            task.cancel('my message')
             done, pending = await asyncio.wait([task])
             task.exception()
 
@@ -2183,14 +2150,7 @@ async def test():
                 async def main():
                     qwe = self.new_task(loop, test())
                     await asyncio.sleep(0.2)
-                    if cancel_args not in ((), (None,)):
-                        with self.assertWarnsRegex(
-                                DeprecationWarning,
-                                "Passing 'msg' argument"
-                        ):
-                            qwe.cancel(*cancel_args)
-                    else:
-                        qwe.cancel(*cancel_args)
+                    qwe.cancel(*cancel_args)
                     await qwe
 
                 try:
diff --git a/Misc/NEWS.d/next/Library/2022-10-06-23-42-00.gh-issue-90985.s280JY.rst b/Misc/NEWS.d/next/Library/2022-10-06-23-42-00.gh-issue-90985.s280JY.rst
new file mode 100644
index 0000000000000000000000000000000000000000..964aa3986331a26a7e9b90501321250962fd83e2
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-10-06-23-42-00.gh-issue-90985.s280JY.rst
@@ -0,0 +1 @@
+Earlier in 3.11 we deprecated ``asyncio.Task.cancel("message")``. We realized we were too harsh, and have undeprecated it.
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 10679be2ef19382c47a737a257e80862375d8482..e51f97f4659076fde5f6a5cba05259e31d9fe08e 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -1111,16 +1111,6 @@ static PyObject *
 _asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg)
 /*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/
 {
-    if (msg != Py_None) {
-        if (PyErr_WarnEx(PyExc_DeprecationWarning,
-                         "Passing 'msg' argument to Future.cancel() "
-                         "is deprecated since Python 3.11, and "
-                         "scheduled for removal in Python 3.14.",
-                         2))
-        {
-            return NULL;
-        }
-    }
     ENSURE_FUTURE_ALIVE(self)
     return future_cancel(self, msg);
 }
@@ -2201,16 +2191,6 @@ static PyObject *
 _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg)
 /*[clinic end generated code: output=c66b60d41c74f9f1 input=7bb51bf25974c783]*/
 {
-    if (msg != Py_None) {
-        if (PyErr_WarnEx(PyExc_DeprecationWarning,
-                         "Passing 'msg' argument to Task.cancel() "
-                         "is deprecated since Python 3.11, and "
-                         "scheduled for removal in Python 3.14.",
-                         2))
-        {
-            return NULL;
-        }
-    }
     self->task_log_tb = 0;
 
     if (self->task_state != STATE_PENDING) {