Here is how I would approach this problem:
1. I start with a ring shape:

2. I create a Bezier Curve with the shape of the curve I want

I give it a bevel radius for thickness, which will correspond to how deep the grove is. I am careful to make the curve seamless on the sides, such that if I arrayed it, the two ends of the curve would fit nicely together (this will be important later).
3. I add a Curve > Circle, and line it up with my ring
We will use this with the curve modifier to curve our groove object around the ring.
4. I convert the Bezier curve to a mesh, and give it 2 modifiers: an Array, and a Curve.
For the curve, select the circle as the target, and the groove mesh will take the shape of a circle around the ring:

Note: this wont work well unless both your curve and circular path are centered at the origin.
Below is an image with the modifiers I use to create the above result:

A couple of notes here: For the array, just play around until you get the right number of repetition so that it wraps all the way around. I also had to decrease the offset distance a little bit to make the copies line up with each other.
Luckily, they dont need to line up perfectly, because the weld modifier at the end fixes up the edges by connecting together the outer sides of each groove object in the array. Play around with the threshold until it is all one smooth mesh. You can see that in the image 2 above, there are gaps in the curve. This was taken before I added the weld, and go away after.
5. Subtract the curve from the ring with a boolean modifier

After scaling the groove to fit the size of the ring, I gave the ring a little more detail first with a subsurf modifier, and then did a boolean set to difference between the two objects. Once you have the boolean set up, you can hide the curve object in the viewport to see the groove.
You may also want to increase the resolution on the curve before you convert it to a mesh, as you can see my groove is a little low-poly.